From 7638185992792a6a0bb0f35399b997ffa6d42811 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Mon, 1 Aug 2022 14:16:11 -0700 Subject: [PATCH 01/21] SBS 96 plotting is optimized fpr speed and organization --- sigProfilerPlotting/sigProfilerPlotting.py | 418 +++++++++------------ 1 file changed, 170 insertions(+), 248 deletions(-) diff --git a/sigProfilerPlotting/sigProfilerPlotting.py b/sigProfilerPlotting/sigProfilerPlotting.py index f33cd8d..3576433 100644 --- a/sigProfilerPlotting/sigProfilerPlotting.py +++ b/sigProfilerPlotting/sigProfilerPlotting.py @@ -464,256 +464,178 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust plot_custom_text = False sig_probs = False pcawg = False - if plot_type == '96': - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - if first_line[0][1] == ">": - pcawg = True - if first_line[0][5] != "]" and first_line[0][1] != ">": - sys.exit("The matrix does not match the correct SBS96 format. Please check you formatting and rerun this plotting function.") - - pp = PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') - mutations = OrderedDict() - total_count = [] - try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[2:] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] - - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['C>A'] = OrderedDict() - mutations[sample]['C>G'] = OrderedDict() - mutations[sample]['C>T'] = OrderedDict() - mutations[sample]['T>A'] = OrderedDict() - mutations[sample]['T>C'] = OrderedDict() - mutations[sample]['T>G'] = OrderedDict() - - - for lines in f: - if pcawg: - line = lines.strip().split(",") - mut_type = line[0] - nuc = line[1][0] + "[" + mut_type + "]" + line[1][2] - sample_index = 2 + if plot_type == '96': + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + + data= reindex_sbs96(data) + sample_count = 0 + + buf= io.BytesIO() + fig_orig=pickle.load(open('template/sbs96.pkl','rb')) + pickle.dump(fig_orig, buf) + figs={} + buff_list={} + + + ctx = data.index #[seq[0]+seq[2]+seq[6] for seq in data.index] + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + colorsall= [[colors[j] for i in range(int(len(ctx)/6))] for j in range(6)] + colors_flat_list = [item for sublist in colorsall for item in sublist] + + for sample in data.columns: + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + + total_count = np.sum(data[sample].values)#sum(sum(nuc.values()) for nuc in mutations[sample].values()) + x = 0.4 + ymax = 0 + i = 0 + muts = data[sample].values + if percentage: + if total_count > 0: + plt.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + plt.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + # ytick_offest = int(y/4) + y = ymax/1.025 + ytick_offest = float(y/3) + + if percentage: + ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] + ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + else: + ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] + ylabels= [0, ytick_offest, ytick_offest*2, + ytick_offest*3, ytick_offest*4] + + labs = np.arange(0.375,96.375,1) + + font_label_size = 30 + if not percentage: + if int(ylabels[3]) >= 1000: + font_label_size = 20 + + if percentage: + if len(ylabels) > 2: + font_label_size = 20 + + if not percentage: + ylabels= getylabels(ylabels) + + + panel1.set_xlim([0, 96]) + panel1.set_ylim([0, y]) + panel1.set_yticks(ylabs) + + if sig_probs: + plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + else: + plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + + + panel1.set_yticklabels(ylabels, fontsize=font_label_size) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + custom_text_upper_plot = '' + try: + custom_text_upper[sample_count] + except: + custom_text_upper = False + try: + custom_text_middle[sample_count] + except: + custom_text_middle = False + try: + custom_text_bottom[sample_count] + except: + custom_text_bottom = False + + if custom_text_upper: + plot_custom_text = True + if len(custom_text_upper[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + if custom_text_middle: + if len(custom_text_middle[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + + if plot_custom_text: + x_pos_custom = 0.98 + if custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] + if custom_text_bottom: + custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] + + if custom_text_upper and not custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + elif custom_text_upper and custom_text_middle: + if not custom_text_bottom: + panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') else: - line = lines.strip().split() - nuc = line[0] - mut_type = line[0][2:5] - sample_index = 1 - - for sample in samples: - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') - mutations[sample][mut_type][nuc] = mutCount - sample_index += 1 - - sample_count = 0 - - for sample in mutations.keys(): - total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='lightgray') - panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) - xlabels = [] - - x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] - i = 0 - for key in mutations[sample]: - for seq in mutations[sample][key]: - xlabels.append(seq[0]+seq[2]+seq[6]) - if percentage: - if total_count > 0: - plt.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq]/total_count*100 > ymax: - ymax = mutations[sample][key][seq]/total_count*100 - else: - plt.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq] > ymax: - ymax = mutations[sample][key][seq] - x += 1 - i += 1 - - x = .043 - y3 = .87 - y = int(ymax*1.25) - y2 = y+2 - for i in range(0, 6, 1): - panel1.add_patch(plt.Rectangle((x,y3), .15, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .159 - - yText = y3 + .06 - plt.text(.1, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.255, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.415, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.575, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.735, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.89, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - - if y <= 4: - y += 4 - - while y%4 != 0: - y += 1 - # ytick_offest = int(y/4) - y = ymax/1.025 - ytick_offest = float(y/3) - - if percentage: - ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - else: - ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] - ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] - - labs = np.arange(0.375,96.375,1) - - font_label_size = 30 - if not percentage: - if int(ylabels[3]) >= 1000: - font_label_size = 20 - - if percentage: - if len(ylabels) > 2: - font_label_size = 20 - - if not percentage: - ylabels= getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp - - panel1.set_xlim([0, 96]) - panel1.set_ylim([0, y]) - panel1.set_xticks(labs) - panel1.set_yticks(ylabs) - count = 0 - m = 0 - for i in range (0, 96, 1): - plt.text(i/101 + .0415, .02, xlabels[i][0], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - plt.text(i/101 + .0415, .044, xlabels[i][1], fontsize=30, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) - plt.text(i/101 + .0415, .071, xlabels[i][2], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - count += 1 - if count == 16: - count = 0 - m += 1 - - if sig_probs: - plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - else: - plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - - - - custom_text_upper_plot = '' - try: - custom_text_upper[sample_count] - except: - custom_text_upper = False - try: - custom_text_middle[sample_count] - except: - custom_text_middle = False - try: - custom_text_bottom[sample_count] - except: - custom_text_bottom = False - - if custom_text_upper: - plot_custom_text = True - if len(custom_text_upper[sample_count]) > 40: - print("To add a custom text, please limit the string to <40 characters including spaces.") - plot_custom_text = False - if custom_text_middle: - if len(custom_text_middle[sample_count]) > 40: - print("To add a custom text, please limit the string to <40 characters including spaces.") - plot_custom_text = False - - if plot_custom_text: - x_pos_custom = 0.98 - if custom_text_upper and custom_text_middle: - custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] - if custom_text_bottom: - custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] - - if custom_text_upper and not custom_text_middle: - custom_text_upper_plot = custom_text_upper[sample_count] - panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - elif custom_text_upper and custom_text_middle: - if not custom_text_bottom: - panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - else: - panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - elif not custom_text_upper and custom_text_middle: - custom_text_upper_plot = custom_text_middle[sample_count] - panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - - - panel1.set_yticklabels(ylabels, fontsize=font_label_size) - plt.gca().yaxis.grid(True) - plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.set_xlabel('') - panel1.set_ylabel('') - - if percentage: - plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - else: - plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - - - - panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) - - - [i.set_color("black") for i in plt.gca().get_yticklabels()] - pp.savefig(plot1) - plt.close() - sample_count += 1 - pp.close() + panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + elif not custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_middle[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + + if percentage: + plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + else: + plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + sample_count += 1 + + if savefig_format == "pdf": + pp = PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') + + for fig in figs: + if savefig_format == "pdf": + figs[fig].savefig(pp, format='pdf') + pp.close() + elif savefig_format == "png": + figs[fig].savefig(output_path + 'SBS_96_plots_'+fig+'.png',dpi=100) + elif savefig_format == "buffer_stream": + buffer2=io.BytesIO() + figs[fig].savefig(buffer2,format='png') + buff_list[fig]=buffer2 + return buff_list except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'SBS_96_plots_' + project + '.pdf') From afffeea799765441b470073f2c385ee50ad88b3a Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Mon, 1 Aug 2022 14:27:14 -0700 Subject: [PATCH 02/21] SBS 96 plotting is optimized fpr speed and organization --- sigProfilerPlotting/sigProfilerPlotting.py | 338 +++++++++++---------- 1 file changed, 175 insertions(+), 163 deletions(-) diff --git a/sigProfilerPlotting/sigProfilerPlotting.py b/sigProfilerPlotting/sigProfilerPlotting.py index 3576433..f8b009f 100644 --- a/sigProfilerPlotting/sigProfilerPlotting.py +++ b/sigProfilerPlotting/sigProfilerPlotting.py @@ -24,6 +24,8 @@ import io import string import warnings +import pickle + warnings.filterwarnings("ignore") def getylabels(ylabels): @@ -58,6 +60,14 @@ def getxlabels(xlabels): xlabels[0] = '0.00' return xlabels +def reindex_sbs96(data_f): + first=['A','C','G','T'] + inner_bracket=[[x]*16 for x in ["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"]] + inner_bracket=[item for sublist in inner_bracket for item in sublist] + outter_bracket=[x for x in list(itertools.product(first,first))] + result=[outter_bracket[f%16][0]+"["+inner_bracket[f]+"]"+outter_bracket[f%16][1] for f in range(0,96)] + data_f= data_f.reindex(result) + return data_f def plotSV(matrix_path, output_path, project, plot_type="pdf", percentage=False, aggregate=False): @@ -70,7 +80,7 @@ def plotSV(matrix_path, output_path, project, plot_type="pdf", percentage=False, :param percentage: True if y-axis is displayed as percentage of CNV events, False if displayed as counts (default:False) :param aggregate: True if output is a single pdf of counts aggregated across samples(e.g for a given cancer type, y-axis will be counts per sample), False if output is a multi-page pdf of counts for each sample - >>> plotSV() + # >>> plotSV() """ @@ -460,182 +470,184 @@ def plot(counts, labels, sample, project, percentage, aggregate=False, write_to_ pp.close() -def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None): +def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): + plot_custom_text = False sig_probs = False pcawg = False if plot_type == '96': - if not isinstance(matrix_path, pd.DataFrame): - data=pd.read_csv(matrix_path,sep='\t',index_col=0) - data=data.dropna(axis=1, how='all') + try: + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + + data= reindex_sbs96(data) + sample_count = 0 - if data.isnull().values.any(): - raise ValueError("Input data contains Nans.") - - data= reindex_sbs96(data) - sample_count = 0 - - buf= io.BytesIO() - fig_orig=pickle.load(open('template/sbs96.pkl','rb')) - pickle.dump(fig_orig, buf) - figs={} - buff_list={} - - - ctx = data.index #[seq[0]+seq[2]+seq[6] for seq in data.index] - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] - colorsall= [[colors[j] for i in range(int(len(ctx)/6))] for j in range(6)] - colors_flat_list = [item for sublist in colorsall for item in sublist] - - for sample in data.columns: - buf.seek(0) - figs[sample]=pickle.load(buf) - panel1= figs[sample].axes[0] - - total_count = np.sum(data[sample].values)#sum(sum(nuc.values()) for nuc in mutations[sample].values()) - x = 0.4 - ymax = 0 - i = 0 - muts = data[sample].values - if percentage: - if total_count > 0: - plt.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) - ymax = np.max(muts/total_count*100) - else: - plt.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) - ymax = np.max(muts) - - x = .043 - y3 = .87 - y = int(ymax*1.25) - y2 = y+2 - - if y <= 4: - y += 4 - - while y%4 != 0: - y += 1 - # ytick_offest = int(y/4) - y = ymax/1.025 - ytick_offest = float(y/3) - - if percentage: - ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - else: - ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] - ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] - - labs = np.arange(0.375,96.375,1) - - font_label_size = 30 - if not percentage: - if int(ylabels[3]) >= 1000: - font_label_size = 20 - - if percentage: - if len(ylabels) > 2: - font_label_size = 20 - - if not percentage: - ylabels= getylabels(ylabels) - - - panel1.set_xlim([0, 96]) - panel1.set_ylim([0, y]) - panel1.set_yticks(ylabs) - - if sig_probs: - plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - else: - plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - - - panel1.set_yticklabels(ylabels, fontsize=font_label_size) - plt.gca().yaxis.grid(True) - plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.set_xlabel('') - panel1.set_ylabel('') - - custom_text_upper_plot = '' - try: - custom_text_upper[sample_count] - except: - custom_text_upper = False - try: - custom_text_middle[sample_count] - except: - custom_text_middle = False - try: - custom_text_bottom[sample_count] - except: - custom_text_bottom = False - - if custom_text_upper: - plot_custom_text = True - if len(custom_text_upper[sample_count]) > 40: - print("To add a custom text, please limit the string to <40 characters including spaces.") - plot_custom_text = False - if custom_text_middle: - if len(custom_text_middle[sample_count]) > 40: - print("To add a custom text, please limit the string to <40 characters including spaces.") - plot_custom_text = False - - if plot_custom_text: - x_pos_custom = 0.98 - if custom_text_upper and custom_text_middle: - custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] - if custom_text_bottom: - custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] - - if custom_text_upper and not custom_text_middle: - custom_text_upper_plot = custom_text_upper[sample_count] - panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - elif custom_text_upper and custom_text_middle: - if not custom_text_bottom: - panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - else: - panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + buf= io.BytesIO() + fig_orig=pickle.load(open('template/sbs96.pkl','rb')) + pickle.dump(fig_orig, buf) + figs={} + buff_list={} - elif not custom_text_upper and custom_text_middle: - custom_text_upper_plot = custom_text_middle[sample_count] - panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + ctx = data.index #[seq[0]+seq[2]+seq[6] for seq in data.index] + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + colorsall= [[colors[j] for i in range(int(len(ctx)/6))] for j in range(6)] + colors_flat_list = [item for sublist in colorsall for item in sublist] - if percentage: - plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - else: - plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + for sample in data.columns: + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] - panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) + total_count = np.sum(data[sample].values) #sum(sum(nuc.values()) for nuc in mutations[sample].values()) + x = 0.4 + ymax = 0 + i = 0 + muts = data[sample].values + if percentage: + if total_count > 0: + plt.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + plt.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 - [i.set_color("black") for i in plt.gca().get_yticklabels()] - sample_count += 1 + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + # ytick_offest = int(y/4) + y = ymax/1.025 + ytick_offest = float(y/3) + + if percentage: + ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] + ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + else: + ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] + ylabels= [0, ytick_offest, ytick_offest*2, + ytick_offest*3, ytick_offest*4] + + labs = np.arange(0.375,96.375,1) + + font_label_size = 30 + if not percentage: + if int(ylabels[3]) >= 1000: + font_label_size = 20 + + if percentage: + if len(ylabels) > 2: + font_label_size = 20 + + if not percentage: + ylabels= getylabels(ylabels) + + + panel1.set_xlim([0, 96]) + panel1.set_ylim([0, y]) + panel1.set_yticks(ylabs) + + if sig_probs: + plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + else: + plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + + + panel1.set_yticklabels(ylabels, fontsize=font_label_size) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + custom_text_upper_plot = '' + try: + custom_text_upper[sample_count] + except: + custom_text_upper = False + try: + custom_text_middle[sample_count] + except: + custom_text_middle = False + try: + custom_text_bottom[sample_count] + except: + custom_text_bottom = False + + if custom_text_upper: + plot_custom_text = True + if len(custom_text_upper[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + if custom_text_middle: + if len(custom_text_middle[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + + if plot_custom_text: + x_pos_custom = 0.98 + if custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] + if custom_text_bottom: + custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] + + if custom_text_upper and not custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + elif custom_text_upper and custom_text_middle: + if not custom_text_bottom: + panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + else: + panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + elif not custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_middle[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + + if percentage: + plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + else: + plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + sample_count += 1 - if savefig_format == "pdf": - pp = PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') - - for fig in figs: if savefig_format == "pdf": - figs[fig].savefig(pp, format='pdf') - pp.close() - elif savefig_format == "png": - figs[fig].savefig(output_path + 'SBS_96_plots_'+fig+'.png',dpi=100) - elif savefig_format == "buffer_stream": - buffer2=io.BytesIO() - figs[fig].savefig(buffer2,format='png') - buff_list[fig]=buffer2 - return buff_list + pp = PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') + + for fig in figs: + if savefig_format == "pdf": + figs[fig].savefig(pp, format='pdf') + pp.close() + elif savefig_format == "png": + figs[fig].savefig(output_path + 'SBS_96_plots_'+fig+'.png',dpi=100) + elif savefig_format == "buffer_stream": + buffer2=io.BytesIO() + figs[fig].savefig(buffer2,format='png') + buff_list[fig]=buffer2 + return buff_list except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'SBS_96_plots_' + project + '.pdf') From 4184299cfc13f29d8b3c9f779cca7afc410f2228 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 2 Aug 2022 16:35:37 -0700 Subject: [PATCH 03/21] pickle installation added for SBS96. --- .gitignore | 2 + sigProfilerPlotting/sigProfilerPlotting.py | 137 +++++++++++++++++++-- 2 files changed, 131 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 17f693f..9d02304 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ # Python egg metadata, regenerated from source files by setuptools. /*.egg-info +sigProfilerPlotting/templates/** + # Hidden files and directories *.DS_Store diff --git a/sigProfilerPlotting/sigProfilerPlotting.py b/sigProfilerPlotting/sigProfilerPlotting.py index f8b009f..72d9eda 100644 --- a/sigProfilerPlotting/sigProfilerPlotting.py +++ b/sigProfilerPlotting/sigProfilerPlotting.py @@ -25,9 +25,126 @@ import string import warnings import pickle +import sigProfilerPlotting as spplt +import pdb +import itertools warnings.filterwarnings("ignore") +def install_plot_templates(context='SBS96'): + package_path = spplt.__path__[0] + install_path =os.path.join(package_path,'templates/') + + if not os.path.exists(install_path): + os.mkdir(install_path) + + filename= os.path.join(install_path,context+'.pkl') + if not os.path.exists(filename): + make_pickle_file(context,path=filename) + +def make_pickle_file(context='SBS96',path='SBS96.pkl'): + plot_custom_text = False + sig_probs = False + pcawg = False + + # total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) + #, extent=[-5, 80, -5, 30]) + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='lightgray') + panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) + seq96=['A[C>A]A','A[C>A]C','A[C>A]G','A[C>A]T','A[C>G]A','A[C>G]C','A[C>G]G','A[C>G]T','A[C>T]A','A[C>T]C','A[C>T]G','A[C>T]T','A[T>A]A','A[T>A]C','A[T>A]G','A[T>A]T','A[T>C]A','A[T>C]C','A[T>C]G','A[T>C]T','A[T>G]A','A[T>G]C','A[T>G]G','A[T>G]T','C[C>A]A','C[C>A]C','C[C>A]G','C[C>A]T','C[C>G]A','C[C>G]C','C[C>G]G','C[C>G]T','C[C>T]A','C[C>T]C','C[C>T]G','C[C>T]T','C[T>A]A','C[T>A]C','C[T>A]G','C[T>A]T','C[T>C]A','C[T>C]C','C[T>C]G','C[T>C]T','C[T>G]A','C[T>G]C','C[T>G]G','C[T>G]T','G[C>A]A','G[C>A]C','G[C>A]G','G[C>A]T','G[C>G]A','G[C>G]C','G[C>G]G','G[C>G]T','G[C>T]A','G[C>T]C','G[C>T]G','G[C>T]T','G[T>A]A','G[T>A]C','G[T>A]G','G[T>A]T','G[T>C]A','G[T>C]C','G[T>C]G','G[T>C]T','G[T>G]A','G[T>G]C','G[T>G]G','G[T>G]T','T[C>A]A','T[C>A]C','T[C>A]G','T[C>A]T','T[C>G]A','T[C>G]C','T[C>G]G','T[C>G]T','T[C>T]A','T[C>T]C','T[C>T]G','T[C>T]T','T[T>A]A','T[T>A]C','T[T>A]G','T[T>A]T','T[T>C]A','T[T>C]C','T[T>C]G','T[T>C]T','T[T>G]A','T[T>G]C','T[T>G]G','T[T>G]T'] + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + xlabels = [seq[0]+seq[2]+seq[6] for seq in seq96] + i = 0 + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 6, 1): + panel1.add_patch(plt.Rectangle((x,y3), .15, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .159 + + yText = y3 + .06 + plt.text(.1, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.255, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.415, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.575, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.735, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.89, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + # ytick_offest = int(y/4) + y = ymax/1.025 + ytick_offest = float(y/3) + + + labs = np.arange(0.375,96.375,1) + + + + panel1.set_xlim([0, 96]) + # panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + # panel1.set_yticks(ylabs) + count = 0 + m = 0 + for i in range (0, 96, 1): + plt.text(i/101 + .0415, .02, xlabels[i][0], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + plt.text(i/101 + .0415, .044, xlabels[i][1], fontsize=30, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) + plt.text(i/101 + .0415, .071, xlabels[i][2], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + count += 1 + if count == 16: + count = 0 + m += 1 + + # if sig_probs: + # plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + # else: + # plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + + + + + + + # panel1.set_yticklabels(ylabels, fontsize=font_label_size) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + # if percentage: + # plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + # else: + # plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + + # image = plt.imread('template/SBS_96_plots_template.jpg') + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + pickle.dump(plot1, open(path, 'wb')) + + + + def getylabels(ylabels): if max(ylabels) >=10**9: ylabels = ["{:.2e}".format(x) for x in ylabels] @@ -489,12 +606,11 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust sample_count = 0 buf= io.BytesIO() - fig_orig=pickle.load(open('template/sbs96.pkl','rb')) + + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS96.pkl','rb')) pickle.dump(fig_orig, buf) figs={} buff_list={} - - ctx = data.index #[seq[0]+seq[2]+seq[6] for seq in data.index] colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] colorsall= [[colors[j] for i in range(int(len(ctx)/6))] for j in range(6)] @@ -633,17 +749,22 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust [i.set_color("black") for i in plt.gca().get_yticklabels()] sample_count += 1 + if savefig_format == "pdf": pp = PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') - for fig in figs: - if savefig_format == "pdf": + + if savefig_format == "pdf": + for fig in figs: figs[fig].savefig(pp, format='pdf') - pp.close() - elif savefig_format == "png": + pp.close() + + if savefig_format == "png": + for fig in figs: figs[fig].savefig(output_path + 'SBS_96_plots_'+fig+'.png',dpi=100) - elif savefig_format == "buffer_stream": + if savefig_format == "buffer_stream": + for fig in figs: buffer2=io.BytesIO() figs[fig].savefig(buffer2,format='png') buff_list[fig]=buffer2 From c486d62ef8f7268d92d07b6122fe16f1df0d55e7 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 23 Aug 2022 04:19:56 -0700 Subject: [PATCH 04/21] Templates install in setup.py --- .../sigProfilerPlotting.py | 393 ++++++++++-------- setup.py | 14 +- sigProfilerPlotting.egg-info/PKG-INFO | 4 - 3 files changed, 239 insertions(+), 172 deletions(-) diff --git a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py index 7685134..72d9eda 100644 --- a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py +++ b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py @@ -24,30 +24,167 @@ import io import string import warnings +import pickle +import sigProfilerPlotting as spplt +import pdb +import itertools + warnings.filterwarnings("ignore") +def install_plot_templates(context='SBS96'): + package_path = spplt.__path__[0] + install_path =os.path.join(package_path,'templates/') + + if not os.path.exists(install_path): + os.mkdir(install_path) + + filename= os.path.join(install_path,context+'.pkl') + if not os.path.exists(filename): + make_pickle_file(context,path=filename) + +def make_pickle_file(context='SBS96',path='SBS96.pkl'): + plot_custom_text = False + sig_probs = False + pcawg = False + + # total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) + #, extent=[-5, 80, -5, 30]) + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='lightgray') + panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) + seq96=['A[C>A]A','A[C>A]C','A[C>A]G','A[C>A]T','A[C>G]A','A[C>G]C','A[C>G]G','A[C>G]T','A[C>T]A','A[C>T]C','A[C>T]G','A[C>T]T','A[T>A]A','A[T>A]C','A[T>A]G','A[T>A]T','A[T>C]A','A[T>C]C','A[T>C]G','A[T>C]T','A[T>G]A','A[T>G]C','A[T>G]G','A[T>G]T','C[C>A]A','C[C>A]C','C[C>A]G','C[C>A]T','C[C>G]A','C[C>G]C','C[C>G]G','C[C>G]T','C[C>T]A','C[C>T]C','C[C>T]G','C[C>T]T','C[T>A]A','C[T>A]C','C[T>A]G','C[T>A]T','C[T>C]A','C[T>C]C','C[T>C]G','C[T>C]T','C[T>G]A','C[T>G]C','C[T>G]G','C[T>G]T','G[C>A]A','G[C>A]C','G[C>A]G','G[C>A]T','G[C>G]A','G[C>G]C','G[C>G]G','G[C>G]T','G[C>T]A','G[C>T]C','G[C>T]G','G[C>T]T','G[T>A]A','G[T>A]C','G[T>A]G','G[T>A]T','G[T>C]A','G[T>C]C','G[T>C]G','G[T>C]T','G[T>G]A','G[T>G]C','G[T>G]G','G[T>G]T','T[C>A]A','T[C>A]C','T[C>A]G','T[C>A]T','T[C>G]A','T[C>G]C','T[C>G]G','T[C>G]T','T[C>T]A','T[C>T]C','T[C>T]G','T[C>T]T','T[T>A]A','T[T>A]C','T[T>A]G','T[T>A]T','T[T>C]A','T[T>C]C','T[T>C]G','T[T>C]T','T[T>G]A','T[T>G]C','T[T>G]G','T[T>G]T'] + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + xlabels = [seq[0]+seq[2]+seq[6] for seq in seq96] + i = 0 + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 6, 1): + panel1.add_patch(plt.Rectangle((x,y3), .15, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .159 + + yText = y3 + .06 + plt.text(.1, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.255, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.415, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.575, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.735, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.89, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + # ytick_offest = int(y/4) + y = ymax/1.025 + ytick_offest = float(y/3) + + + labs = np.arange(0.375,96.375,1) + + + + panel1.set_xlim([0, 96]) + # panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + # panel1.set_yticks(ylabs) + count = 0 + m = 0 + for i in range (0, 96, 1): + plt.text(i/101 + .0415, .02, xlabels[i][0], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + plt.text(i/101 + .0415, .044, xlabels[i][1], fontsize=30, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) + plt.text(i/101 + .0415, .071, xlabels[i][2], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + count += 1 + if count == 16: + count = 0 + m += 1 + + # if sig_probs: + # plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + # else: + # plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + + + + + + + # panel1.set_yticklabels(ylabels, fontsize=font_label_size) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + # if percentage: + # plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + # else: + # plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + + # image = plt.imread('template/SBS_96_plots_template.jpg') + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + pickle.dump(plot1, open(path, 'wb')) + + + + def getylabels(ylabels): - if max(ylabels) >=10**9: - ylabels = ["{:.2e}".format(x) for x in ylabels] - else: - if max(ylabels)< 10**5: - ylabels = ['{:,.2f}'.format(x/1000)+'k' for x in ylabels] - elif max(ylabels)>= 10**5: - ylabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in ylabels] - ylabels[0] = '0.00' - return ylabels + if max(ylabels) >=10**9: + ylabels = ["{:.2e}".format(x) for x in ylabels] + ylabels[0] = '0.00' + else: + if max(ylabels)<= 1000: + ylabels = ['{:,.0f}'.format(x) for x in ylabels] + ylabels[0] = '0' + elif max(ylabels)< 10**5 and max(ylabels) > 1000: + ylabels = ['{:,.0f}'.format(x/1000)+'k' for x in ylabels] + ylabels[0] = '0' + else:#if max(ylabels)>= 10**5: + ylabels = ['{:,.0f}'.format(x/(10**6))+'m' for x in ylabels] + ylabels[0] = '0' + return ylabels def getxlabels(xlabels): - if max(xlabels) >=10**10: - xlabels = ["{:.2e}".format(x) for x in xlabels] - else: - if max(xlabels)< 10**6: - xlabels = ['{:,.2f}'.format(x/1000)+'k' for x in xlabels] - elif max(xlabels)>= 10**6: - xlabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in xlabels] - xlabels[0] = '0.00' - return xlabels - + if max(xlabels) >=10**10: + xlabels = ["{:.2e}".format(x) for x in xlabels] + xlabels[0] = '0.00' + else: + if max(xlabels) <= 1000: + xlabels = ['{:,.1f}'.format(x) for x in xlabels] + xlabels[0] = '0' + elif max(xlabels)< 10**6 and max(xlabels)> 1000: + xlabels = ['{:,.2f}'.format(x/1000)+'k' for x in xlabels] + xlabels[0] = '0.00' + else:#max(xlabels)>= 10**6: + xlabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in xlabels] + xlabels[0] = '0.00' + return xlabels + +def reindex_sbs96(data_f): + first=['A','C','G','T'] + inner_bracket=[[x]*16 for x in ["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"]] + inner_bracket=[item for sublist in inner_bracket for item in sublist] + outter_bracket=[x for x in list(itertools.product(first,first))] + result=[outter_bracket[f%16][0]+"["+inner_bracket[f]+"]"+outter_bracket[f%16][1] for f in range(0,96)] + data_f= data_f.reindex(result) + return data_f def plotSV(matrix_path, output_path, project, plot_type="pdf", percentage=False, aggregate=False): @@ -60,7 +197,7 @@ def plotSV(matrix_path, output_path, project, plot_type="pdf", percentage=False, :param percentage: True if y-axis is displayed as percentage of CNV events, False if displayed as counts (default:False) :param aggregate: True if output is a single pdf of counts aggregated across samples(e.g for a given cancer type, y-axis will be counts per sample), False if output is a multi-page pdf of counts for each sample - >>> plotSV() + # >>> plotSV() """ @@ -450,113 +587,57 @@ def plot(counts, labels, sample, project, percentage, aggregate=False, write_to_ pp.close() -def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None): +def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): + plot_custom_text = False sig_probs = False pcawg = False - if plot_type == '96': - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - if first_line[0][1] == ">": - pcawg = True - if first_line[0][5] != "]" and first_line[0][1] != ">": - sys.exit("The matrix does not match the correct SBS96 format. Please check you formatting and rerun this plotting function.") - - pp = PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') - mutations = OrderedDict() - total_count = [] + if plot_type == '96': try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[2:] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] - - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['C>A'] = OrderedDict() - mutations[sample]['C>G'] = OrderedDict() - mutations[sample]['C>T'] = OrderedDict() - mutations[sample]['T>A'] = OrderedDict() - mutations[sample]['T>C'] = OrderedDict() - mutations[sample]['T>G'] = OrderedDict() - - - for lines in f: - if pcawg: - line = lines.strip().split(",") - mut_type = line[0] - nuc = line[1][0] + "[" + mut_type + "]" + line[1][2] - sample_index = 2 - else: - line = lines.strip().split() - nuc = line[0] - mut_type = line[0][2:5] - sample_index = 1 - - for sample in samples: - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') - mutations[sample][mut_type][nuc] = mutCount - sample_index += 1 - + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + + data= reindex_sbs96(data) sample_count = 0 - for sample in mutations.keys(): - total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='lightgray') - panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) - xlabels = [] - + buf= io.BytesIO() + + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS96.pkl','rb')) + pickle.dump(fig_orig, buf) + figs={} + buff_list={} + ctx = data.index #[seq[0]+seq[2]+seq[6] for seq in data.index] + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + colorsall= [[colors[j] for i in range(int(len(ctx)/6))] for j in range(6)] + colors_flat_list = [item for sublist in colorsall for item in sublist] + + for sample in data.columns: + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + + total_count = np.sum(data[sample].values) #sum(sum(nuc.values()) for nuc in mutations[sample].values()) x = 0.4 ymax = 0 - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] i = 0 - for key in mutations[sample]: - for seq in mutations[sample][key]: - xlabels.append(seq[0]+seq[2]+seq[6]) - if percentage: - if total_count > 0: - plt.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq]/total_count*100 > ymax: - ymax = mutations[sample][key][seq]/total_count*100 - else: - plt.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq] > ymax: - ymax = mutations[sample][key][seq] - x += 1 - i += 1 + muts = data[sample].values + if percentage: + if total_count > 0: + plt.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + plt.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) x = .043 y3 = .87 y = int(ymax*1.25) y2 = y+2 - for i in range(0, 6, 1): - panel1.add_patch(plt.Rectangle((x,y3), .15, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .159 - - yText = y3 + .06 - plt.text(.1, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.255, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.415, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.575, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.735, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.89, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) if y <= 4: y += 4 @@ -570,11 +651,11 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] labs = np.arange(0.375,96.375,1) @@ -589,47 +670,23 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if not percentage: ylabels= getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 96]) panel1.set_ylim([0, y]) - panel1.set_xticks(labs) panel1.set_yticks(ylabs) - count = 0 - m = 0 - for i in range (0, 96, 1): - plt.text(i/101 + .0415, .02, xlabels[i][0], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - plt.text(i/101 + .0415, .044, xlabels[i][1], fontsize=30, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) - plt.text(i/101 + .0415, .071, xlabels[i][2], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - count += 1 - if count == 16: - count = 0 - m += 1 - + if sig_probs: plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) else: plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + panel1.set_yticklabels(ylabels, fontsize=font_label_size) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') custom_text_upper_plot = '' try: @@ -677,33 +734,41 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - panel1.set_yticklabels(ylabels, fontsize=font_label_size) - plt.gca().yaxis.grid(True) - plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.set_xlabel('') - panel1.set_ylabel('') - if percentage: plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') else: plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - - panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) [i.set_color("black") for i in plt.gca().get_yticklabels()] - pp.savefig(plot1) - plt.close() sample_count += 1 - pp.close() + + + if savefig_format == "pdf": + pp = PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') + + + if savefig_format == "pdf": + for fig in figs: + figs[fig].savefig(pp, format='pdf') + pp.close() + + if savefig_format == "png": + for fig in figs: + figs[fig].savefig(output_path + 'SBS_96_plots_'+fig+'.png',dpi=100) + if savefig_format == "buffer_stream": + for fig in figs: + buffer2=io.BytesIO() + figs[fig].savefig(buffer2,format='png') + buff_list[fig]=buffer2 + return buff_list except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'SBS_96_plots_' + project + '.pdf') @@ -3318,10 +3383,8 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust pp.close() except: - print("There may be an issue with the formatting of your matrix file.") - os.remove(output_path + 'SBS_288_plots_' + project + '.pdf') - - + print("There may be an issue with the formatting of your matrix file.") + os.remove(output_path + 'SBS_288_plots_' + project + '.pdf') elif plot_type == '288_Normalized': with open(matrix_path) as f: diff --git a/setup.py b/setup.py index c2dd1a2..c1da74f 100644 --- a/setup.py +++ b/setup.py @@ -53,13 +53,20 @@ def run(self): file_names = ["Times New Roman.ttf", "Arial.ttf", "Courier New.ttf", "Courier New Bold.ttf", "Arial Bold.ttf", "Times New Roman Bold.ttf"] for file in file_names: - old_path = os.path.join(cp_ttf_dir, "fonts/" + file) - new_path = os.path.join(mpl_ttf_dir, file) - shutil.copyfile(old_path, new_path) + old_path = os.path.join(cp_ttf_dir, "fonts/" + file) + new_path = os.path.join(mpl_ttf_dir, file) + shutil.copyfile(old_path, new_path) matplotlib.font_manager._rebuild() except: warnings.warn("WARNING: An issue occured while installing the fonts.") + #install figure templates + try: + import sigProfilerPlotting as sigPlt + sigPlt.install_plot_templates('SBS96') + os.system("echo 'installed figure templates' ") + except: + print("Failed to install templates") @@ -78,3 +85,4 @@ def run(self): #Specify the custom install class cmdclass={'install' : move_ttf}, zip_safe=False) + diff --git a/sigProfilerPlotting.egg-info/PKG-INFO b/sigProfilerPlotting.egg-info/PKG-INFO index 8dc31ba..54ad03f 100644 --- a/sigProfilerPlotting.egg-info/PKG-INFO +++ b/sigProfilerPlotting.egg-info/PKG-INFO @@ -6,8 +6,4 @@ Home-page: Author: Erik Bergstrom Author-email: ebergstr@eng.ucsd.edu License: UCSD -Platform: UNKNOWN License-File: LICENSE - -UNKNOWN - From c3efce7e879a9ec412e4b86acbd2a9e70320758f Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 23 Aug 2022 06:51:36 -0700 Subject: [PATCH 05/21] removing temp files --- sigProfilerPlotting.egg-info/PKG-INFO | 9 -------- sigProfilerPlotting.egg-info/SOURCES.txt | 22 ------------------- .../dependency_links.txt | 1 - sigProfilerPlotting.egg-info/not-zip-safe | 1 - sigProfilerPlotting.egg-info/requires.txt | 3 --- sigProfilerPlotting.egg-info/top_level.txt | 1 - 6 files changed, 37 deletions(-) delete mode 100644 sigProfilerPlotting.egg-info/PKG-INFO delete mode 100644 sigProfilerPlotting.egg-info/SOURCES.txt delete mode 100644 sigProfilerPlotting.egg-info/dependency_links.txt delete mode 100644 sigProfilerPlotting.egg-info/not-zip-safe delete mode 100644 sigProfilerPlotting.egg-info/requires.txt delete mode 100644 sigProfilerPlotting.egg-info/top_level.txt diff --git a/sigProfilerPlotting.egg-info/PKG-INFO b/sigProfilerPlotting.egg-info/PKG-INFO deleted file mode 100644 index 54ad03f..0000000 --- a/sigProfilerPlotting.egg-info/PKG-INFO +++ /dev/null @@ -1,9 +0,0 @@ -Metadata-Version: 2.1 -Name: sigProfilerPlotting -Version: 1.2.2 -Summary: SigProfiler plotting tool -Home-page: -Author: Erik Bergstrom -Author-email: ebergstr@eng.ucsd.edu -License: UCSD -License-File: LICENSE diff --git a/sigProfilerPlotting.egg-info/SOURCES.txt b/sigProfilerPlotting.egg-info/SOURCES.txt deleted file mode 100644 index a029009..0000000 --- a/sigProfilerPlotting.egg-info/SOURCES.txt +++ /dev/null @@ -1,22 +0,0 @@ -LICENSE -MANIFEST.in -README.md -setup.py -fonts/Arial Bold.ttf -fonts/Arial.ttf -fonts/Courier New Bold.ttf -fonts/Courier New.ttf -fonts/Times New Roman Bold.ttf -fonts/Times New Roman.ttf -fonts/__init__.py -sigProfilerPlotting/__init__.py -sigProfilerPlotting/sample_portrait.py -sigProfilerPlotting/sigProfilerPlotting.py -sigProfilerPlotting/sigProfilerPlotting_old.py -sigProfilerPlotting/version.py -sigProfilerPlotting.egg-info/PKG-INFO -sigProfilerPlotting.egg-info/SOURCES.txt -sigProfilerPlotting.egg-info/dependency_links.txt -sigProfilerPlotting.egg-info/not-zip-safe -sigProfilerPlotting.egg-info/requires.txt -sigProfilerPlotting.egg-info/top_level.txt \ No newline at end of file diff --git a/sigProfilerPlotting.egg-info/dependency_links.txt b/sigProfilerPlotting.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/sigProfilerPlotting.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/sigProfilerPlotting.egg-info/not-zip-safe b/sigProfilerPlotting.egg-info/not-zip-safe deleted file mode 100644 index 8b13789..0000000 --- a/sigProfilerPlotting.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/sigProfilerPlotting.egg-info/requires.txt b/sigProfilerPlotting.egg-info/requires.txt deleted file mode 100644 index 39ee474..0000000 --- a/sigProfilerPlotting.egg-info/requires.txt +++ /dev/null @@ -1,3 +0,0 @@ -matplotlib<=3.4.3,>=3.3.0 -pandas -seaborn diff --git a/sigProfilerPlotting.egg-info/top_level.txt b/sigProfilerPlotting.egg-info/top_level.txt deleted file mode 100644 index faf5a12..0000000 --- a/sigProfilerPlotting.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -sigProfilerPlotting From 4affd6d7295bf32caf985a38907515e1d59262ce Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:06:49 -0700 Subject: [PATCH 06/21] SBS 96 288 modifications --- input/examples/samples/test1536.all | 1537 +++++++++++++++++ input/examples/samples/test288.all | 289 ++++ output/examples/BRCA_example_CNV48_counts.pdf | Bin 35368 -> 0 bytes output/examples/BRCA_example_RS32_counts.pdf | Bin 30756 -> 0 bytes .../examples/SBS_384_plots_BRCA_example.pdf | Bin 72395 -> 0 bytes output/examples/SBS_96_plots_BRCA_example.pdf | Bin 57488 -> 0 bytes setup.py | 1 + .../plot_example.py | 0 sigProfilerPlotting/sigProfilerPlotting.py | 967 +++++++---- 9 files changed, 2475 insertions(+), 319 deletions(-) create mode 100755 input/examples/samples/test1536.all create mode 100755 input/examples/samples/test288.all delete mode 100644 output/examples/BRCA_example_CNV48_counts.pdf delete mode 100644 output/examples/BRCA_example_RS32_counts.pdf delete mode 100644 output/examples/SBS_384_plots_BRCA_example.pdf delete mode 100644 output/examples/SBS_96_plots_BRCA_example.pdf rename plot_example.py => sigProfilerPlotting/plot_example.py (100%) diff --git a/input/examples/samples/test1536.all b/input/examples/samples/test1536.all new file mode 100755 index 0000000..a1a8965 --- /dev/null +++ b/input/examples/samples/test1536.all @@ -0,0 +1,1537 @@ +MutationType Sample 1 Sample 2 Sample 3 Sample 4 Sample 5 Sample 6 Sample 7 Sample 8 Sample 9 Sample 10 Sample 11 Sample 12 Sample 13 Sample 14 Sample 15 +AA[C>A]AA 43 13 46 35 18 6 15 14 14 14 3 10 25 14 14 +AA[C>A]AC 13 6 23 11 5 1 3 8 7 5 1 2 7 10 5 +AA[C>A]AG 18 5 14 7 4 4 2 4 6 5 2 1 6 5 5 +AA[C>A]AT 16 7 21 19 6 1 10 8 12 16 4 5 15 7 7 +AA[C>A]CA 19 6 19 8 7 1 6 8 7 8 2 3 4 12 4 +AA[C>A]CC 9 0 4 6 8 2 2 7 6 1 1 2 10 4 2 +AA[C>A]CG 3 0 0 0 0 0 0 0 0 0 0 0 1 0 0 +AA[C>A]CT 12 7 8 13 10 1 8 11 5 6 0 3 8 10 4 +AA[C>A]GA 5 1 2 4 2 0 1 2 1 1 0 1 1 0 0 +AA[C>A]GC 1 0 0 0 0 0 0 2 1 0 0 1 2 1 2 +AA[C>A]GG 2 0 1 2 0 1 3 0 0 0 0 1 0 1 1 +AA[C>A]GT 2 1 1 3 1 1 2 1 0 2 2 0 2 0 2 +AA[C>A]TA 15 5 14 4 4 5 4 7 1 2 2 1 1 5 3 +AA[C>A]TC 8 4 5 7 3 0 4 3 6 7 0 3 8 7 2 +AA[C>A]TG 11 6 11 5 6 0 1 6 6 4 1 1 7 4 5 +AA[C>A]TT 10 6 14 7 5 2 3 10 7 8 0 6 7 8 6 +AA[C>G]AA 11 4 8 10 8 2 7 10 7 9 0 2 8 8 7 +AA[C>G]AC 1 1 2 2 1 0 1 3 0 4 0 1 2 0 3 +AA[C>G]AG 4 9 8 4 7 3 5 8 4 7 2 3 12 11 5 +AA[C>G]AT 8 2 1 1 2 0 4 5 2 4 0 1 2 1 0 +AA[C>G]CA 6 5 7 6 5 0 2 11 3 3 0 1 5 2 4 +AA[C>G]CC 2 0 2 1 2 0 3 1 1 3 1 1 0 1 1 +AA[C>G]CG 1 1 1 1 0 0 1 1 1 0 0 0 1 0 0 +AA[C>G]CT 10 1 4 2 4 0 1 6 3 4 0 1 1 4 2 +AA[C>G]GA 1 1 1 0 0 1 1 0 1 3 1 0 1 1 0 +AA[C>G]GC 0 0 0 0 1 0 1 0 0 1 1 0 2 0 0 +AA[C>G]GG 2 0 1 0 2 0 1 0 1 1 0 0 0 1 0 +AA[C>G]GT 0 1 1 1 1 0 1 1 2 3 0 1 0 1 0 +AA[C>G]TA 10 6 5 2 7 0 3 11 4 13 1 1 2 5 2 +AA[C>G]TC 2 1 8 3 1 0 3 2 9 1 1 2 1 1 1 +AA[C>G]TG 5 2 4 2 8 1 4 7 5 8 3 0 4 2 1 +AA[C>G]TT 6 2 13 5 5 1 5 8 7 6 0 1 4 6 2 +AA[C>T]AA 16 12 8 14 6 4 6 8 7 11 1 5 12 8 6 +AA[C>T]AC 10 0 5 3 5 2 0 9 3 4 1 1 5 4 6 +AA[C>T]AG 13 6 10 9 5 4 1 9 3 3 2 0 5 5 7 +AA[C>T]AT 23 9 19 17 11 3 11 12 14 13 4 3 10 14 10 +AA[C>T]CA 12 8 7 4 9 0 5 7 2 6 3 2 1 4 5 +AA[C>T]CC 4 6 6 2 4 0 3 10 4 4 0 2 1 4 0 +AA[C>T]CG 1 0 1 0 0 0 0 3 1 1 0 0 0 0 0 +AA[C>T]CT 11 9 5 5 3 3 10 4 5 10 1 7 10 0 7 +AA[C>T]GA 22 8 10 14 13 4 8 5 4 21 1 4 8 2 7 +AA[C>T]GC 16 10 3 6 3 1 7 5 5 13 0 0 6 5 4 +AA[C>T]GG 20 6 8 10 10 4 5 9 6 7 1 0 10 3 4 +AA[C>T]GT 22 11 6 13 5 1 4 3 4 11 0 2 9 7 2 +AA[C>T]TA 8 5 11 4 5 3 2 4 4 5 4 3 5 1 4 +AA[C>T]TC 7 5 4 6 4 0 6 5 7 9 0 0 6 7 2 +AA[C>T]TG 8 9 9 3 2 1 3 6 7 3 1 2 2 4 2 +AA[C>T]TT 6 4 7 11 6 3 5 9 7 4 3 1 5 3 3 +AA[T>A]AA 28 4 11 6 9 4 5 10 9 9 2 3 7 7 6 +AA[T>A]AC 17 3 3 4 6 5 5 7 3 3 1 2 4 3 1 +AA[T>A]AG 14 3 5 4 3 4 1 4 3 2 1 1 2 3 2 +AA[T>A]AT 51 5 6 1 4 5 3 5 5 13 0 6 5 2 4 +AA[T>A]CA 7 7 3 2 1 1 6 3 3 3 1 2 3 1 3 +AA[T>A]CC 3 3 3 6 4 1 1 5 1 3 2 0 3 0 0 +AA[T>A]CG 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +AA[T>A]CT 9 1 5 4 2 1 0 5 3 1 1 3 0 2 3 +AA[T>A]GA 11 5 8 2 3 6 5 5 2 3 2 2 3 4 10 +AA[T>A]GC 5 1 0 1 3 1 5 4 4 4 2 2 4 2 1 +AA[T>A]GG 6 2 6 2 3 1 5 3 2 5 1 3 2 4 1 +AA[T>A]GT 21 10 5 6 8 1 12 9 9 6 2 4 2 7 3 +AA[T>A]TA 33 1 7 9 4 3 3 9 9 6 4 2 1 4 4 +AA[T>A]TC 12 2 8 1 6 4 3 5 2 3 1 2 0 2 3 +AA[T>A]TG 9 2 2 0 1 4 1 4 6 4 0 0 1 1 6 +AA[T>A]TT 28 11 13 15 13 10 6 21 21 17 2 2 6 4 5 +AA[T>C]AA 38 19 48 29 17 5 16 17 11 18 7 4 17 30 5 +AA[T>C]AC 35 32 47 22 20 3 12 16 19 15 4 8 12 14 5 +AA[T>C]AG 32 20 20 19 9 3 7 17 6 22 4 4 10 15 10 +AA[T>C]AT 59 24 56 30 9 6 10 15 15 25 4 6 21 34 6 +AA[T>C]CA 29 11 28 12 11 1 7 12 10 10 1 0 11 26 3 +AA[T>C]CC 24 4 34 6 12 2 5 9 2 9 2 1 4 11 3 +AA[T>C]CG 1 0 0 0 1 0 0 2 0 3 0 1 0 0 0 +AA[T>C]CT 17 6 19 6 12 0 7 4 11 6 5 2 8 13 0 +AA[T>C]GA 25 7 25 21 9 2 12 16 14 16 3 4 11 15 7 +AA[T>C]GC 21 15 34 10 16 3 5 13 6 8 4 3 8 8 1 +AA[T>C]GG 15 11 25 14 13 1 7 7 5 11 3 3 6 9 6 +AA[T>C]GT 25 14 35 25 20 5 9 11 11 14 4 4 14 14 4 +AA[T>C]TA 20 3 15 21 14 1 12 14 11 8 2 7 5 15 5 +AA[T>C]TC 24 11 13 6 10 1 5 6 8 15 1 4 8 8 1 +AA[T>C]TG 15 14 20 16 12 4 9 8 9 10 3 1 15 21 10 +AA[T>C]TT 18 9 25 12 8 4 12 13 9 20 2 2 14 9 8 +AA[T>G]AA 13 2 3 4 9 2 4 11 2 7 1 0 3 2 5 +AA[T>G]AC 2 0 4 1 1 0 3 4 1 3 0 0 2 0 0 +AA[T>G]AG 6 2 4 2 3 3 2 0 2 2 0 1 1 5 0 +AA[T>G]AT 8 3 3 2 6 0 3 5 5 3 0 1 2 2 2 +AA[T>G]CA 5 4 1 4 4 0 3 4 3 7 0 0 1 3 2 +AA[T>G]CC 3 0 6 1 0 0 2 1 1 5 1 1 2 1 1 +AA[T>G]CG 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 +AA[T>G]CT 6 0 7 1 6 0 0 7 6 6 0 1 2 2 0 +AA[T>G]GA 8 1 4 2 5 1 4 20 5 6 0 1 2 7 0 +AA[T>G]GC 2 0 1 4 3 0 2 3 2 7 0 0 0 3 0 +AA[T>G]GG 1 0 2 0 2 0 2 4 2 1 0 0 2 2 0 +AA[T>G]GT 5 0 2 1 4 0 2 7 1 1 1 1 2 2 3 +AA[T>G]TA 10 1 14 6 6 1 12 12 8 16 4 3 5 1 4 +AA[T>G]TC 10 5 6 5 1 0 2 5 4 9 1 2 2 3 4 +AA[T>G]TG 5 3 5 2 4 0 3 8 4 4 0 1 2 1 0 +AA[T>G]TT 15 4 5 3 11 0 6 9 7 24 1 6 6 8 8 +AC[C>A]AA 24 10 20 20 5 4 11 4 7 12 1 2 15 9 6 +AC[C>A]AC 12 6 14 14 1 2 5 10 4 6 2 3 8 4 11 +AC[C>A]AG 13 6 6 7 7 4 2 5 5 6 1 0 11 7 4 +AC[C>A]AT 38 15 17 24 12 1 11 4 8 14 0 3 13 13 6 +AC[C>A]CA 22 7 17 7 8 0 4 8 5 2 2 4 8 9 4 +AC[C>A]CC 12 3 13 6 3 0 4 6 4 5 2 2 2 5 3 +AC[C>A]CG 3 1 0 3 1 0 1 2 2 1 0 0 0 1 1 +AC[C>A]CT 13 9 9 8 9 2 4 7 6 8 1 2 8 12 1 +AC[C>A]GA 3 1 1 0 2 0 0 0 1 1 0 1 0 0 0 +AC[C>A]GC 1 1 2 3 0 1 0 0 2 0 0 0 0 0 1 +AC[C>A]GG 0 0 2 1 0 0 0 0 0 1 0 0 0 0 2 +AC[C>A]GT 1 0 2 1 0 0 0 2 2 0 0 0 0 1 2 +AC[C>A]TA 13 3 6 4 3 0 4 4 6 4 3 1 5 5 4 +AC[C>A]TC 7 2 12 5 4 1 8 10 5 8 1 0 5 6 3 +AC[C>A]TG 9 4 9 8 7 1 8 8 5 12 1 1 9 3 5 +AC[C>A]TT 12 4 12 10 4 3 9 3 2 10 2 1 11 7 7 +AC[C>G]AA 11 3 11 7 5 3 1 5 8 6 0 1 3 0 2 +AC[C>G]AC 3 1 1 5 2 0 1 1 1 1 0 1 3 4 1 +AC[C>G]AG 3 2 5 1 4 2 4 5 1 2 1 1 1 3 1 +AC[C>G]AT 5 2 6 1 5 0 2 6 4 0 2 1 0 0 4 +AC[C>G]CA 8 1 7 4 4 1 3 5 3 6 1 0 3 5 1 +AC[C>G]CC 5 3 0 1 2 0 2 4 1 2 0 1 1 2 0 +AC[C>G]CG 0 0 0 1 0 0 1 2 0 1 0 0 0 0 0 +AC[C>G]CT 7 4 5 2 4 1 3 3 7 9 2 0 5 4 3 +AC[C>G]GA 1 0 2 2 0 0 0 0 0 0 0 0 0 0 1 +AC[C>G]GC 1 0 0 2 1 0 2 0 0 1 0 0 1 0 0 +AC[C>G]GG 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 +AC[C>G]GT 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 +AC[C>G]TA 5 5 2 6 5 0 6 8 2 3 0 0 1 1 2 +AC[C>G]TC 1 3 3 3 8 2 3 4 6 4 2 2 2 2 0 +AC[C>G]TG 5 3 4 5 3 2 1 3 3 2 3 2 1 2 1 +AC[C>G]TT 7 2 6 5 6 2 6 7 7 5 1 0 3 5 2 +AC[C>T]AA 9 8 12 8 8 3 5 7 3 5 0 3 5 10 3 +AC[C>T]AC 6 3 9 8 6 5 2 2 2 5 0 2 5 4 1 +AC[C>T]AG 8 2 8 11 8 2 6 7 6 5 1 0 2 6 0 +AC[C>T]AT 15 6 11 11 10 4 4 5 7 6 2 2 5 5 5 +AC[C>T]CA 9 4 12 6 3 2 2 11 6 8 0 2 6 5 5 +AC[C>T]CC 10 3 7 5 5 3 4 6 4 2 1 2 6 3 4 +AC[C>T]CG 1 3 2 0 1 0 0 1 1 0 1 0 1 1 1 +AC[C>T]CT 10 4 6 13 5 3 7 6 4 8 2 3 3 9 7 +AC[C>T]GA 5 3 4 4 0 0 6 2 4 0 1 2 3 0 1 +AC[C>T]GC 10 5 8 6 6 1 2 2 3 4 0 0 4 1 2 +AC[C>T]GG 2 5 1 5 1 0 2 1 2 2 0 0 2 2 0 +AC[C>T]GT 5 2 3 5 3 1 2 3 3 7 1 1 5 2 0 +AC[C>T]TA 3 5 7 9 4 4 3 7 5 8 0 0 3 5 3 +AC[C>T]TC 10 11 3 8 11 3 4 8 5 4 0 2 4 11 1 +AC[C>T]TG 8 6 10 9 6 3 6 6 7 8 4 0 5 5 3 +AC[C>T]TT 16 13 11 13 5 3 12 11 6 4 6 3 6 3 5 +AC[T>A]AA 17 3 6 4 3 0 4 6 3 1 1 0 6 3 1 +AC[T>A]AC 7 0 0 0 3 1 4 2 4 6 3 0 2 0 2 +AC[T>A]AG 15 1 2 2 2 1 2 4 1 0 0 1 1 4 2 +AC[T>A]AT 44 1 7 3 7 2 1 3 0 1 1 2 1 0 7 +AC[T>A]CA 17 8 2 5 2 3 0 3 3 9 0 1 1 4 4 +AC[T>A]CC 11 2 4 2 1 1 1 5 2 1 0 0 3 5 2 +AC[T>A]CG 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0 +AC[T>A]CT 14 1 9 6 6 1 2 7 6 3 2 3 4 8 2 +AC[T>A]GA 17 2 4 3 11 0 2 6 5 2 1 1 4 2 0 +AC[T>A]GC 16 1 9 5 4 0 2 2 4 2 1 4 3 3 1 +AC[T>A]GG 11 1 6 2 4 3 3 4 0 4 1 2 2 3 5 +AC[T>A]GT 46 1 2 2 2 2 5 6 4 4 2 0 2 5 0 +AC[T>A]TA 11 5 3 4 5 1 2 7 0 6 1 1 2 2 6 +AC[T>A]TC 8 4 3 3 2 1 3 3 5 2 1 2 1 1 1 +AC[T>A]TG 15 2 7 2 5 0 2 3 2 1 1 0 4 1 0 +AC[T>A]TT 14 4 5 7 5 0 5 7 6 8 2 3 1 10 5 +AC[T>C]AA 10 5 16 9 4 4 6 8 5 8 3 5 1 9 6 +AC[T>C]AC 7 3 8 8 8 0 4 7 3 5 2 0 3 2 3 +AC[T>C]AG 3 3 2 0 9 1 2 3 4 6 2 2 2 5 4 +AC[T>C]AT 10 2 12 10 5 2 3 7 7 5 1 0 4 8 5 +AC[T>C]CA 11 9 16 9 2 4 7 2 4 3 1 1 1 5 3 +AC[T>C]CC 6 3 11 3 6 1 6 3 3 5 1 1 5 7 2 +AC[T>C]CG 0 1 0 2 0 0 0 0 0 0 0 0 0 1 0 +AC[T>C]CT 13 9 16 13 4 3 3 9 3 6 0 5 7 8 1 +AC[T>C]GA 5 3 8 7 2 1 3 4 7 2 1 1 4 6 1 +AC[T>C]GC 8 3 8 4 6 3 2 7 3 2 1 2 9 10 1 +AC[T>C]GG 6 2 2 5 4 1 3 8 5 4 3 3 3 7 1 +AC[T>C]GT 9 2 8 6 3 1 3 6 5 0 1 2 2 8 2 +AC[T>C]TA 8 7 7 4 4 2 0 5 3 6 3 2 4 11 0 +AC[T>C]TC 12 5 27 7 5 0 12 10 7 7 0 0 11 11 1 +AC[T>C]TG 8 4 10 10 6 0 4 9 5 5 2 1 7 7 3 +AC[T>C]TT 22 9 31 19 9 2 12 9 7 12 3 3 8 15 3 +AC[T>G]AA 5 2 1 0 2 1 1 7 2 2 0 0 0 0 0 +AC[T>G]AC 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 +AC[T>G]AG 2 0 1 0 0 0 0 0 1 0 0 1 1 0 1 +AC[T>G]AT 4 1 0 0 0 0 1 2 1 0 0 1 0 0 0 +AC[T>G]CA 3 1 3 3 0 1 2 1 1 3 0 2 0 0 4 +AC[T>G]CC 1 0 2 1 0 2 2 2 1 1 0 1 0 0 1 +AC[T>G]CG 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 +AC[T>G]CT 3 1 1 0 2 0 0 0 2 1 0 0 2 1 0 +AC[T>G]GA 3 2 5 2 4 0 3 3 2 4 1 1 2 1 0 +AC[T>G]GC 2 1 3 2 1 0 1 1 2 1 1 1 3 3 1 +AC[T>G]GG 3 1 4 2 1 0 1 1 4 1 0 0 0 1 0 +AC[T>G]GT 5 2 1 1 1 1 1 3 0 0 0 1 1 0 2 +AC[T>G]TA 6 2 3 3 9 3 4 5 6 4 0 1 0 2 0 +AC[T>G]TC 4 3 5 4 2 0 1 2 2 2 1 1 0 1 0 +AC[T>G]TG 1 1 2 2 1 1 3 2 0 1 1 0 4 1 0 +AC[T>G]TT 7 2 2 3 4 1 5 8 2 3 0 0 8 4 4 +AG[C>A]AA 24 6 14 17 7 2 3 14 2 6 2 3 8 6 6 +AG[C>A]AC 10 3 10 5 1 2 4 8 7 2 3 3 0 7 4 +AG[C>A]AG 15 2 10 5 4 3 4 8 4 2 2 1 2 9 6 +AG[C>A]AT 20 9 12 15 8 3 3 3 12 4 2 2 5 1 3 +AG[C>A]CA 18 5 13 11 3 0 3 10 9 6 1 3 3 9 7 +AG[C>A]CC 11 3 8 4 5 0 2 3 3 2 0 0 2 3 5 +AG[C>A]CG 1 0 2 0 1 0 1 2 2 1 1 0 1 0 1 +AG[C>A]CT 13 2 11 7 6 0 4 6 6 4 3 3 1 5 1 +AG[C>A]GA 5 1 2 3 3 1 0 0 0 1 0 1 2 0 1 +AG[C>A]GC 1 1 0 1 1 0 0 2 1 1 0 0 1 0 0 +AG[C>A]GG 2 1 2 2 1 0 0 0 1 1 0 0 1 1 1 +AG[C>A]GT 0 1 0 0 1 0 2 0 0 0 0 0 1 0 1 +AG[C>A]TA 11 4 11 4 0 0 3 4 4 3 2 1 3 7 4 +AG[C>A]TC 5 3 4 3 2 0 0 4 0 4 0 1 1 2 2 +AG[C>A]TG 17 5 3 5 5 3 5 6 5 5 1 1 5 5 2 +AG[C>A]TT 13 7 8 1 4 0 6 8 6 5 0 0 6 7 5 +AG[C>G]AA 10 3 6 3 2 1 1 6 1 2 2 0 2 5 4 +AG[C>G]AC 2 1 1 0 0 0 1 1 3 2 0 1 0 1 1 +AG[C>G]AG 5 3 2 4 3 0 2 8 1 3 2 0 2 1 2 +AG[C>G]AT 1 2 10 3 4 2 1 0 0 2 1 0 2 2 1 +AG[C>G]CA 9 7 5 2 7 1 1 6 1 6 2 1 1 3 1 +AG[C>G]CC 6 3 0 3 3 0 1 2 1 3 0 1 2 1 0 +AG[C>G]CG 1 0 0 0 0 0 1 0 2 0 0 0 0 0 2 +AG[C>G]CT 9 3 3 3 5 1 2 7 5 2 1 1 2 3 2 +AG[C>G]GA 1 0 1 0 0 0 1 1 1 0 0 1 2 1 0 +AG[C>G]GC 0 1 0 0 0 0 2 0 0 0 0 0 1 0 1 +AG[C>G]GG 0 0 0 2 0 0 0 2 0 0 0 0 0 0 0 +AG[C>G]GT 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 +AG[C>G]TA 7 2 4 2 0 1 2 5 5 4 1 0 4 3 3 +AG[C>G]TC 3 1 5 1 2 1 2 3 2 3 0 1 0 2 0 +AG[C>G]TG 4 1 4 4 2 2 1 3 1 1 0 0 1 0 1 +AG[C>G]TT 6 2 1 5 0 2 2 3 1 5 1 1 1 5 2 +AG[C>T]AA 10 6 9 10 7 0 4 12 4 3 1 1 4 6 3 +AG[C>T]AC 5 3 8 5 3 0 5 6 1 7 0 2 8 5 2 +AG[C>T]AG 9 2 10 7 8 1 12 10 7 12 2 2 3 1 5 +AG[C>T]AT 19 4 14 7 10 1 5 7 6 7 3 3 6 9 3 +AG[C>T]CA 14 7 12 10 8 4 8 6 3 8 3 1 6 8 6 +AG[C>T]CC 5 3 5 6 5 2 4 11 7 6 0 0 3 3 2 +AG[C>T]CG 3 0 1 0 1 0 0 1 0 1 0 0 1 2 1 +AG[C>T]CT 16 5 11 3 9 2 5 9 5 8 5 1 2 5 4 +AG[C>T]GA 11 3 5 5 9 0 7 6 6 6 1 0 3 3 2 +AG[C>T]GC 14 5 5 3 3 0 2 3 0 4 0 1 5 2 3 +AG[C>T]GG 8 3 3 6 4 1 4 5 6 10 0 0 1 4 4 +AG[C>T]GT 9 6 3 4 3 0 0 2 4 6 1 3 0 2 1 +AG[C>T]TA 7 4 10 3 10 1 7 7 3 6 2 1 6 4 4 +AG[C>T]TC 3 5 5 6 6 2 3 4 2 2 0 0 3 4 6 +AG[C>T]TG 15 10 10 6 5 3 4 4 6 9 1 2 5 3 11 +AG[C>T]TT 6 4 11 8 4 5 6 4 3 8 2 1 5 7 8 +AG[T>A]AA 9 3 0 1 1 2 6 1 2 3 1 3 2 4 1 +AG[T>A]AC 1 2 6 2 5 0 2 5 0 0 1 1 2 0 2 +AG[T>A]AG 16 1 1 3 2 1 2 2 1 1 1 1 1 1 1 +AG[T>A]AT 7 0 2 0 4 1 2 3 6 3 1 1 2 1 0 +AG[T>A]CA 11 3 9 7 3 1 2 4 0 4 0 1 2 7 1 +AG[T>A]CC 8 1 4 1 3 0 0 2 2 1 0 0 2 1 1 +AG[T>A]CG 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 +AG[T>A]CT 3 2 3 1 0 0 2 2 3 2 0 2 0 1 3 +AG[T>A]GA 8 0 4 4 5 1 2 5 0 2 1 2 1 0 1 +AG[T>A]GC 7 0 5 3 0 1 2 0 2 1 2 2 0 0 0 +AG[T>A]GG 9 0 1 2 3 0 4 2 4 0 0 0 1 7 0 +AG[T>A]GT 5 1 6 2 1 1 3 2 4 1 0 0 2 3 1 +AG[T>A]TA 8 4 2 0 2 1 1 2 2 4 0 1 4 3 2 +AG[T>A]TC 4 1 3 0 1 0 0 1 1 0 1 1 3 0 1 +AG[T>A]TG 4 1 4 3 2 1 0 3 1 1 0 0 1 4 2 +AG[T>A]TT 7 3 9 5 5 2 3 3 3 4 3 1 1 5 6 +AG[T>C]AA 24 14 29 13 11 1 7 9 12 16 1 3 12 20 2 +AG[T>C]AC 11 16 21 15 14 0 9 6 4 9 1 2 4 11 3 +AG[T>C]AG 19 9 23 15 9 2 8 5 6 10 2 5 6 10 3 +AG[T>C]AT 27 14 38 17 12 0 16 9 9 8 1 2 14 19 3 +AG[T>C]CA 24 10 36 9 6 1 12 11 8 12 1 2 8 12 0 +AG[T>C]CC 20 12 10 8 9 1 8 3 8 6 1 2 6 7 1 +AG[T>C]CG 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 +AG[T>C]CT 14 9 16 14 14 2 10 8 4 9 1 3 6 7 1 +AG[T>C]GA 9 9 23 11 11 1 7 12 4 6 2 4 8 10 3 +AG[T>C]GC 11 7 28 5 15 1 10 11 4 6 1 5 8 11 0 +AG[T>C]GG 10 5 13 4 10 0 7 3 3 6 2 1 6 7 0 +AG[T>C]GT 16 8 24 7 6 1 8 6 7 10 3 3 2 16 4 +AG[T>C]TA 11 4 8 3 4 1 3 4 2 7 1 4 3 7 1 +AG[T>C]TC 17 10 30 17 9 0 10 8 5 14 1 5 4 13 2 +AG[T>C]TG 9 4 19 9 5 3 6 5 6 6 1 2 4 7 1 +AG[T>C]TT 11 4 13 3 3 0 8 10 7 9 0 5 8 8 6 +AG[T>G]AA 0 0 2 3 2 0 3 3 0 4 0 0 4 1 1 +AG[T>G]AC 2 1 2 0 1 2 0 0 0 1 0 1 1 0 0 +AG[T>G]AG 1 1 2 0 0 1 1 3 1 1 0 0 0 0 1 +AG[T>G]AT 2 1 0 0 2 0 1 1 2 2 0 1 1 1 0 +AG[T>G]CA 0 3 2 5 1 0 3 1 1 3 0 0 0 2 1 +AG[T>G]CC 2 0 1 0 0 0 1 1 1 0 0 0 1 0 0 +AG[T>G]CG 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 +AG[T>G]CT 0 0 2 0 1 0 0 5 1 2 0 0 0 0 1 +AG[T>G]GA 2 2 2 2 3 0 4 2 0 3 2 1 2 2 0 +AG[T>G]GC 0 0 3 0 0 0 5 1 2 2 0 1 3 1 3 +AG[T>G]GG 3 2 2 0 2 0 1 2 1 2 1 1 0 3 1 +AG[T>G]GT 1 1 2 0 1 0 1 2 3 2 0 1 0 0 0 +AG[T>G]TA 1 4 2 1 2 0 3 3 3 6 1 2 1 1 1 +AG[T>G]TC 1 4 0 0 1 0 4 5 0 0 0 1 1 1 1 +AG[T>G]TG 0 0 0 1 2 0 1 4 5 1 0 0 2 0 2 +AG[T>G]TT 4 2 2 2 5 1 3 3 2 3 1 1 1 1 1 +AT[C>A]AA 18 7 13 10 9 2 11 9 8 8 0 3 8 11 3 +AT[C>A]AC 8 7 7 10 5 0 5 8 8 8 2 3 6 3 4 +AT[C>A]AG 14 3 13 3 7 1 2 3 10 10 2 1 4 6 2 +AT[C>A]AT 20 9 20 10 13 1 2 12 14 9 2 3 5 8 5 +AT[C>A]CA 17 3 21 15 8 0 8 14 9 9 1 4 9 7 4 +AT[C>A]CC 11 6 9 7 4 2 3 10 7 5 4 0 5 7 6 +AT[C>A]CG 0 1 1 3 0 1 0 2 0 2 0 0 1 0 0 +AT[C>A]CT 27 3 12 15 8 0 4 11 8 12 4 1 4 12 7 +AT[C>A]GA 2 1 2 1 2 0 4 0 2 0 0 1 1 1 3 +AT[C>A]GC 3 1 2 2 1 0 0 4 2 3 0 0 1 2 0 +AT[C>A]GG 2 1 0 1 3 0 1 2 1 2 1 1 0 0 0 +AT[C>A]GT 4 0 1 1 0 0 0 0 0 1 0 0 0 0 1 +AT[C>A]TA 21 6 8 7 5 1 9 8 13 11 0 1 5 7 1 +AT[C>A]TC 14 5 5 19 5 2 3 6 10 8 5 7 2 4 4 +AT[C>A]TG 16 5 11 5 13 0 7 6 11 8 4 5 6 5 6 +AT[C>A]TT 28 4 13 13 17 1 8 14 22 4 3 5 10 12 6 +AT[C>G]AA 19 2 17 6 13 0 3 15 7 1 4 3 2 4 3 +AT[C>G]AC 3 2 4 3 3 1 0 6 4 2 1 0 0 0 0 +AT[C>G]AG 5 1 4 4 4 4 5 8 8 2 0 1 1 4 2 +AT[C>G]AT 10 0 6 5 2 0 2 4 1 3 0 3 2 1 2 +AT[C>G]CA 14 1 6 7 7 2 3 7 9 7 1 3 3 1 1 +AT[C>G]CC 4 2 3 2 5 0 2 7 4 3 0 1 2 3 3 +AT[C>G]CG 1 0 3 1 0 0 0 1 0 0 0 0 1 0 0 +AT[C>G]CT 7 3 8 4 5 3 3 8 9 4 3 2 2 5 1 +AT[C>G]GA 1 0 3 2 0 0 2 1 0 1 0 1 0 0 0 +AT[C>G]GC 0 0 0 0 0 0 1 1 2 0 1 0 0 1 0 +AT[C>G]GG 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 +AT[C>G]GT 0 0 0 1 1 1 0 2 3 1 0 2 2 0 0 +AT[C>G]TA 7 5 12 1 13 2 5 11 6 10 0 3 3 3 7 +AT[C>G]TC 17 3 9 8 5 1 2 11 6 4 3 0 4 5 6 +AT[C>G]TG 15 2 9 5 3 0 2 6 4 5 1 1 0 4 0 +AT[C>G]TT 14 5 7 10 10 3 13 16 5 9 2 1 3 5 2 +AT[C>T]AA 14 3 11 9 7 1 3 12 6 10 1 0 5 7 6 +AT[C>T]AC 12 3 9 8 12 2 5 7 5 7 2 1 7 3 2 +AT[C>T]AG 8 6 9 5 6 0 4 13 4 6 0 5 4 9 1 +AT[C>T]AT 17 6 16 13 18 1 10 14 10 10 3 2 7 6 7 +AT[C>T]CA 13 7 7 8 8 1 2 5 9 7 1 1 4 4 5 +AT[C>T]CC 21 5 11 3 8 1 5 6 4 7 1 2 5 5 1 +AT[C>T]CG 0 3 1 0 1 0 0 1 1 1 0 0 2 0 0 +AT[C>T]CT 11 10 9 10 7 4 4 11 5 13 2 2 11 7 9 +AT[C>T]GA 3 1 3 3 0 1 2 5 1 5 1 0 5 2 3 +AT[C>T]GC 12 1 3 3 3 1 1 1 4 3 0 0 5 1 2 +AT[C>T]GG 10 2 2 1 1 0 2 0 1 4 0 0 1 1 0 +AT[C>T]GT 5 3 1 5 2 1 2 2 1 4 0 1 1 4 2 +AT[C>T]TA 5 4 7 6 5 1 1 11 4 8 0 0 3 2 2 +AT[C>T]TC 12 4 10 5 6 0 6 15 6 6 1 0 3 3 7 +AT[C>T]TG 10 2 7 5 6 0 4 8 2 5 2 2 4 3 7 +AT[C>T]TT 16 6 15 8 9 2 5 8 4 10 1 3 6 2 5 +AT[T>A]AA 41 3 8 5 3 1 6 10 4 6 3 1 1 2 2 +AT[T>A]AC 13 2 3 0 7 1 3 6 3 3 0 2 1 4 1 +AT[T>A]AG 33 1 2 2 3 0 1 3 2 0 0 1 4 0 0 +AT[T>A]AT 49 3 8 1 6 2 2 7 7 6 0 2 0 6 0 +AT[T>A]CA 18 5 13 3 11 2 2 2 4 5 0 1 4 8 3 +AT[T>A]CC 13 0 6 6 3 0 5 7 3 6 3 1 1 8 1 +AT[T>A]CG 1 0 0 0 0 0 0 1 0 2 0 0 0 0 0 +AT[T>A]CT 12 4 10 12 6 0 4 9 9 4 5 3 4 8 1 +AT[T>A]GA 13 1 6 5 5 1 3 6 7 2 0 1 2 2 3 +AT[T>A]GC 4 2 3 2 3 3 1 2 2 2 1 3 2 3 0 +AT[T>A]GG 14 0 4 3 1 0 2 4 1 1 0 0 0 0 1 +AT[T>A]GT 24 2 8 3 2 3 1 3 0 8 0 2 3 0 2 +AT[T>A]TA 34 3 12 4 7 4 12 11 15 14 2 6 6 6 5 +AT[T>A]TC 11 2 6 7 12 5 5 10 14 10 0 4 2 8 3 +AT[T>A]TG 33 4 13 6 7 0 7 7 4 15 3 6 4 3 4 +AT[T>A]TT 42 9 20 15 16 7 15 18 18 19 4 11 8 6 13 +AT[T>C]AA 22 19 31 23 7 1 11 13 11 9 2 1 6 15 2 +AT[T>C]AC 17 5 26 14 8 0 9 13 2 8 1 1 7 11 2 +AT[T>C]AG 17 10 23 13 8 3 6 4 11 10 3 2 9 12 0 +AT[T>C]AT 43 26 62 26 25 1 17 15 7 26 1 8 27 24 3 +AT[T>C]CA 8 9 26 15 12 0 5 6 2 10 0 5 5 12 2 +AT[T>C]CC 8 4 8 4 7 0 1 2 2 4 1 1 3 6 1 +AT[T>C]CG 0 0 1 0 0 0 0 1 1 0 0 0 0 2 0 +AT[T>C]CT 17 4 20 10 6 0 6 5 5 4 0 2 6 10 1 +AT[T>C]GA 15 2 13 9 6 0 4 4 4 3 2 2 3 7 0 +AT[T>C]GC 2 7 11 9 2 0 4 7 4 3 1 3 5 12 1 +AT[T>C]GG 4 6 6 2 3 1 1 1 2 7 3 1 0 3 0 +AT[T>C]GT 15 7 11 13 3 0 6 3 5 4 0 0 8 10 1 +AT[T>C]TA 25 5 22 10 6 2 3 6 9 7 0 2 7 14 1 +AT[T>C]TC 23 8 36 19 11 0 9 11 6 11 0 4 9 20 1 +AT[T>C]TG 16 6 15 8 4 0 7 4 2 6 2 2 9 5 2 +AT[T>C]TT 27 18 40 21 8 1 9 6 7 12 0 2 10 14 2 +AT[T>G]AA 13 1 5 0 6 1 1 7 9 5 0 4 6 6 1 +AT[T>G]AC 2 0 2 2 0 0 3 1 3 2 0 0 1 0 0 +AT[T>G]AG 4 0 0 1 0 0 2 3 1 4 1 0 1 2 1 +AT[T>G]AT 4 0 4 3 0 1 8 6 1 5 0 1 3 1 2 +AT[T>G]CA 5 2 7 2 7 0 5 5 6 6 0 3 4 3 0 +AT[T>G]CC 3 2 2 3 3 1 3 4 2 5 0 1 1 1 1 +AT[T>G]CG 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 +AT[T>G]CT 5 6 5 8 9 0 2 3 3 7 1 2 2 1 4 +AT[T>G]GA 2 2 4 2 5 0 2 6 1 1 0 2 1 2 0 +AT[T>G]GC 1 0 2 1 3 0 0 3 4 1 1 2 1 0 1 +AT[T>G]GG 0 0 1 0 1 0 2 7 4 3 1 1 1 1 1 +AT[T>G]GT 9 1 5 1 4 0 1 6 1 2 0 0 1 1 1 +AT[T>G]TA 15 8 10 7 13 4 4 8 4 10 3 3 4 6 8 +AT[T>G]TC 5 2 10 3 3 0 5 7 2 12 1 1 3 3 0 +AT[T>G]TG 6 3 3 2 5 0 3 7 1 6 1 0 4 5 2 +AT[T>G]TT 14 6 16 13 9 0 7 20 4 18 3 0 12 9 4 +CA[C>A]AA 18 9 15 16 9 3 11 6 9 12 3 3 9 11 6 +CA[C>A]AC 15 6 12 7 3 2 5 4 4 3 1 2 6 6 5 +CA[C>A]AG 18 9 9 7 4 0 3 10 6 5 0 1 4 3 6 +CA[C>A]AT 17 3 17 6 3 2 2 12 8 8 1 0 2 5 5 +CA[C>A]CA 24 9 14 6 6 1 3 9 11 5 2 0 4 8 3 +CA[C>A]CC 14 2 4 6 4 0 2 2 1 3 1 1 4 5 0 +CA[C>A]CG 3 0 3 0 1 0 0 1 1 1 0 0 2 0 1 +CA[C>A]CT 12 1 10 4 1 0 1 10 6 11 2 1 3 2 3 +CA[C>A]GA 2 0 1 0 0 0 0 4 1 0 0 0 3 1 2 +CA[C>A]GC 5 0 1 1 1 0 1 1 0 1 0 1 1 1 0 +CA[C>A]GG 3 0 1 0 3 1 3 2 0 1 1 1 1 0 0 +CA[C>A]GT 6 0 1 2 0 0 2 0 0 1 2 1 0 1 0 +CA[C>A]TA 9 1 5 1 4 1 0 2 1 3 0 1 2 2 3 +CA[C>A]TC 4 2 2 1 4 1 2 3 6 2 0 1 3 3 0 +CA[C>A]TG 15 3 8 9 7 1 7 8 2 4 2 0 9 9 1 +CA[C>A]TT 11 5 5 8 6 2 3 5 6 1 2 0 6 4 3 +CA[C>G]AA 4 0 4 5 2 2 4 8 5 4 3 1 2 2 0 +CA[C>G]AC 2 1 3 2 0 1 3 3 1 1 1 0 1 3 1 +CA[C>G]AG 6 9 8 5 6 4 5 4 5 8 1 3 8 8 2 +CA[C>G]AT 6 4 3 2 2 1 3 6 1 6 1 0 1 3 0 +CA[C>G]CA 8 2 12 4 7 0 2 8 6 7 1 0 3 3 1 +CA[C>G]CC 1 0 3 1 2 0 5 7 3 4 1 1 2 2 3 +CA[C>G]CG 0 1 1 2 1 0 0 1 2 0 0 0 2 0 1 +CA[C>G]CT 3 0 3 7 5 0 3 2 5 5 0 0 0 3 1 +CA[C>G]GA 1 1 1 1 0 0 2 4 1 2 0 0 0 1 1 +CA[C>G]GC 0 2 1 0 2 1 0 1 1 2 0 2 0 0 1 +CA[C>G]GG 0 1 1 0 0 0 0 1 3 1 0 1 0 0 0 +CA[C>G]GT 2 0 0 1 2 0 1 0 3 0 0 0 0 1 1 +CA[C>G]TA 6 0 3 3 5 0 2 5 7 3 1 0 2 1 2 +CA[C>G]TC 5 2 1 2 2 1 3 4 4 4 0 1 3 1 2 +CA[C>G]TG 6 3 4 4 5 3 11 6 6 3 2 1 3 3 4 +CA[C>G]TT 6 7 6 5 7 0 3 7 3 6 2 0 4 6 2 +CA[C>T]AA 10 6 9 5 6 2 9 6 4 7 0 2 3 6 5 +CA[C>T]AC 12 7 4 8 4 3 5 3 6 3 0 0 5 2 5 +CA[C>T]AG 10 5 5 6 4 2 2 6 4 7 1 1 5 2 5 +CA[C>T]AT 14 8 13 10 5 2 7 10 6 5 0 2 11 6 10 +CA[C>T]CA 9 8 9 11 4 3 4 6 5 10 2 3 9 10 8 +CA[C>T]CC 7 2 10 4 12 1 4 10 2 7 1 3 5 5 2 +CA[C>T]CG 0 1 2 0 0 0 1 1 0 2 3 0 2 0 1 +CA[C>T]CT 11 1 5 5 10 1 7 5 8 9 3 2 3 7 7 +CA[C>T]GA 22 8 3 13 8 1 4 8 7 16 0 2 7 3 2 +CA[C>T]GC 28 20 15 17 7 5 10 9 13 14 2 3 15 6 7 +CA[C>T]GG 19 6 6 14 10 2 8 7 4 13 2 0 10 3 10 +CA[C>T]GT 17 8 8 5 8 2 7 10 7 8 1 3 11 5 8 +CA[C>T]TA 4 2 2 6 3 1 2 3 3 7 2 2 5 1 2 +CA[C>T]TC 9 4 7 7 2 1 3 10 2 3 1 1 5 0 3 +CA[C>T]TG 18 7 14 11 6 3 11 10 5 6 1 2 9 5 4 +CA[C>T]TT 12 8 11 7 8 5 3 6 6 3 1 3 3 6 6 +CA[T>A]AA 12 3 8 3 3 0 2 4 3 6 1 1 2 4 3 +CA[T>A]AC 14 0 0 2 4 1 0 2 2 3 0 1 4 0 0 +CA[T>A]AG 17 1 5 0 3 1 0 1 3 2 1 0 3 2 2 +CA[T>A]AT 42 2 4 2 1 0 7 5 3 4 0 0 2 2 0 +CA[T>A]CA 5 1 5 2 2 2 3 1 2 2 0 0 4 2 3 +CA[T>A]CC 4 1 4 2 1 1 3 0 2 1 0 1 1 2 2 +CA[T>A]CG 0 0 1 0 1 0 0 1 0 0 1 0 0 0 2 +CA[T>A]CT 7 4 7 0 1 0 2 4 2 3 1 1 6 6 3 +CA[T>A]GA 4 2 5 2 2 0 4 3 2 5 0 1 1 3 1 +CA[T>A]GC 3 3 5 3 2 2 1 3 0 2 2 0 1 2 0 +CA[T>A]GG 13 1 3 1 1 2 1 3 2 1 2 1 3 1 2 +CA[T>A]GT 23 2 2 4 6 1 8 1 1 4 1 0 2 2 2 +CA[T>A]TA 9 1 10 2 0 2 0 0 3 5 2 1 1 2 2 +CA[T>A]TC 6 2 4 0 3 1 0 1 2 1 0 1 0 0 3 +CA[T>A]TG 6 1 4 4 4 0 3 4 3 1 1 1 2 4 1 +CA[T>A]TT 20 4 6 3 7 0 0 7 4 6 1 1 2 0 8 +CA[T>C]AA 6 6 6 4 7 3 3 4 7 8 1 3 3 7 2 +CA[T>C]AC 12 7 11 9 11 1 1 9 5 8 1 1 6 10 2 +CA[T>C]AG 13 12 18 6 6 1 9 11 4 7 3 4 5 7 4 +CA[T>C]AT 19 4 13 5 3 2 7 6 12 11 1 4 3 8 2 +CA[T>C]CA 7 8 12 11 6 2 7 3 4 6 0 4 5 9 2 +CA[T>C]CC 15 4 14 10 4 2 4 6 6 5 3 2 3 7 1 +CA[T>C]CG 2 0 0 0 0 0 0 2 0 0 0 0 1 0 0 +CA[T>C]CT 21 8 23 14 9 1 10 8 7 11 2 3 8 11 1 +CA[T>C]GA 8 6 9 8 2 1 3 5 8 12 0 0 3 7 4 +CA[T>C]GC 16 6 12 7 2 0 4 3 7 12 3 6 4 9 1 +CA[T>C]GG 15 7 11 5 7 1 8 2 6 7 2 2 7 9 3 +CA[T>C]GT 18 6 17 9 3 3 6 6 5 8 0 5 8 7 5 +CA[T>C]TA 9 5 5 5 4 0 3 5 8 10 1 1 1 6 3 +CA[T>C]TC 17 4 17 12 5 0 3 2 7 3 1 1 5 8 2 +CA[T>C]TG 8 7 13 10 8 2 7 9 6 11 4 0 14 11 4 +CA[T>C]TT 14 6 17 12 12 0 11 11 8 10 3 6 12 11 5 +CA[T>G]AA 3 2 4 1 1 0 0 7 1 3 0 1 3 1 1 +CA[T>G]AC 2 0 1 3 0 0 1 0 2 0 1 0 1 0 1 +CA[T>G]AG 3 0 2 2 4 0 1 4 2 0 0 0 0 0 2 +CA[T>G]AT 5 0 0 2 1 0 0 3 1 0 1 0 2 0 0 +CA[T>G]CA 2 1 3 1 2 1 0 0 2 4 0 1 2 0 1 +CA[T>G]CC 2 0 2 2 1 0 3 4 0 2 0 0 0 0 3 +CA[T>G]CG 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 +CA[T>G]CT 1 1 3 1 4 2 2 3 1 5 0 0 1 3 3 +CA[T>G]GA 6 0 0 0 0 1 3 3 3 2 1 5 2 1 1 +CA[T>G]GC 8 0 0 3 4 1 3 2 0 1 2 0 1 1 1 +CA[T>G]GG 2 0 0 5 0 1 1 2 1 2 0 0 1 3 0 +CA[T>G]GT 7 0 2 2 1 1 4 2 1 2 2 1 2 1 4 +CA[T>G]TA 3 2 0 1 2 5 4 1 2 3 1 1 0 2 0 +CA[T>G]TC 4 1 3 2 4 0 3 4 1 2 0 1 0 1 1 +CA[T>G]TG 2 0 5 2 0 0 2 1 1 4 0 0 0 1 1 +CA[T>G]TT 5 0 6 4 5 2 5 5 3 4 1 2 0 2 2 +CC[C>A]AA 23 8 14 11 4 1 1 8 9 7 1 3 7 12 5 +CC[C>A]AC 24 6 23 11 12 1 4 5 5 2 1 2 1 9 8 +CC[C>A]AG 40 5 14 7 11 4 8 10 8 11 2 2 4 13 0 +CC[C>A]AT 25 12 31 12 7 1 3 11 2 6 3 1 14 23 3 +CC[C>A]CA 28 9 21 14 13 1 6 7 8 5 1 1 4 16 6 +CC[C>A]CC 17 3 9 6 3 1 2 3 6 3 0 1 5 4 0 +CC[C>A]CG 9 0 3 2 1 0 1 1 0 1 1 2 0 0 1 +CC[C>A]CT 22 3 13 10 2 3 5 11 6 5 1 1 6 8 8 +CC[C>A]GA 2 1 2 0 1 0 0 3 1 1 0 1 0 0 1 +CC[C>A]GC 3 0 1 1 0 0 3 3 0 4 0 2 1 0 3 +CC[C>A]GG 5 1 5 2 1 0 1 3 1 2 0 0 1 2 0 +CC[C>A]GT 5 0 1 4 0 1 1 1 3 1 0 0 2 1 1 +CC[C>A]TA 15 2 9 5 2 0 1 7 3 6 1 0 1 3 2 +CC[C>A]TC 13 1 8 0 1 0 5 5 2 4 4 4 5 4 4 +CC[C>A]TG 17 5 7 4 3 0 2 1 6 8 1 1 3 6 8 +CC[C>A]TT 19 5 7 10 2 2 6 9 6 4 1 4 2 8 2 +CC[C>G]AA 5 2 11 4 7 3 3 6 7 5 1 1 2 5 2 +CC[C>G]AC 2 5 2 4 1 1 1 2 1 0 0 2 1 2 2 +CC[C>G]AG 8 2 3 2 2 0 2 8 2 7 0 1 4 2 4 +CC[C>G]AT 3 0 1 2 0 0 5 4 3 0 0 0 1 1 0 +CC[C>G]CA 8 3 5 3 6 1 2 2 7 1 0 0 3 4 4 +CC[C>G]CC 3 3 2 1 3 1 0 2 1 3 1 2 0 3 0 +CC[C>G]CG 1 1 0 0 0 1 2 1 1 0 0 1 1 0 0 +CC[C>G]CT 15 2 6 4 4 2 2 4 4 3 1 2 4 4 1 +CC[C>G]GA 1 0 3 0 1 0 0 3 0 2 0 0 1 0 0 +CC[C>G]GC 2 1 2 0 1 1 2 2 0 0 1 0 0 1 0 +CC[C>G]GG 1 0 0 1 3 0 0 3 0 1 0 1 0 0 3 +CC[C>G]GT 1 0 0 1 0 1 2 1 3 3 0 0 0 1 0 +CC[C>G]TA 4 1 4 5 9 0 1 7 4 1 1 1 5 2 1 +CC[C>G]TC 2 1 5 4 5 1 6 11 1 4 0 1 3 3 2 +CC[C>G]TG 3 0 1 5 4 1 5 4 11 2 2 1 2 4 2 +CC[C>G]TT 5 5 5 5 7 1 8 5 3 5 2 4 4 5 1 +CC[C>T]AA 6 8 11 6 3 2 5 2 4 6 1 2 3 6 4 +CC[C>T]AC 5 2 5 9 5 2 5 8 0 7 5 1 6 2 1 +CC[C>T]AG 19 4 17 17 7 2 2 8 8 13 4 3 12 5 4 +CC[C>T]AT 7 5 9 10 5 0 5 11 5 5 2 2 4 5 2 +CC[C>T]CA 12 5 12 14 10 1 9 5 5 8 0 1 4 7 7 +CC[C>T]CC 6 4 9 8 3 2 2 7 4 7 4 0 2 5 2 +CC[C>T]CG 2 3 0 2 1 0 1 3 2 3 0 1 3 0 0 +CC[C>T]CT 15 1 5 8 4 0 10 10 6 12 0 1 1 4 2 +CC[C>T]GA 8 6 6 9 2 0 5 4 2 7 0 1 2 3 3 +CC[C>T]GC 17 3 10 8 5 2 5 13 4 11 1 1 3 9 6 +CC[C>T]GG 21 7 6 11 3 1 10 7 7 13 1 1 7 2 5 +CC[C>T]GT 14 4 5 3 6 2 3 3 5 4 0 2 3 3 4 +CC[C>T]TA 7 3 8 1 5 0 4 10 0 3 0 0 1 5 3 +CC[C>T]TC 12 4 5 6 1 1 4 6 3 9 1 2 6 3 4 +CC[C>T]TG 6 2 12 15 9 3 3 7 6 3 2 1 4 3 6 +CC[C>T]TT 19 8 13 7 6 1 5 7 9 2 4 1 4 7 3 +CC[T>A]AA 26 2 3 1 5 4 2 2 2 1 3 3 2 3 2 +CC[T>A]AC 15 2 0 2 4 1 1 1 1 3 0 1 0 2 0 +CC[T>A]AG 18 1 1 1 0 2 0 3 1 0 0 0 2 0 1 +CC[T>A]AT 50 0 1 1 4 0 2 3 3 0 0 2 0 0 1 +CC[T>A]CA 24 1 9 5 2 0 2 4 3 4 0 2 3 7 4 +CC[T>A]CC 12 1 6 8 5 3 2 6 6 6 3 1 1 1 3 +CC[T>A]CG 3 0 2 0 0 0 1 1 0 0 1 0 1 0 1 +CC[T>A]CT 15 4 7 2 6 1 0 3 4 5 1 0 3 4 2 +CC[T>A]GA 15 2 4 6 3 0 5 4 2 2 1 0 3 0 3 +CC[T>A]GC 22 5 2 6 6 2 2 5 2 6 0 1 4 5 5 +CC[T>A]GG 22 2 10 7 7 0 3 6 5 10 1 2 5 4 2 +CC[T>A]GT 58 3 3 4 2 0 5 3 8 5 3 0 0 0 2 +CC[T>A]TA 10 4 3 2 2 0 2 2 2 3 0 0 1 1 1 +CC[T>A]TC 3 1 5 1 2 2 1 4 3 3 1 3 0 0 1 +CC[T>A]TG 21 3 3 2 6 1 2 1 4 6 1 0 0 2 6 +CC[T>A]TT 19 6 7 6 7 1 3 10 6 6 0 3 3 3 3 +CC[T>C]AA 6 3 3 1 5 1 2 3 2 5 0 4 0 2 1 +CC[T>C]AC 4 2 7 0 3 1 5 3 1 7 1 1 2 0 1 +CC[T>C]AG 3 1 4 2 4 2 3 5 3 3 1 1 2 0 6 +CC[T>C]AT 5 3 2 1 6 2 0 5 3 6 1 2 1 1 3 +CC[T>C]CA 3 1 5 3 3 2 1 6 4 5 0 2 2 7 0 +CC[T>C]CC 5 2 2 1 3 1 5 2 1 5 0 1 3 3 2 +CC[T>C]CG 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 +CC[T>C]CT 12 2 9 7 6 0 2 4 3 4 1 3 4 4 2 +CC[T>C]GA 7 1 6 2 6 0 3 3 9 4 2 3 2 3 5 +CC[T>C]GC 5 3 3 3 9 3 3 2 6 2 3 0 1 2 6 +CC[T>C]GG 6 2 9 3 5 2 4 4 3 4 1 0 2 4 0 +CC[T>C]GT 4 7 3 3 9 2 1 5 2 2 2 1 2 3 2 +CC[T>C]TA 2 0 1 1 1 2 1 1 3 2 1 0 1 0 2 +CC[T>C]TC 3 0 1 1 5 1 1 1 3 1 1 1 3 4 2 +CC[T>C]TG 6 1 2 3 3 1 2 4 2 4 1 1 1 3 0 +CC[T>C]TT 8 2 5 6 5 1 1 2 4 5 1 3 1 1 3 +CC[T>G]AA 2 1 2 3 3 0 1 2 5 1 0 0 2 1 1 +CC[T>G]AC 1 3 1 0 2 0 1 1 1 0 0 0 1 1 1 +CC[T>G]AG 3 2 1 0 0 0 0 2 1 3 0 2 0 0 0 +CC[T>G]AT 7 0 0 0 0 1 0 2 1 0 0 0 0 0 2 +CC[T>G]CA 3 0 8 2 0 0 1 4 2 5 2 0 1 1 2 +CC[T>G]CC 4 1 1 3 1 0 5 1 1 5 3 1 1 3 0 +CC[T>G]CG 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CC[T>G]CT 4 0 2 2 3 0 1 2 1 3 0 2 1 4 2 +CC[T>G]GA 3 0 1 2 3 0 2 2 3 5 0 0 1 3 3 +CC[T>G]GC 1 0 3 1 0 0 2 1 2 1 0 0 0 0 0 +CC[T>G]GG 0 0 2 0 0 0 0 2 1 0 1 1 1 1 2 +CC[T>G]GT 7 0 3 1 0 0 1 3 1 1 0 1 0 1 1 +CC[T>G]TA 2 1 2 4 0 0 1 1 6 3 1 0 1 1 0 +CC[T>G]TC 0 0 3 1 5 0 1 3 4 2 3 0 1 0 2 +CC[T>G]TG 2 1 1 2 1 0 2 3 1 2 1 0 0 1 1 +CC[T>G]TT 3 1 3 4 4 1 4 3 2 1 1 1 3 4 2 +CG[C>A]AA 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 +CG[C>A]AC 1 0 1 1 0 0 0 0 1 0 0 0 0 1 0 +CG[C>A]AG 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 +CG[C>A]AT 2 0 2 2 1 0 0 0 0 0 0 2 0 0 1 +CG[C>A]CA 0 1 1 0 2 0 1 1 0 3 0 0 0 0 0 +CG[C>A]CC 1 0 1 2 1 0 0 0 3 0 0 0 1 0 1 +CG[C>A]CG 1 0 1 0 1 1 0 1 1 0 0 0 0 0 0 +CG[C>A]CT 2 0 1 1 1 0 1 0 2 0 1 1 0 0 2 +CG[C>A]GA 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[C>A]GC 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 +CG[C>A]GG 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 +CG[C>A]GT 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 +CG[C>A]TA 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 +CG[C>A]TC 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 +CG[C>A]TG 1 0 1 1 1 0 1 0 0 0 1 0 1 0 1 +CG[C>A]TT 2 0 1 2 1 0 1 0 0 1 0 0 0 0 0 +CG[C>G]AA 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 +CG[C>G]AC 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 +CG[C>G]AG 0 0 1 0 0 0 0 0 0 1 0 0 0 2 0 +CG[C>G]AT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[C>G]CA 1 0 0 0 0 0 0 0 0 0 0 0 1 0 2 +CG[C>G]CC 0 0 0 0 1 0 0 2 1 2 0 0 0 0 0 +CG[C>G]CG 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 +CG[C>G]CT 2 0 1 0 0 0 0 0 1 0 0 0 1 0 0 +CG[C>G]GA 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[C>G]GC 0 0 0 0 0 0 1 1 2 0 0 0 1 1 0 +CG[C>G]GG 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 +CG[C>G]GT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[C>G]TA 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +CG[C>G]TC 0 0 1 0 0 0 0 0 0 0 0 0 2 1 0 +CG[C>G]TG 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 +CG[C>G]TT 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 +CG[C>T]AA 0 0 2 1 0 0 0 1 0 0 0 0 1 0 0 +CG[C>T]AC 3 0 1 2 0 1 2 0 0 0 1 0 1 1 0 +CG[C>T]AG 2 0 1 1 1 0 0 0 2 0 0 0 1 1 1 +CG[C>T]AT 4 2 0 1 1 0 1 1 2 1 0 0 1 1 1 +CG[C>T]CA 3 0 0 0 2 0 0 1 0 0 0 0 1 2 0 +CG[C>T]CC 2 2 0 0 5 1 0 1 0 2 1 0 0 3 2 +CG[C>T]CG 0 0 2 2 0 1 0 0 0 0 0 0 1 0 0 +CG[C>T]CT 6 0 0 5 3 0 1 1 0 1 2 0 1 2 1 +CG[C>T]GA 2 2 5 3 2 1 0 1 2 3 1 0 1 2 2 +CG[C>T]GC 9 3 4 3 3 2 1 5 4 3 0 1 5 2 2 +CG[C>T]GG 9 2 5 3 2 2 3 2 3 6 2 0 3 2 2 +CG[C>T]GT 0 3 0 0 4 1 0 1 1 0 0 1 0 1 1 +CG[C>T]TA 1 0 0 2 1 0 0 0 0 1 0 0 0 1 0 +CG[C>T]TC 0 1 1 1 1 0 0 0 0 1 0 1 2 2 0 +CG[C>T]TG 0 3 1 1 1 1 1 2 0 0 1 2 0 2 1 +CG[C>T]TT 1 4 1 3 0 0 0 2 0 1 0 1 2 0 0 +CG[T>A]AA 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 +CG[T>A]AC 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 +CG[T>A]AG 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>A]AT 3 1 1 0 1 0 0 1 0 1 0 0 1 0 0 +CG[T>A]CA 1 0 1 0 2 0 0 0 0 0 0 0 0 0 0 +CG[T>A]CC 0 0 0 2 0 0 0 0 0 0 0 0 0 0 1 +CG[T>A]CG 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 +CG[T>A]CT 1 0 0 0 0 1 2 1 1 0 0 0 0 0 0 +CG[T>A]GA 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 +CG[T>A]GC 2 0 0 0 0 0 0 1 1 1 0 0 1 0 1 +CG[T>A]GG 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 +CG[T>A]GT 0 0 0 0 1 0 0 3 1 0 0 0 0 0 0 +CG[T>A]TA 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>A]TC 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>A]TG 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>A]TT 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>C]AA 4 0 0 2 1 1 0 0 0 0 0 0 0 0 0 +CG[T>C]AC 3 0 0 1 0 0 2 1 0 0 0 0 0 0 1 +CG[T>C]AG 1 0 0 2 0 0 0 0 0 0 0 0 0 0 1 +CG[T>C]AT 1 1 2 0 2 0 1 2 0 0 0 0 1 1 0 +CG[T>C]CA 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 +CG[T>C]CC 1 0 1 0 0 0 0 0 1 2 0 0 0 0 0 +CG[T>C]CG 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>C]CT 2 3 1 2 2 0 3 1 1 0 0 0 3 2 0 +CG[T>C]GA 1 0 2 3 1 0 0 0 1 1 0 0 0 2 0 +CG[T>C]GC 0 0 1 1 0 0 1 0 0 0 0 1 0 2 1 +CG[T>C]GG 2 0 1 0 2 0 2 3 0 1 0 0 0 0 0 +CG[T>C]GT 2 0 0 0 0 1 0 0 1 1 0 0 1 0 0 +CG[T>C]TA 1 0 1 0 0 0 0 0 2 0 0 0 0 1 0 +CG[T>C]TC 0 1 2 0 0 0 1 0 0 0 0 0 1 1 0 +CG[T>C]TG 3 2 1 0 1 0 0 0 2 0 0 2 0 1 0 +CG[T>C]TT 2 0 0 0 1 0 0 1 0 0 0 0 0 2 0 +CG[T>G]AA 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]AC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]AG 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]AT 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 +CG[T>G]CA 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]CC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]CG 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]CT 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 +CG[T>G]GA 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 +CG[T>G]GC 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]GG 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]GT 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 +CG[T>G]TA 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]TC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +CG[T>G]TG 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 +CG[T>G]TT 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +CT[C>A]AA 21 6 15 9 9 0 2 8 8 6 4 1 2 7 5 +CT[C>A]AC 13 6 8 9 4 0 2 11 10 8 3 0 2 6 4 +CT[C>A]AG 18 5 11 10 9 2 3 10 3 9 3 3 2 3 5 +CT[C>A]AT 19 7 17 7 5 2 0 14 10 8 0 4 5 7 6 +CT[C>A]CA 20 7 9 5 7 4 7 9 7 7 2 3 6 9 6 +CT[C>A]CC 16 7 13 7 6 0 3 12 3 9 3 3 7 5 4 +CT[C>A]CG 1 1 2 1 1 0 0 2 0 2 1 0 0 1 0 +CT[C>A]CT 24 8 14 5 16 2 12 14 9 9 1 3 3 7 7 +CT[C>A]GA 1 1 0 1 2 0 0 0 0 2 0 1 2 2 0 +CT[C>A]GC 1 0 1 0 2 1 0 0 0 0 0 0 1 1 0 +CT[C>A]GG 4 1 5 0 1 0 1 3 2 2 1 0 0 0 0 +CT[C>A]GT 2 3 1 0 0 0 1 1 1 2 1 1 0 0 2 +CT[C>A]TA 7 3 8 4 6 0 3 10 9 4 2 2 5 4 3 +CT[C>A]TC 12 1 7 3 7 1 3 5 8 6 0 0 4 3 3 +CT[C>A]TG 15 3 7 7 12 0 1 7 6 6 0 1 3 2 6 +CT[C>A]TT 18 3 13 4 6 1 5 6 7 5 5 2 5 4 3 +CT[C>G]AA 11 4 10 1 8 1 3 18 11 5 1 1 6 2 3 +CT[C>G]AC 4 1 2 3 2 0 0 4 1 3 3 0 0 2 3 +CT[C>G]AG 7 3 5 6 6 0 3 3 4 2 1 1 4 2 0 +CT[C>G]AT 10 1 3 1 6 1 3 6 0 6 1 1 1 1 1 +CT[C>G]CA 12 5 8 3 9 2 3 13 6 8 3 1 2 7 3 +CT[C>G]CC 8 4 3 4 8 1 3 10 4 0 0 3 4 3 3 +CT[C>G]CG 1 0 1 2 0 0 0 1 0 2 0 0 0 1 0 +CT[C>G]CT 13 3 12 2 14 3 2 9 9 5 3 3 4 5 2 +CT[C>G]GA 2 0 0 1 0 0 0 0 1 0 0 0 0 0 1 +CT[C>G]GC 0 0 1 0 0 0 0 3 0 0 0 0 0 1 0 +CT[C>G]GG 1 1 0 1 0 0 0 2 0 0 0 0 0 1 0 +CT[C>G]GT 1 0 1 1 1 0 0 2 0 0 0 0 1 0 0 +CT[C>G]TA 13 3 7 1 5 1 5 16 11 11 2 3 3 4 1 +CT[C>G]TC 6 5 7 4 9 2 4 9 5 11 1 3 6 6 3 +CT[C>G]TG 7 4 8 5 10 0 9 11 5 7 1 2 4 3 3 +CT[C>G]TT 8 4 12 4 15 4 3 22 10 7 3 6 5 6 5 +CT[C>T]AA 14 5 13 7 7 1 7 6 3 8 6 0 4 7 3 +CT[C>T]AC 17 3 13 3 6 1 1 11 4 6 0 0 4 8 2 +CT[C>T]AG 18 4 12 10 7 3 6 16 7 7 2 2 5 7 7 +CT[C>T]AT 15 3 8 8 12 4 1 15 3 7 2 0 6 4 9 +CT[C>T]CA 11 2 10 9 3 2 2 7 3 9 3 3 5 6 3 +CT[C>T]CC 13 11 9 14 9 1 3 12 9 10 2 1 5 11 3 +CT[C>T]CG 1 3 0 0 0 0 0 1 3 1 0 0 0 1 2 +CT[C>T]CT 20 9 18 15 15 1 5 16 11 10 5 2 14 19 9 +CT[C>T]GA 10 1 3 4 1 2 2 2 2 2 0 2 3 0 3 +CT[C>T]GC 5 2 1 2 1 0 1 2 2 6 1 1 1 4 3 +CT[C>T]GG 12 8 7 4 5 2 9 2 7 6 1 2 5 4 3 +CT[C>T]GT 4 2 6 7 4 1 3 6 1 3 0 2 4 0 0 +CT[C>T]TA 11 3 5 8 8 0 2 3 3 7 2 1 1 5 2 +CT[C>T]TC 13 5 6 3 1 1 4 7 4 11 2 1 9 1 3 +CT[C>T]TG 13 5 6 7 7 1 5 6 4 4 2 2 3 4 6 +CT[C>T]TT 9 3 8 6 7 3 4 7 4 7 0 0 4 2 6 +CT[T>A]AA 28 2 1 3 1 1 4 1 2 6 0 0 2 1 2 +CT[T>A]AC 12 2 5 0 2 1 0 4 2 1 1 2 1 2 3 +CT[T>A]AG 29 0 3 0 3 0 0 1 0 3 1 0 0 1 1 +CT[T>A]AT 54 1 5 3 1 2 2 3 2 3 0 0 2 1 3 +CT[T>A]CA 9 3 7 5 1 2 3 5 4 2 0 2 2 7 2 +CT[T>A]CC 6 2 7 6 4 0 5 5 4 4 1 0 2 1 1 +CT[T>A]CG 0 0 0 0 0 0 0 1 2 0 0 0 1 0 0 +CT[T>A]CT 17 3 9 6 6 1 8 4 2 1 3 1 1 2 6 +CT[T>A]GA 10 2 5 0 3 1 0 3 1 4 1 0 0 2 0 +CT[T>A]GC 8 1 3 0 0 2 0 2 3 3 0 2 0 0 0 +CT[T>A]GG 14 0 4 1 3 1 0 3 2 2 0 1 1 2 1 +CT[T>A]GT 22 0 2 4 3 1 1 0 2 0 0 1 1 2 1 +CT[T>A]TA 8 1 5 2 1 6 2 1 4 5 2 0 3 1 0 +CT[T>A]TC 7 1 10 1 2 0 4 2 0 3 2 4 0 1 1 +CT[T>A]TG 24 2 2 1 8 0 0 3 3 1 0 1 2 2 2 +CT[T>A]TT 20 2 5 3 3 1 0 3 6 5 2 1 2 2 0 +CT[T>C]AA 6 3 7 1 4 0 2 2 6 3 2 3 1 2 0 +CT[T>C]AC 5 2 4 2 1 1 6 4 1 4 1 3 2 0 1 +CT[T>C]AG 3 0 4 3 4 0 3 1 3 2 1 2 1 2 0 +CT[T>C]AT 12 2 8 6 5 0 4 5 3 2 0 0 6 6 3 +CT[T>C]CA 6 2 2 4 4 1 1 2 3 1 0 1 3 2 0 +CT[T>C]CC 5 3 6 3 7 1 4 6 0 5 0 3 2 8 0 +CT[T>C]CG 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 +CT[T>C]CT 8 3 11 5 5 0 7 5 2 5 2 1 1 7 3 +CT[T>C]GA 1 1 3 1 3 0 4 4 2 2 0 0 0 1 0 +CT[T>C]GC 3 1 4 2 2 0 5 2 4 1 2 0 0 4 0 +CT[T>C]GG 2 1 4 1 4 0 0 2 3 2 1 0 0 3 0 +CT[T>C]GT 4 0 1 1 0 0 1 5 0 4 0 0 1 1 2 +CT[T>C]TA 5 2 2 2 3 1 1 3 1 6 4 0 1 0 1 +CT[T>C]TC 9 3 7 5 9 1 1 5 2 2 0 1 1 6 3 +CT[T>C]TG 5 3 5 5 2 0 7 8 8 7 3 2 1 3 3 +CT[T>C]TT 9 3 6 6 4 2 5 11 0 13 0 1 7 3 3 +CT[T>G]AA 6 1 6 2 2 0 3 8 3 3 2 0 3 4 1 +CT[T>G]AC 2 2 1 1 3 1 0 1 1 0 0 0 3 1 2 +CT[T>G]AG 4 1 0 1 0 0 0 4 3 1 0 0 2 0 0 +CT[T>G]AT 1 0 1 0 3 0 1 1 1 0 0 0 0 0 0 +CT[T>G]CA 3 0 3 2 3 0 4 1 5 3 2 1 0 3 1 +CT[T>G]CC 0 0 3 0 6 0 4 9 4 3 0 1 2 2 1 +CT[T>G]CG 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 +CT[T>G]CT 3 3 5 2 4 1 4 2 3 3 1 4 4 1 3 +CT[T>G]GA 5 1 4 0 3 0 3 2 1 4 0 0 0 2 1 +CT[T>G]GC 1 2 0 0 1 1 2 7 0 3 2 3 1 0 1 +CT[T>G]GG 3 0 3 1 2 0 2 3 6 4 1 0 0 1 2 +CT[T>G]GT 5 0 1 2 3 1 3 4 0 0 1 1 1 3 1 +CT[T>G]TA 5 0 5 1 5 1 3 7 5 8 0 1 4 2 5 +CT[T>G]TC 5 5 7 3 2 1 5 4 2 0 4 0 3 1 3 +CT[T>G]TG 3 1 3 1 3 3 5 4 4 5 2 3 1 0 0 +CT[T>G]TT 8 4 6 3 10 4 13 15 2 12 3 1 5 5 2 +GA[C>A]AA 26 10 15 10 9 0 3 13 7 8 3 2 4 7 5 +GA[C>A]AC 9 6 9 7 6 0 3 5 1 3 1 1 2 9 2 +GA[C>A]AG 13 3 5 1 8 0 2 7 4 2 1 3 2 4 2 +GA[C>A]AT 12 5 23 6 4 1 3 3 6 5 0 2 6 19 5 +GA[C>A]CA 10 4 3 7 5 0 6 1 5 5 0 1 1 8 2 +GA[C>A]CC 1 1 5 3 3 0 1 4 3 1 1 0 4 3 1 +GA[C>A]CG 3 0 0 1 0 0 1 0 0 0 0 0 0 0 0 +GA[C>A]CT 9 4 8 7 4 1 2 1 2 4 1 1 3 4 0 +GA[C>A]GA 0 0 0 3 0 0 0 0 0 0 0 0 1 0 0 +GA[C>A]GC 1 2 1 1 1 0 0 0 1 2 1 0 2 0 0 +GA[C>A]GG 2 0 5 0 1 0 1 3 1 0 0 2 0 0 2 +GA[C>A]GT 3 1 0 0 1 0 0 0 1 0 0 0 0 0 0 +GA[C>A]TA 8 2 4 2 3 0 1 0 2 4 0 0 2 2 7 +GA[C>A]TC 5 1 5 3 0 0 1 5 1 4 0 0 1 0 1 +GA[C>A]TG 6 2 2 5 2 3 3 5 6 2 1 2 2 3 4 +GA[C>A]TT 8 5 6 6 4 1 3 7 5 3 1 2 2 3 1 +GA[C>G]AA 3 4 4 3 3 1 3 4 2 5 0 0 3 3 0 +GA[C>G]AC 5 1 4 1 1 1 1 2 2 1 0 0 1 1 1 +GA[C>G]AG 5 4 6 6 4 1 2 5 4 8 4 0 6 7 7 +GA[C>G]AT 1 0 2 1 0 0 1 1 0 3 1 0 3 1 1 +GA[C>G]CA 7 2 3 1 2 0 5 3 1 4 1 1 2 2 4 +GA[C>G]CC 1 0 3 2 2 0 3 3 0 2 1 1 1 0 1 +GA[C>G]CG 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 +GA[C>G]CT 5 2 6 4 0 1 2 6 1 5 0 2 1 1 2 +GA[C>G]GA 0 0 0 1 1 0 1 2 0 0 0 1 1 0 2 +GA[C>G]GC 1 2 2 0 1 0 1 0 0 0 1 0 0 0 0 +GA[C>G]GG 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 +GA[C>G]GT 0 0 1 0 2 0 0 0 0 1 1 0 0 0 0 +GA[C>G]TA 1 0 4 1 1 2 2 5 5 3 0 0 0 0 1 +GA[C>G]TC 0 0 3 1 2 0 0 5 3 1 0 0 0 0 1 +GA[C>G]TG 6 2 1 1 3 1 2 1 1 2 3 2 2 0 1 +GA[C>G]TT 2 1 1 3 3 0 4 2 3 6 2 1 0 7 1 +GA[C>T]AA 6 4 3 5 5 1 6 7 2 6 0 3 4 5 6 +GA[C>T]AC 3 3 5 2 7 2 2 2 3 3 1 1 0 0 1 +GA[C>T]AG 10 6 5 5 5 2 1 7 1 2 2 0 5 3 2 +GA[C>T]AT 8 6 10 10 6 5 8 11 4 3 2 1 13 4 3 +GA[C>T]CA 10 4 5 5 2 0 1 6 5 4 1 0 2 1 1 +GA[C>T]CC 7 2 2 0 1 0 2 3 0 3 0 2 0 3 2 +GA[C>T]CG 4 1 0 0 1 0 1 1 0 0 0 0 0 0 1 +GA[C>T]CT 8 6 3 3 4 0 4 3 2 5 1 2 2 6 4 +GA[C>T]GA 18 5 5 8 7 1 6 8 3 9 1 2 10 7 0 +GA[C>T]GC 18 8 10 1 4 2 6 3 6 15 0 0 6 7 4 +GA[C>T]GG 25 7 7 14 10 8 17 8 9 9 1 2 7 5 2 +GA[C>T]GT 18 9 10 8 3 2 4 3 4 12 0 2 11 1 3 +GA[C>T]TA 8 2 5 6 1 1 2 3 0 1 0 0 2 6 2 +GA[C>T]TC 0 2 3 2 5 1 3 3 2 2 0 0 3 1 2 +GA[C>T]TG 14 2 6 2 1 2 1 5 1 1 1 0 1 2 3 +GA[C>T]TT 6 5 1 5 8 1 6 3 1 4 0 1 3 4 5 +GA[T>A]AA 16 4 4 3 5 2 1 3 3 3 1 3 4 3 2 +GA[T>A]AC 3 1 2 1 2 0 0 4 3 4 1 1 0 1 0 +GA[T>A]AG 23 2 3 4 3 2 1 3 1 5 0 2 1 2 0 +GA[T>A]AT 16 0 2 1 1 2 3 2 4 2 0 0 1 1 1 +GA[T>A]CA 7 2 8 3 3 0 2 2 3 2 0 1 2 1 1 +GA[T>A]CC 2 1 2 3 1 0 0 2 0 2 0 0 2 0 0 +GA[T>A]CG 1 0 1 0 0 0 1 0 2 1 0 0 0 1 0 +GA[T>A]CT 10 0 5 3 3 0 1 4 0 5 0 0 4 1 1 +GA[T>A]GA 5 3 3 2 6 1 3 3 3 4 1 2 3 3 4 +GA[T>A]GC 2 0 5 0 2 0 2 0 1 2 1 0 1 1 1 +GA[T>A]GG 9 0 4 3 1 3 0 4 0 2 1 1 3 0 1 +GA[T>A]GT 12 2 2 1 2 1 0 2 3 1 1 1 1 2 1 +GA[T>A]TA 5 3 5 5 1 0 1 4 1 3 0 0 1 4 2 +GA[T>A]TC 3 0 1 2 5 0 1 5 4 2 2 2 2 1 2 +GA[T>A]TG 5 1 5 1 2 0 3 0 3 3 2 2 1 1 1 +GA[T>A]TT 3 1 3 1 2 0 3 0 4 4 1 1 4 3 3 +GA[T>C]AA 12 2 10 5 9 2 9 4 7 5 2 3 6 11 2 +GA[T>C]AC 16 4 7 8 5 1 2 7 7 5 1 1 5 3 7 +GA[T>C]AG 14 4 10 6 5 1 4 9 11 5 0 2 3 7 4 +GA[T>C]AT 18 3 9 4 5 0 8 6 2 6 1 2 7 12 2 +GA[T>C]CA 12 6 23 8 6 1 6 3 2 2 0 2 7 8 1 +GA[T>C]CC 2 4 6 3 6 0 3 3 2 6 2 1 1 5 2 +GA[T>C]CG 0 0 1 0 1 0 0 0 0 1 0 0 0 1 0 +GA[T>C]CT 9 4 9 8 1 1 5 3 4 2 2 1 4 11 2 +GA[T>C]GA 13 3 11 4 5 2 5 5 6 6 1 0 1 6 3 +GA[T>C]GC 8 3 8 4 4 3 4 2 1 4 0 0 4 3 0 +GA[T>C]GG 11 6 18 7 3 1 5 6 2 5 5 1 9 7 4 +GA[T>C]GT 4 9 6 5 6 2 2 4 2 5 0 1 3 7 2 +GA[T>C]TA 4 3 9 2 1 0 2 1 4 3 0 0 1 5 0 +GA[T>C]TC 10 2 6 2 1 1 1 1 0 3 0 1 0 4 1 +GA[T>C]TG 7 11 10 5 7 2 4 7 5 8 0 1 10 11 3 +GA[T>C]TT 10 6 10 9 3 1 6 8 6 8 1 2 2 6 4 +GA[T>G]AA 1 2 2 0 0 0 0 4 0 2 1 1 3 1 0 +GA[T>G]AC 3 0 1 0 0 0 0 1 0 2 0 0 0 1 0 +GA[T>G]AG 4 0 1 2 2 0 4 1 1 1 1 0 1 2 0 +GA[T>G]AT 2 0 0 0 1 0 1 1 0 1 0 1 1 1 0 +GA[T>G]CA 1 0 0 1 0 1 2 1 1 3 1 0 1 2 0 +GA[T>G]CC 1 0 1 0 2 0 1 1 1 1 0 0 0 0 2 +GA[T>G]CG 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 +GA[T>G]CT 0 1 0 0 4 1 3 1 1 3 0 0 3 2 1 +GA[T>G]GA 2 0 3 2 0 0 5 4 3 0 1 1 1 1 1 +GA[T>G]GC 3 0 2 0 1 2 0 1 0 0 0 2 0 1 1 +GA[T>G]GG 2 0 3 2 3 1 1 2 0 0 0 0 1 1 0 +GA[T>G]GT 3 0 3 3 0 0 1 1 3 0 0 0 0 0 1 +GA[T>G]TA 2 0 2 2 3 1 0 0 2 0 2 1 0 2 0 +GA[T>G]TC 2 0 1 2 1 0 1 1 1 0 0 0 0 0 1 +GA[T>G]TG 2 0 2 2 3 1 0 3 0 1 1 1 1 1 0 +GA[T>G]TT 4 0 1 1 4 0 2 7 4 6 1 0 1 0 1 +GC[C>A]AA 16 4 8 6 2 0 6 6 4 8 2 1 2 8 5 +GC[C>A]AC 11 5 10 4 1 0 2 6 4 7 0 1 5 8 2 +GC[C>A]AG 7 1 11 8 2 0 1 2 4 2 4 2 5 5 1 +GC[C>A]AT 19 6 22 6 3 1 7 9 8 4 1 2 7 8 3 +GC[C>A]CA 14 5 15 2 2 3 2 9 4 3 1 0 1 10 1 +GC[C>A]CC 9 4 4 8 3 0 5 5 4 6 2 2 3 5 2 +GC[C>A]CG 2 1 3 2 1 0 0 3 1 1 1 0 0 1 0 +GC[C>A]CT 11 5 13 5 11 2 7 3 5 5 2 2 5 6 3 +GC[C>A]GA 4 0 2 2 0 1 3 0 2 0 0 0 1 0 0 +GC[C>A]GC 0 0 1 2 1 0 0 1 0 1 0 1 1 0 1 +GC[C>A]GG 4 0 0 1 1 0 0 0 2 1 1 0 1 1 2 +GC[C>A]GT 1 0 0 1 0 0 0 1 1 0 0 0 0 1 1 +GC[C>A]TA 3 0 4 4 0 0 2 3 3 3 1 0 0 1 0 +GC[C>A]TC 10 0 6 4 9 1 3 10 5 3 3 2 6 2 2 +GC[C>A]TG 12 5 4 6 5 0 6 4 6 5 3 3 5 8 6 +GC[C>A]TT 12 2 6 7 2 1 5 2 4 4 0 3 4 5 2 +GC[C>G]AA 5 2 3 0 1 0 2 3 0 3 0 0 0 3 1 +GC[C>G]AC 2 0 0 0 0 1 0 1 2 1 0 0 0 0 0 +GC[C>G]AG 8 1 4 2 2 0 3 2 3 1 1 2 1 4 1 +GC[C>G]AT 2 3 1 3 1 1 0 2 5 2 0 1 0 2 1 +GC[C>G]CA 3 3 4 4 2 1 3 4 1 2 0 0 1 0 2 +GC[C>G]CC 2 0 1 4 1 0 0 4 1 3 0 0 2 0 4 +GC[C>G]CG 0 0 1 0 3 1 1 2 1 0 0 0 0 0 1 +GC[C>G]CT 3 2 5 2 7 2 4 5 1 5 1 1 2 2 0 +GC[C>G]GA 1 0 0 0 0 2 0 1 0 2 0 1 0 0 1 +GC[C>G]GC 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 +GC[C>G]GG 1 0 1 0 0 1 1 0 1 0 0 0 1 0 1 +GC[C>G]GT 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 +GC[C>G]TA 1 2 2 3 3 0 3 4 3 4 1 0 0 1 0 +GC[C>G]TC 4 3 5 0 4 0 3 6 1 5 2 1 1 2 4 +GC[C>G]TG 1 3 1 1 3 1 3 4 1 4 1 1 2 2 2 +GC[C>G]TT 4 5 0 2 2 1 5 4 1 7 3 0 1 4 1 +GC[C>T]AA 9 10 10 5 5 1 1 2 3 2 0 1 5 6 0 +GC[C>T]AC 5 0 7 5 2 0 4 5 3 4 4 0 5 3 4 +GC[C>T]AG 5 6 6 7 2 3 0 3 3 5 0 2 6 4 2 +GC[C>T]AT 11 5 5 5 8 0 7 3 6 3 0 1 3 4 4 +GC[C>T]CA 7 4 7 7 7 1 4 11 5 9 3 2 8 6 6 +GC[C>T]CC 3 7 3 11 8 1 5 9 3 3 1 1 4 4 2 +GC[C>T]CG 1 1 2 3 1 1 0 1 1 1 0 0 1 1 1 +GC[C>T]CT 10 8 4 5 12 3 7 7 5 7 1 2 6 11 1 +GC[C>T]GA 11 5 3 6 5 2 2 3 4 8 3 0 1 3 3 +GC[C>T]GC 4 2 6 3 4 3 2 1 3 8 2 0 1 0 2 +GC[C>T]GG 16 6 6 2 9 1 7 6 9 9 0 1 4 3 1 +GC[C>T]GT 11 3 3 3 2 3 2 4 4 1 0 0 0 1 0 +GC[C>T]TA 4 2 6 4 4 0 2 6 2 5 0 2 2 7 3 +GC[C>T]TC 11 6 5 8 6 2 6 4 7 8 0 1 6 9 4 +GC[C>T]TG 11 2 6 6 3 2 4 10 6 8 3 2 5 7 4 +GC[C>T]TT 14 2 8 7 3 1 1 1 3 9 1 3 1 2 6 +GC[T>A]AA 34 2 5 2 4 0 3 5 4 3 1 1 1 1 0 +GC[T>A]AC 10 2 2 0 3 0 4 1 2 2 0 1 2 2 2 +GC[T>A]AG 29 1 2 1 3 0 2 0 0 3 2 0 1 0 0 +GC[T>A]AT 37 2 2 6 1 2 1 1 2 2 0 3 1 1 1 +GC[T>A]CA 6 2 3 1 4 1 1 3 2 5 1 1 0 3 2 +GC[T>A]CC 8 2 0 1 1 1 1 2 1 4 0 0 1 1 1 +GC[T>A]CG 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 +GC[T>A]CT 14 1 8 6 3 2 4 5 5 4 1 3 2 0 2 +GC[T>A]GA 21 2 4 1 5 3 4 2 1 3 1 0 2 0 1 +GC[T>A]GC 8 0 3 3 1 2 1 3 0 0 1 0 1 1 3 +GC[T>A]GG 15 3 5 3 3 0 3 4 1 2 2 1 3 0 1 +GC[T>A]GT 30 1 4 4 5 4 2 5 3 4 1 2 2 0 1 +GC[T>A]TA 7 1 6 1 4 2 0 3 3 3 1 0 0 0 3 +GC[T>A]TC 2 2 5 2 3 0 0 0 0 2 0 1 2 1 1 +GC[T>A]TG 10 1 1 3 3 0 0 1 2 1 0 0 3 2 1 +GC[T>A]TT 2 1 4 6 3 0 3 6 2 5 2 0 2 3 1 +GC[T>C]AA 3 1 0 5 2 2 4 5 3 1 3 1 1 5 1 +GC[T>C]AC 3 3 2 4 3 0 5 2 2 1 2 1 3 1 3 +GC[T>C]AG 8 0 5 1 1 0 3 5 2 2 0 2 3 0 0 +GC[T>C]AT 4 3 5 2 3 3 1 8 4 3 1 2 1 3 2 +GC[T>C]CA 4 1 4 4 3 0 2 3 1 3 2 0 0 2 1 +GC[T>C]CC 5 1 2 3 3 1 1 4 2 2 0 0 1 5 1 +GC[T>C]CG 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 +GC[T>C]CT 2 2 6 3 1 0 4 3 0 0 1 0 2 5 5 +GC[T>C]GA 5 2 6 2 3 2 4 3 4 3 2 2 2 2 1 +GC[T>C]GC 4 3 2 7 2 1 2 3 2 1 0 0 0 2 2 +GC[T>C]GG 2 4 6 3 4 0 2 1 6 5 1 1 1 3 1 +GC[T>C]GT 4 1 1 7 2 3 3 2 3 3 1 1 1 4 2 +GC[T>C]TA 4 1 2 6 1 0 2 2 2 6 0 0 5 1 0 +GC[T>C]TC 6 2 4 3 1 2 4 4 5 4 0 2 3 1 2 +GC[T>C]TG 3 0 1 4 4 1 1 3 4 2 1 0 3 3 2 +GC[T>C]TT 4 5 1 5 4 2 6 5 4 4 1 1 3 4 2 +GC[T>G]AA 1 2 3 2 0 0 0 2 2 0 0 0 0 0 1 +GC[T>G]AC 1 0 2 0 0 0 2 0 0 0 0 0 0 0 0 +GC[T>G]AG 3 1 1 0 0 0 2 1 0 1 0 0 2 0 0 +GC[T>G]AT 2 1 1 0 1 1 1 1 0 2 0 0 0 0 0 +GC[T>G]CA 2 1 3 0 0 0 2 1 1 0 0 0 1 0 1 +GC[T>G]CC 2 1 2 2 1 0 2 1 0 1 0 0 2 1 0 +GC[T>G]CG 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 +GC[T>G]CT 4 1 2 0 0 1 0 0 1 1 0 0 1 0 0 +GC[T>G]GA 2 2 2 1 0 0 1 3 0 2 1 2 0 1 1 +GC[T>G]GC 2 0 0 1 0 0 0 1 0 0 0 0 0 0 0 +GC[T>G]GG 3 1 1 1 3 0 2 5 3 3 0 0 1 0 0 +GC[T>G]GT 1 1 2 1 2 1 2 2 1 0 0 0 1 0 1 +GC[T>G]TA 1 0 1 0 1 0 3 3 0 2 0 0 0 2 1 +GC[T>G]TC 2 3 1 1 3 0 0 6 3 1 1 1 1 1 0 +GC[T>G]TG 4 1 2 1 2 0 0 1 2 1 1 0 0 0 0 +GC[T>G]TT 2 1 3 0 4 1 1 6 2 1 0 0 0 1 1 +GG[C>A]AA 15 4 9 8 6 5 5 2 8 6 0 1 8 7 0 +GG[C>A]AC 9 2 9 4 2 0 1 0 3 2 1 0 3 4 2 +GG[C>A]AG 12 4 3 4 3 1 3 8 9 3 2 4 8 5 7 +GG[C>A]AT 12 8 18 5 12 0 8 4 6 3 2 2 5 9 2 +GG[C>A]CA 11 2 10 5 4 1 8 6 3 7 1 2 4 6 3 +GG[C>A]CC 6 1 2 7 1 1 4 3 5 3 1 2 3 2 3 +GG[C>A]CG 4 0 1 0 0 0 0 0 1 0 0 0 2 1 1 +GG[C>A]CT 9 1 8 7 8 0 6 1 3 4 2 2 2 11 4 +GG[C>A]GA 1 2 2 2 0 0 2 0 0 0 0 0 0 1 0 +GG[C>A]GC 3 1 1 4 0 1 1 0 2 3 0 0 0 1 2 +GG[C>A]GG 8 2 4 0 2 0 2 1 3 0 0 0 0 2 1 +GG[C>A]GT 2 1 2 1 3 1 0 0 0 1 0 0 3 0 0 +GG[C>A]TA 12 1 4 4 4 0 1 3 0 0 0 3 2 3 0 +GG[C>A]TC 8 2 5 4 3 0 3 3 3 2 0 2 0 1 2 +GG[C>A]TG 15 3 6 7 3 0 0 5 3 4 1 1 2 7 2 +GG[C>A]TT 15 3 5 4 4 2 5 1 5 4 0 1 5 4 1 +GG[C>G]AA 5 3 3 1 2 0 2 1 1 4 0 0 0 1 1 +GG[C>G]AC 2 0 0 1 2 0 2 0 1 2 0 2 0 1 0 +GG[C>G]AG 1 0 7 0 4 1 3 2 1 1 1 1 1 2 3 +GG[C>G]AT 0 0 2 0 1 0 0 0 1 2 1 0 0 1 0 +GG[C>G]CA 7 1 5 2 1 1 0 4 3 4 0 1 1 0 0 +GG[C>G]CC 4 1 0 0 0 0 0 4 1 0 1 4 1 2 0 +GG[C>G]CG 0 0 0 1 1 0 2 0 0 0 0 0 0 0 2 +GG[C>G]CT 4 0 5 0 1 0 3 2 1 1 1 0 2 0 0 +GG[C>G]GA 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 +GG[C>G]GC 0 0 2 0 0 0 1 0 0 0 2 0 0 1 0 +GG[C>G]GG 0 0 1 0 2 0 2 0 0 0 1 0 0 0 0 +GG[C>G]GT 1 0 1 0 0 0 1 0 1 0 0 0 0 0 1 +GG[C>G]TA 2 1 2 2 3 0 1 2 4 3 0 0 1 1 0 +GG[C>G]TC 1 0 3 0 1 1 2 3 0 3 0 0 1 0 1 +GG[C>G]TG 2 0 1 2 6 1 0 3 1 0 0 0 1 1 2 +GG[C>G]TT 1 3 2 1 5 1 2 2 1 0 1 0 0 2 0 +GG[C>T]AA 10 9 9 11 7 2 6 9 5 6 4 1 5 6 4 +GG[C>T]AC 9 6 6 4 2 0 2 8 11 13 1 1 3 0 4 +GG[C>T]AG 15 8 6 11 4 6 3 12 7 8 2 2 8 8 6 +GG[C>T]AT 12 5 10 10 9 1 5 11 3 9 1 0 4 9 2 +GG[C>T]CA 15 9 5 10 6 2 8 7 7 7 2 1 7 7 1 +GG[C>T]CC 6 4 5 3 5 6 1 3 1 7 2 3 5 2 4 +GG[C>T]CG 0 0 2 5 1 0 4 0 0 1 1 1 1 1 1 +GG[C>T]CT 8 5 9 13 5 4 8 10 4 5 2 0 9 9 10 +GG[C>T]GA 20 5 4 4 10 0 4 2 6 7 2 0 7 5 4 +GG[C>T]GC 20 7 6 8 7 3 9 8 4 11 2 1 9 7 5 +GG[C>T]GG 38 6 15 16 11 2 12 11 10 14 2 4 9 7 5 +GG[C>T]GT 14 7 8 9 6 2 6 7 4 7 1 0 9 2 5 +GG[C>T]TA 11 5 3 6 3 2 4 3 1 4 2 1 2 4 1 +GG[C>T]TC 7 2 3 7 6 1 1 8 5 7 0 0 4 5 7 +GG[C>T]TG 10 7 8 13 5 2 8 11 9 8 3 3 6 5 6 +GG[C>T]TT 14 2 6 3 3 1 6 5 3 3 0 3 3 5 3 +GG[T>A]AA 5 1 1 1 0 0 1 2 2 3 0 0 0 0 3 +GG[T>A]AC 2 1 1 1 1 0 1 1 0 1 0 1 1 0 0 +GG[T>A]AG 7 0 0 0 2 2 0 2 3 0 0 0 1 0 1 +GG[T>A]AT 5 1 1 3 1 0 2 1 3 4 0 0 0 1 1 +GG[T>A]CA 8 1 7 3 3 0 0 3 0 1 0 0 2 3 0 +GG[T>A]CC 4 1 0 2 0 0 0 2 2 0 0 2 1 0 0 +GG[T>A]CG 0 1 1 0 0 0 0 0 0 1 0 0 0 1 0 +GG[T>A]CT 6 1 1 1 1 1 2 1 1 1 0 1 2 7 0 +GG[T>A]GA 5 2 2 1 2 1 1 5 1 0 0 0 0 0 0 +GG[T>A]GC 3 1 3 0 1 0 3 5 0 1 0 1 1 0 2 +GG[T>A]GG 6 2 1 2 4 0 3 4 0 2 0 0 0 0 0 +GG[T>A]GT 4 0 1 0 0 0 0 2 0 1 0 0 0 0 0 +GG[T>A]TA 5 1 0 1 2 0 0 3 2 5 1 1 0 4 1 +GG[T>A]TC 1 0 0 0 2 0 1 1 0 5 0 0 0 0 0 +GG[T>A]TG 5 1 1 0 1 1 1 2 0 1 0 2 1 1 3 +GG[T>A]TT 5 0 1 1 1 1 2 2 6 1 0 0 1 3 2 +GG[T>C]AA 3 2 5 5 1 0 2 5 1 3 0 1 2 7 0 +GG[T>C]AC 3 3 1 6 1 0 0 4 5 1 0 1 1 2 0 +GG[T>C]AG 2 4 4 3 3 2 4 4 3 3 0 2 1 5 2 +GG[T>C]AT 3 4 3 5 3 1 1 4 3 1 1 0 6 2 0 +GG[T>C]CA 4 4 2 7 4 1 2 1 2 3 2 2 0 2 1 +GG[T>C]CC 4 4 6 1 1 0 1 5 1 2 0 0 1 0 0 +GG[T>C]CG 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 +GG[T>C]CT 1 4 5 4 3 0 6 3 3 3 1 1 6 5 1 +GG[T>C]GA 5 2 10 0 0 1 3 4 2 5 1 1 3 0 0 +GG[T>C]GC 1 1 2 1 2 0 0 1 4 2 0 0 1 3 3 +GG[T>C]GG 1 1 4 4 1 2 3 3 3 6 0 2 2 0 0 +GG[T>C]GT 5 1 3 2 3 1 1 1 4 3 0 0 1 2 1 +GG[T>C]TA 2 0 4 2 2 0 2 1 0 1 2 1 1 0 0 +GG[T>C]TC 4 2 1 3 3 0 4 2 0 4 2 1 2 3 1 +GG[T>C]TG 4 3 2 5 1 1 2 2 4 3 3 3 2 5 4 +GG[T>C]TT 7 3 5 6 2 1 3 2 1 3 0 1 5 4 2 +GG[T>G]AA 0 0 1 0 1 0 0 2 0 2 0 0 0 0 0 +GG[T>G]AC 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 +GG[T>G]AG 2 0 0 0 0 0 0 1 0 0 0 0 0 0 1 +GG[T>G]AT 0 0 0 1 0 0 1 1 0 0 0 0 1 0 0 +GG[T>G]CA 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 +GG[T>G]CC 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +GG[T>G]CG 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 +GG[T>G]CT 0 2 1 0 0 0 0 1 0 1 0 0 0 1 0 +GG[T>G]GA 0 0 1 0 3 0 0 0 1 1 0 0 1 0 1 +GG[T>G]GC 2 0 0 1 0 2 1 0 0 2 1 0 1 1 0 +GG[T>G]GG 2 0 0 0 0 0 0 0 0 0 0 0 2 1 0 +GG[T>G]GT 0 0 1 0 1 0 0 2 0 1 0 0 0 0 0 +GG[T>G]TA 1 0 1 0 1 0 0 0 0 0 1 1 0 1 0 +GG[T>G]TC 0 1 1 0 3 0 0 0 0 2 0 0 0 1 0 +GG[T>G]TG 2 1 1 0 1 0 0 1 0 0 0 1 0 0 0 +GG[T>G]TT 1 0 2 1 1 1 0 1 2 1 1 0 0 2 0 +GT[C>A]AA 9 3 11 10 3 0 4 10 6 5 2 3 3 6 3 +GT[C>A]AC 7 3 6 4 5 0 2 4 2 5 3 1 2 4 3 +GT[C>A]AG 4 3 6 1 3 2 0 2 3 3 0 0 0 2 3 +GT[C>A]AT 9 2 6 8 5 0 5 10 7 7 1 1 4 2 2 +GT[C>A]CA 11 4 3 6 4 1 5 6 5 6 3 3 5 4 4 +GT[C>A]CC 8 2 8 5 5 0 4 4 1 6 2 2 2 6 3 +GT[C>A]CG 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 +GT[C>A]CT 11 2 8 3 3 2 4 5 2 8 2 2 5 4 4 +GT[C>A]GA 0 0 1 0 0 1 0 0 0 0 0 0 2 0 0 +GT[C>A]GC 0 1 2 0 0 0 0 1 1 0 0 0 1 0 0 +GT[C>A]GG 1 0 0 1 1 0 0 1 1 2 0 0 0 1 0 +GT[C>A]GT 0 0 0 1 0 0 0 0 2 0 0 0 0 0 0 +GT[C>A]TA 8 1 4 5 2 1 3 4 3 4 0 1 1 1 1 +GT[C>A]TC 4 2 6 2 11 0 1 6 4 5 0 1 1 2 3 +GT[C>A]TG 8 4 8 6 2 0 3 5 5 4 2 0 2 5 3 +GT[C>A]TT 11 2 10 8 4 1 3 5 7 7 0 4 3 6 3 +GT[C>G]AA 9 3 7 1 4 0 0 8 2 5 2 0 2 4 0 +GT[C>G]AC 5 0 4 0 1 0 0 3 1 1 0 0 1 2 0 +GT[C>G]AG 3 3 6 6 8 2 4 6 4 4 0 2 5 5 0 +GT[C>G]AT 8 1 3 0 4 1 2 6 0 1 0 0 0 0 0 +GT[C>G]CA 5 2 4 0 4 1 2 1 2 4 1 1 1 1 2 +GT[C>G]CC 3 5 6 3 7 0 5 2 2 4 2 0 0 0 0 +GT[C>G]CG 0 1 3 0 1 0 0 1 0 0 0 0 0 1 0 +GT[C>G]CT 5 3 2 1 5 2 4 3 5 5 1 0 1 3 0 +GT[C>G]GA 0 1 1 0 3 0 1 1 0 0 1 0 1 0 0 +GT[C>G]GC 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 +GT[C>G]GG 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +GT[C>G]GT 2 1 0 0 0 1 0 0 0 2 0 0 0 1 0 +GT[C>G]TA 2 2 2 4 6 0 3 10 3 4 0 0 4 3 4 +GT[C>G]TC 6 5 5 3 9 1 0 8 7 7 2 2 2 3 4 +GT[C>G]TG 6 1 6 3 4 1 3 6 2 4 1 0 2 1 0 +GT[C>G]TT 0 1 8 6 12 0 5 18 3 9 2 2 2 4 0 +GT[C>T]AA 13 4 14 10 8 1 5 8 4 4 0 3 5 3 2 +GT[C>T]AC 6 2 3 5 4 1 3 6 2 4 1 0 2 2 6 +GT[C>T]AG 10 5 3 7 6 1 5 10 2 4 2 1 1 3 2 +GT[C>T]AT 20 6 15 11 10 1 4 10 3 7 2 3 2 6 8 +GT[C>T]CA 5 6 7 3 8 0 3 9 3 7 3 0 3 2 4 +GT[C>T]CC 4 5 7 4 4 1 4 10 5 5 2 0 6 5 2 +GT[C>T]CG 0 0 0 0 1 0 1 2 1 0 0 0 1 1 0 +GT[C>T]CT 12 2 9 6 9 1 4 11 5 3 2 2 7 4 6 +GT[C>T]GA 7 3 1 1 2 1 0 1 2 3 0 0 1 1 0 +GT[C>T]GC 4 1 2 1 1 0 0 3 2 3 1 1 1 0 2 +GT[C>T]GG 5 1 0 3 2 2 1 1 0 1 0 0 1 1 1 +GT[C>T]GT 6 1 4 3 1 1 1 2 1 1 1 0 1 0 4 +GT[C>T]TA 4 3 4 1 3 2 1 1 5 2 0 0 0 3 0 +GT[C>T]TC 10 6 8 6 7 3 3 5 0 6 2 0 4 2 3 +GT[C>T]TG 8 2 5 8 2 2 1 7 4 3 1 2 0 2 2 +GT[C>T]TT 4 3 14 7 8 2 4 6 7 6 0 1 3 6 1 +GT[T>A]AA 24 2 0 4 3 1 1 3 3 2 0 0 2 2 0 +GT[T>A]AC 4 0 2 2 2 0 1 0 0 1 0 0 1 0 2 +GT[T>A]AG 24 1 0 0 1 0 1 5 0 2 1 1 0 0 0 +GT[T>A]AT 21 0 3 1 2 1 4 2 1 0 1 2 1 2 4 +GT[T>A]CA 14 4 6 1 7 0 2 2 3 4 0 3 1 5 3 +GT[T>A]CC 6 3 5 4 4 0 1 2 3 0 0 1 1 1 0 +GT[T>A]CG 3 0 1 1 0 0 0 1 0 0 0 0 1 0 0 +GT[T>A]CT 6 1 9 2 5 0 8 5 1 0 1 1 2 4 2 +GT[T>A]GA 4 1 2 2 2 1 1 1 2 1 2 0 2 0 0 +GT[T>A]GC 4 1 5 2 2 1 1 0 3 1 0 1 0 4 1 +GT[T>A]GG 7 1 2 2 1 0 4 3 1 2 0 2 1 3 0 +GT[T>A]GT 12 1 5 3 4 1 1 0 2 1 0 0 2 1 1 +GT[T>A]TA 5 1 1 4 2 1 0 2 2 1 1 1 0 2 0 +GT[T>A]TC 6 0 6 2 4 0 3 2 3 4 0 0 1 2 1 +GT[T>A]TG 9 0 3 2 1 0 0 6 1 2 0 0 2 1 0 +GT[T>A]TT 10 7 6 3 3 2 7 3 3 2 2 1 2 1 2 +GT[T>C]AA 4 2 6 3 3 1 3 2 5 0 0 0 1 7 0 +GT[T>C]AC 6 5 8 3 3 0 1 0 3 2 0 1 0 2 0 +GT[T>C]AG 7 1 3 0 9 0 1 2 3 2 0 0 1 1 0 +GT[T>C]AT 6 1 3 1 3 0 2 1 4 3 0 1 3 1 0 +GT[T>C]CA 1 1 4 2 5 0 0 5 1 4 0 0 0 3 0 +GT[T>C]CC 1 0 5 1 1 1 3 2 3 0 1 1 2 0 0 +GT[T>C]CG 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 +GT[T>C]CT 3 2 2 1 5 0 0 2 1 1 0 0 1 3 1 +GT[T>C]GA 0 0 1 0 1 0 0 2 1 0 0 0 1 0 0 +GT[T>C]GC 3 2 3 0 0 0 0 0 1 3 0 1 1 1 2 +GT[T>C]GG 2 2 1 1 1 0 1 0 0 3 0 1 2 1 0 +GT[T>C]GT 1 0 1 1 3 0 3 5 0 0 1 2 1 3 1 +GT[T>C]TA 4 1 6 1 4 0 0 2 0 2 0 0 1 1 1 +GT[T>C]TC 6 3 8 1 3 0 3 0 2 3 0 3 1 5 2 +GT[T>C]TG 5 1 1 3 5 1 0 2 1 1 2 2 0 0 1 +GT[T>C]TT 5 1 4 2 1 0 2 0 1 1 0 4 2 4 4 +GT[T>G]AA 4 0 0 1 3 0 1 1 0 5 0 0 2 1 1 +GT[T>G]AC 1 0 0 0 2 0 2 1 3 1 0 0 0 0 0 +GT[T>G]AG 4 0 1 1 1 2 1 0 0 0 0 0 0 0 0 +GT[T>G]AT 4 0 1 0 1 0 0 0 0 0 0 0 0 1 0 +GT[T>G]CA 3 0 1 2 1 1 1 3 1 2 0 1 3 0 1 +GT[T>G]CC 0 1 2 1 2 0 2 1 2 0 2 0 1 0 0 +GT[T>G]CG 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +GT[T>G]CT 0 1 1 1 3 0 3 0 1 1 1 0 1 4 2 +GT[T>G]GA 4 2 2 3 2 1 0 2 0 3 0 0 1 0 0 +GT[T>G]GC 1 1 3 2 0 0 0 2 2 3 1 0 0 2 0 +GT[T>G]GG 0 2 0 1 0 0 2 3 0 2 1 0 0 0 0 +GT[T>G]GT 3 1 3 0 1 0 2 2 1 1 0 0 1 1 1 +GT[T>G]TA 4 3 7 2 2 0 1 5 2 6 0 0 2 1 0 +GT[T>G]TC 0 4 4 2 3 1 5 3 0 8 0 1 2 3 2 +GT[T>G]TG 3 0 3 3 2 1 5 2 4 2 1 0 3 0 1 +GT[T>G]TT 8 2 5 5 7 1 3 11 3 5 1 1 4 2 3 +TA[C>A]AA 25 9 29 24 14 3 17 11 11 11 4 5 6 14 9 +TA[C>A]AC 10 0 8 8 6 1 3 7 3 4 3 0 2 4 6 +TA[C>A]AG 18 1 15 9 4 1 2 6 4 6 2 3 3 7 4 +TA[C>A]AT 21 7 32 20 8 0 10 8 8 10 1 4 10 17 5 +TA[C>A]CA 11 1 6 5 4 0 4 1 5 3 0 2 3 3 2 +TA[C>A]CC 0 1 4 4 2 0 0 2 3 5 0 0 3 1 2 +TA[C>A]CG 2 0 0 0 1 0 0 0 1 0 0 0 1 0 1 +TA[C>A]CT 5 1 11 4 4 0 6 5 6 4 2 0 5 2 4 +TA[C>A]GA 1 0 1 1 1 0 0 2 0 1 0 1 1 4 0 +TA[C>A]GC 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 +TA[C>A]GG 2 2 2 0 1 0 0 4 1 1 1 0 0 1 0 +TA[C>A]GT 3 1 1 0 1 0 0 1 1 1 0 0 0 3 1 +TA[C>A]TA 12 2 4 3 2 1 0 3 2 6 0 1 7 1 3 +TA[C>A]TC 5 3 2 0 1 0 1 3 3 1 0 0 0 2 0 +TA[C>A]TG 13 3 4 3 5 2 3 4 3 7 1 1 2 4 5 +TA[C>A]TT 14 4 11 3 9 2 3 4 8 4 3 0 7 5 5 +TA[C>G]AA 8 2 4 3 1 0 2 7 8 6 1 1 0 2 0 +TA[C>G]AC 3 1 2 1 0 1 2 3 0 3 0 0 0 1 0 +TA[C>G]AG 12 5 7 7 5 3 2 5 2 5 2 3 5 3 5 +TA[C>G]AT 8 0 2 2 2 1 1 3 3 3 1 1 5 3 0 +TA[C>G]CA 5 0 2 1 1 2 2 7 6 7 0 0 2 4 1 +TA[C>G]CC 3 0 1 1 1 0 1 3 4 4 0 0 1 4 0 +TA[C>G]CG 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 +TA[C>G]CT 5 1 2 2 0 0 0 3 1 3 1 1 2 1 3 +TA[C>G]GA 3 0 1 1 0 0 0 1 0 0 0 0 0 0 0 +TA[C>G]GC 1 0 0 0 1 0 2 2 0 0 0 0 0 0 1 +TA[C>G]GG 0 0 1 0 1 0 0 2 0 0 0 0 0 0 0 +TA[C>G]GT 2 1 1 0 1 0 1 0 0 0 0 1 1 1 0 +TA[C>G]TA 10 4 10 2 3 1 5 8 3 7 1 3 1 2 0 +TA[C>G]TC 6 1 3 2 2 0 2 8 3 2 1 0 2 3 3 +TA[C>G]TG 5 3 4 1 3 0 3 8 2 3 2 2 3 5 5 +TA[C>G]TT 9 5 5 7 3 1 8 7 5 4 0 3 7 0 3 +TA[C>T]AA 9 6 8 9 5 1 8 6 6 7 0 2 5 6 5 +TA[C>T]AC 6 1 3 5 4 3 0 3 5 2 0 3 7 1 1 +TA[C>T]AG 11 4 13 5 8 6 3 12 4 12 3 3 0 5 3 +TA[C>T]AT 21 11 14 16 13 4 10 17 4 10 3 2 9 10 5 +TA[C>T]CA 9 3 5 5 9 1 5 5 2 12 1 2 4 9 3 +TA[C>T]CC 5 3 5 4 6 0 3 2 2 4 3 0 5 3 1 +TA[C>T]CG 1 0 2 1 0 0 0 0 1 1 0 1 0 1 0 +TA[C>T]CT 6 6 4 1 6 2 4 4 5 5 1 1 4 6 3 +TA[C>T]GA 11 6 3 3 6 1 4 6 9 10 1 0 9 3 2 +TA[C>T]GC 8 5 6 5 3 1 5 5 3 8 0 0 3 7 1 +TA[C>T]GG 16 4 6 5 5 1 7 4 7 4 1 1 5 4 0 +TA[C>T]GT 23 11 6 10 5 7 9 8 4 8 2 4 9 6 2 +TA[C>T]TA 8 4 9 4 9 2 3 5 4 5 2 1 4 5 6 +TA[C>T]TC 4 5 7 4 7 1 5 5 8 6 0 0 3 3 3 +TA[C>T]TG 6 7 4 7 10 4 9 11 5 7 0 2 8 9 3 +TA[C>T]TT 14 12 11 9 10 3 11 8 7 10 4 4 11 8 9 +TA[T>A]AA 43 3 5 6 4 3 5 6 6 7 2 2 6 2 2 +TA[T>A]AC 8 1 2 3 4 1 4 2 1 5 0 0 0 3 1 +TA[T>A]AG 28 0 3 3 4 0 3 1 1 5 1 2 1 0 1 +TA[T>A]AT 81 3 4 1 5 1 6 7 3 5 0 3 4 3 2 +TA[T>A]CA 20 1 3 4 2 0 1 1 3 1 0 1 0 0 1 +TA[T>A]CC 4 0 5 1 0 0 1 1 0 2 1 1 1 2 1 +TA[T>A]CG 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 +TA[T>A]CT 7 2 4 5 3 1 4 4 0 3 1 3 1 1 0 +TA[T>A]GA 10 3 5 3 2 0 2 1 0 6 1 1 6 1 2 +TA[T>A]GC 9 2 4 3 2 2 3 0 1 0 0 1 2 1 1 +TA[T>A]GG 25 0 2 1 3 0 3 4 2 3 1 3 1 0 0 +TA[T>A]GT 30 6 7 5 2 0 1 3 1 5 4 0 2 2 0 +TA[T>A]TA 13 1 4 4 8 1 2 4 1 5 0 1 1 4 1 +TA[T>A]TC 6 0 4 5 5 2 3 1 4 3 0 0 2 2 1 +TA[T>A]TG 23 1 5 1 3 4 4 2 5 2 1 0 1 1 1 +TA[T>A]TT 17 5 9 7 8 3 2 9 2 9 1 5 3 4 5 +TA[T>C]AA 25 7 27 11 11 2 10 14 8 9 5 4 14 11 9 +TA[T>C]AC 32 12 16 15 12 1 7 7 12 10 3 2 14 8 5 +TA[T>C]AG 26 10 16 14 5 0 7 9 7 9 1 3 9 12 5 +TA[T>C]AT 60 21 33 33 25 3 7 22 14 19 4 4 14 25 7 +TA[T>C]CA 13 10 19 9 4 1 7 7 2 9 2 3 5 8 4 +TA[T>C]CC 4 2 11 5 3 2 6 3 4 4 2 0 4 4 3 +TA[T>C]CG 0 0 1 0 0 0 0 1 0 2 0 0 0 0 0 +TA[T>C]CT 10 8 18 11 7 1 8 3 3 5 4 3 8 10 2 +TA[T>C]GA 15 1 19 12 6 4 6 4 4 10 3 4 5 12 4 +TA[T>C]GC 8 6 11 7 6 3 2 5 8 6 1 3 7 6 7 +TA[T>C]GG 10 8 15 5 10 1 2 5 6 2 6 0 7 6 0 +TA[T>C]GT 27 10 24 12 14 3 10 9 3 6 1 5 5 11 7 +TA[T>C]TA 22 7 12 10 12 3 4 13 10 10 1 3 6 5 4 +TA[T>C]TC 23 4 14 9 10 1 3 12 4 14 1 2 8 13 4 +TA[T>C]TG 14 8 10 12 14 1 9 5 10 10 3 0 6 9 2 +TA[T>C]TT 18 13 14 21 19 4 11 14 14 19 4 0 7 26 9 +TA[T>G]AA 9 3 5 3 3 0 3 4 5 4 0 0 4 0 3 +TA[T>G]AC 2 3 0 1 3 1 1 1 0 0 1 0 1 0 0 +TA[T>G]AG 7 0 0 1 1 0 2 2 2 2 0 0 1 3 3 +TA[T>G]AT 15 2 2 0 4 2 3 6 0 5 0 1 1 0 1 +TA[T>G]CA 6 1 4 2 3 1 1 3 1 3 0 0 0 0 0 +TA[T>G]CC 1 0 2 1 2 0 0 0 0 0 0 0 2 0 0 +TA[T>G]CG 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 +TA[T>G]CT 3 1 4 3 1 2 0 1 2 0 0 0 0 0 1 +TA[T>G]GA 1 1 2 0 4 1 2 3 0 4 1 0 2 1 2 +TA[T>G]GC 5 2 1 0 1 0 2 4 0 1 1 2 1 0 1 +TA[T>G]GG 1 0 1 0 1 1 0 2 1 0 0 1 0 0 0 +TA[T>G]GT 3 2 2 1 3 0 4 2 2 0 1 1 1 0 1 +TA[T>G]TA 3 3 5 5 8 0 1 9 4 8 1 1 5 1 1 +TA[T>G]TC 0 0 3 2 1 1 2 2 1 5 0 0 2 0 1 +TA[T>G]TG 1 2 1 2 1 0 1 0 2 4 0 0 0 1 2 +TA[T>G]TT 10 0 9 5 8 0 5 9 3 8 2 1 3 4 3 +TC[C>A]AA 16 4 17 9 10 2 1 5 7 7 0 1 3 7 3 +TC[C>A]AC 19 4 10 6 3 0 2 6 3 8 2 0 1 7 1 +TC[C>A]AG 12 3 3 9 6 0 4 9 6 2 1 0 4 3 5 +TC[C>A]AT 35 14 27 12 11 0 6 8 4 4 1 1 13 20 1 +TC[C>A]CA 16 2 21 7 8 0 3 10 10 3 2 0 7 4 5 +TC[C>A]CC 14 6 12 10 7 4 3 9 3 2 0 1 4 9 3 +TC[C>A]CG 4 1 0 0 2 0 0 0 0 2 0 0 0 1 0 +TC[C>A]CT 23 14 19 11 11 3 2 9 4 4 4 4 5 6 7 +TC[C>A]GA 1 0 1 2 0 0 0 2 0 0 0 0 1 1 0 +TC[C>A]GC 0 0 0 0 0 0 0 0 1 3 0 0 0 1 1 +TC[C>A]GG 1 2 1 0 0 0 1 1 0 0 0 0 0 0 0 +TC[C>A]GT 2 0 0 1 2 0 1 1 1 1 0 0 2 0 1 +TC[C>A]TA 14 3 5 2 1 1 1 2 2 3 0 1 1 4 2 +TC[C>A]TC 15 0 16 7 3 1 7 4 5 4 1 2 7 5 3 +TC[C>A]TG 14 3 11 4 11 1 5 9 12 7 0 1 1 5 2 +TC[C>A]TT 28 10 16 9 9 3 5 11 5 7 4 1 7 12 7 +TC[C>G]AA 7 5 7 3 4 0 3 2 2 2 0 1 1 3 4 +TC[C>G]AC 3 2 2 3 2 0 0 1 0 1 0 0 0 3 1 +TC[C>G]AG 5 1 4 4 0 2 1 2 1 1 1 1 2 3 0 +TC[C>G]AT 1 0 2 3 2 0 0 3 1 1 0 3 4 0 1 +TC[C>G]CA 13 2 3 2 4 1 3 8 1 8 0 1 2 2 4 +TC[C>G]CC 4 1 7 2 2 0 0 2 2 3 4 1 1 2 1 +TC[C>G]CG 2 0 1 0 0 0 1 0 0 0 0 0 0 0 0 +TC[C>G]CT 4 1 4 4 0 1 1 6 2 5 1 1 3 5 3 +TC[C>G]GA 2 0 0 0 1 1 1 0 0 0 0 0 0 0 0 +TC[C>G]GC 1 0 1 0 1 0 0 1 0 1 0 0 1 0 0 +TC[C>G]GG 0 0 0 2 0 0 0 0 0 0 0 0 0 0 1 +TC[C>G]GT 0 0 1 1 2 0 0 2 2 1 0 0 0 0 0 +TC[C>G]TA 6 3 7 1 3 0 2 6 4 5 2 1 3 0 1 +TC[C>G]TC 1 2 4 3 10 3 6 6 4 3 1 1 3 4 2 +TC[C>G]TG 5 1 9 3 3 1 2 6 0 4 1 1 2 1 2 +TC[C>G]TT 4 2 5 4 6 2 3 13 6 5 0 0 7 4 2 +TC[C>T]AA 8 5 8 12 9 0 5 9 4 8 1 0 6 7 4 +TC[C>T]AC 11 3 7 11 6 2 2 7 4 7 0 1 3 4 3 +TC[C>T]AG 8 6 7 4 5 3 5 6 2 8 1 3 5 6 6 +TC[C>T]AT 18 8 13 8 10 2 3 5 9 9 1 1 3 12 6 +TC[C>T]CA 10 7 11 8 5 0 7 11 8 11 5 3 7 7 5 +TC[C>T]CC 14 7 4 4 11 4 6 8 6 4 1 1 12 10 6 +TC[C>T]CG 1 2 1 2 1 0 0 0 0 0 0 0 0 1 0 +TC[C>T]CT 18 13 12 15 7 3 11 12 5 18 1 1 4 5 11 +TC[C>T]GA 3 5 1 11 6 0 0 4 3 7 2 2 5 3 4 +TC[C>T]GC 18 9 4 6 6 1 3 8 2 6 1 0 7 7 4 +TC[C>T]GG 11 3 8 4 4 1 4 4 5 7 0 2 4 3 1 +TC[C>T]GT 14 5 3 6 6 3 5 5 10 8 1 1 4 2 4 +TC[C>T]TA 11 5 11 11 5 0 3 9 5 6 2 1 8 5 1 +TC[C>T]TC 11 7 3 5 7 1 4 8 5 13 2 0 3 8 3 +TC[C>T]TG 15 8 15 7 13 2 6 24 11 10 1 1 6 7 6 +TC[C>T]TT 10 6 12 8 11 2 9 7 8 9 4 4 6 11 2 +TC[T>A]AA 38 4 2 1 2 3 2 4 5 10 3 5 2 0 2 +TC[T>A]AC 12 1 2 3 2 1 5 8 4 1 1 0 2 0 0 +TC[T>A]AG 40 1 3 1 2 0 4 2 2 5 0 2 3 1 1 +TC[T>A]AT 80 0 4 3 5 3 2 6 3 4 2 4 0 3 1 +TC[T>A]CA 17 2 3 7 8 0 2 3 5 2 1 0 1 7 1 +TC[T>A]CC 8 4 4 6 8 2 3 6 6 6 1 1 2 8 2 +TC[T>A]CG 0 0 1 0 0 0 1 2 0 1 0 0 0 0 0 +TC[T>A]CT 22 4 9 5 6 1 1 9 6 1 1 3 2 7 0 +TC[T>A]GA 35 1 6 1 4 1 3 6 8 3 1 1 3 5 3 +TC[T>A]GC 8 0 9 5 1 1 5 3 0 6 1 1 1 1 1 +TC[T>A]GG 17 1 5 3 3 1 3 0 4 4 0 3 3 1 0 +TC[T>A]GT 60 1 6 6 4 3 5 7 4 6 1 0 2 6 3 +TC[T>A]TA 21 2 6 1 4 0 1 5 3 7 1 0 2 3 1 +TC[T>A]TC 7 2 9 2 3 1 4 2 2 3 0 2 1 0 4 +TC[T>A]TG 22 2 5 2 5 1 4 5 4 5 1 1 1 2 3 +TC[T>A]TT 17 5 12 10 10 2 4 11 4 12 3 4 2 2 1 +TC[T>C]AA 11 7 6 4 3 2 1 6 2 3 2 4 2 9 3 +TC[T>C]AC 14 5 17 1 5 2 7 8 5 4 2 2 5 7 4 +TC[T>C]AG 8 3 6 5 6 2 2 13 10 6 2 2 2 3 3 +TC[T>C]AT 17 2 19 16 12 0 6 6 5 10 4 1 4 7 5 +TC[T>C]CA 11 11 17 14 5 1 1 3 4 9 2 2 3 8 2 +TC[T>C]CC 11 4 8 10 7 3 4 4 3 4 3 1 4 5 0 +TC[T>C]CG 2 1 0 0 0 0 0 1 0 4 0 0 2 1 0 +TC[T>C]CT 21 12 28 17 19 2 11 12 7 7 3 5 10 23 8 +TC[T>C]GA 11 2 8 6 8 0 3 5 1 5 1 0 5 8 2 +TC[T>C]GC 10 0 6 4 0 2 3 6 6 6 1 0 3 9 2 +TC[T>C]GG 7 1 4 5 1 2 1 4 4 6 1 1 2 2 1 +TC[T>C]GT 16 5 7 9 6 2 4 13 8 5 4 1 4 4 0 +TC[T>C]TA 10 6 5 4 1 2 5 8 1 7 2 0 5 5 1 +TC[T>C]TC 11 5 16 13 6 1 6 8 4 4 0 1 0 10 4 +TC[T>C]TG 7 5 15 7 4 0 4 5 6 6 1 4 2 7 3 +TC[T>C]TT 21 9 33 26 17 4 9 15 13 16 1 4 7 14 5 +TC[T>G]AA 4 0 0 0 1 1 1 3 1 3 0 1 0 1 0 +TC[T>G]AC 3 0 1 2 0 0 0 0 0 0 0 0 1 0 0 +TC[T>G]AG 4 2 1 1 2 0 0 0 1 1 0 0 0 0 0 +TC[T>G]AT 5 0 3 2 0 2 2 1 0 2 1 0 2 0 0 +TC[T>G]CA 2 0 1 6 2 0 3 6 3 6 1 1 3 2 0 +TC[T>G]CC 3 0 1 1 4 0 1 4 1 1 0 0 0 1 1 +TC[T>G]CG 0 0 0 0 1 0 0 2 0 0 0 1 1 0 0 +TC[T>G]CT 7 2 3 0 5 0 1 3 0 4 0 1 2 1 3 +TC[T>G]GA 1 1 1 4 2 0 4 2 2 3 0 0 1 2 1 +TC[T>G]GC 1 2 0 0 2 1 1 3 1 0 1 1 2 0 1 +TC[T>G]GG 3 1 3 1 1 0 1 1 1 2 0 0 0 2 0 +TC[T>G]GT 10 1 3 1 1 0 2 1 1 2 2 1 3 0 1 +TC[T>G]TA 5 5 5 3 4 1 2 7 5 3 1 0 0 1 1 +TC[T>G]TC 5 3 1 2 2 0 0 8 1 5 3 0 0 0 2 +TC[T>G]TG 4 1 8 2 0 1 3 0 2 4 0 1 1 2 0 +TC[T>G]TT 5 6 7 2 7 1 4 7 7 14 1 2 3 4 3 +TG[C>A]AA 17 5 13 7 5 0 5 6 9 9 3 4 7 10 4 +TG[C>A]AC 8 4 9 6 4 1 3 1 4 2 0 0 3 2 4 +TG[C>A]AG 12 6 7 7 5 3 0 4 6 4 0 2 5 10 4 +TG[C>A]AT 29 11 20 7 11 0 5 7 10 10 1 4 4 13 7 +TG[C>A]CA 13 5 7 6 5 2 5 3 7 1 0 3 2 5 4 +TG[C>A]CC 4 4 8 3 4 1 2 4 3 3 0 0 2 4 3 +TG[C>A]CG 3 0 2 0 2 0 1 0 0 0 0 0 0 1 0 +TG[C>A]CT 15 7 17 9 2 3 3 8 9 2 0 4 5 5 2 +TG[C>A]GA 1 0 0 1 0 0 1 0 0 1 0 0 0 2 0 +TG[C>A]GC 1 2 0 2 0 0 0 0 0 1 0 1 2 1 0 +TG[C>A]GG 4 1 0 2 0 1 0 0 0 0 0 0 2 1 2 +TG[C>A]GT 1 0 1 0 0 0 0 2 0 0 0 0 0 1 2 +TG[C>A]TA 8 0 2 4 1 0 2 0 4 4 1 0 2 3 3 +TG[C>A]TC 3 4 5 4 2 0 4 6 3 1 1 1 0 5 5 +TG[C>A]TG 13 2 4 5 5 1 5 10 8 3 0 0 6 3 3 +TG[C>A]TT 9 7 11 11 5 2 5 8 9 7 1 4 2 3 3 +TG[C>G]AA 2 2 2 2 3 1 2 5 0 4 2 0 2 2 1 +TG[C>G]AC 1 0 1 1 0 1 2 0 1 2 0 0 0 1 0 +TG[C>G]AG 3 0 1 4 1 1 0 2 1 3 1 2 1 3 4 +TG[C>G]AT 3 1 4 3 1 0 1 2 1 2 0 1 2 0 1 +TG[C>G]CA 5 0 4 1 4 2 0 2 1 3 1 0 4 1 2 +TG[C>G]CC 3 1 1 2 1 0 2 4 0 2 1 1 2 0 0 +TG[C>G]CG 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 +TG[C>G]CT 6 0 3 2 6 2 2 5 0 4 2 1 4 3 2 +TG[C>G]GA 3 0 1 0 0 0 0 0 1 0 0 0 0 0 1 +TG[C>G]GC 0 0 2 0 0 0 1 0 0 0 0 0 1 1 0 +TG[C>G]GG 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 +TG[C>G]GT 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 +TG[C>G]TA 4 2 2 1 4 1 3 3 1 1 0 0 0 1 2 +TG[C>G]TC 6 1 4 0 2 0 0 1 3 2 2 0 1 0 0 +TG[C>G]TG 6 2 2 2 2 0 1 6 4 4 1 0 1 2 0 +TG[C>G]TT 2 1 7 1 2 1 2 4 3 3 1 0 2 4 4 +TG[C>T]AA 11 7 16 6 9 0 2 12 7 13 2 3 7 8 7 +TG[C>T]AC 9 4 2 8 6 3 4 4 11 6 0 0 5 6 2 +TG[C>T]AG 11 2 14 13 10 3 4 12 9 13 2 2 8 7 8 +TG[C>T]AT 7 11 11 11 4 1 5 9 4 9 2 1 9 12 5 +TG[C>T]CA 10 6 9 11 6 4 11 3 7 4 0 4 9 7 2 +TG[C>T]CC 13 2 10 7 4 0 6 9 12 9 1 1 5 7 6 +TG[C>T]CG 1 2 1 2 3 0 1 0 1 2 0 0 2 0 1 +TG[C>T]CT 9 9 19 18 18 3 3 14 11 14 2 2 7 12 8 +TG[C>T]GA 14 3 5 3 4 1 7 3 3 10 1 2 2 1 1 +TG[C>T]GC 5 1 6 8 2 0 5 3 5 6 0 1 4 2 3 +TG[C>T]GG 15 4 2 4 5 3 3 4 4 3 2 3 8 2 3 +TG[C>T]GT 9 3 8 4 2 2 6 5 4 11 0 1 5 2 1 +TG[C>T]TA 7 6 7 11 3 2 1 3 8 3 0 1 2 8 6 +TG[C>T]TC 10 7 5 4 5 3 9 9 11 7 1 2 7 5 2 +TG[C>T]TG 9 3 13 10 11 2 14 6 8 9 3 2 3 10 5 +TG[C>T]TT 14 7 9 9 3 2 8 8 7 6 3 2 6 12 7 +TG[T>A]AA 29 3 2 1 4 2 4 1 3 4 0 1 1 0 1 +TG[T>A]AC 13 0 2 0 0 0 3 5 3 1 0 0 0 1 0 +TG[T>A]AG 25 0 1 2 0 0 0 3 2 1 0 0 3 1 2 +TG[T>A]AT 36 0 3 1 6 0 2 1 3 4 0 0 1 1 1 +TG[T>A]CA 12 2 10 2 3 2 4 7 2 4 0 1 2 0 1 +TG[T>A]CC 6 0 1 2 3 2 0 3 4 2 3 3 1 1 1 +TG[T>A]CG 1 0 0 0 0 1 0 2 0 0 0 0 0 0 0 +TG[T>A]CT 7 2 4 7 4 1 4 3 5 4 2 3 2 3 1 +TG[T>A]GA 7 0 7 2 5 2 1 3 1 3 0 0 2 5 3 +TG[T>A]GC 5 1 6 1 0 0 1 3 1 4 0 1 2 3 2 +TG[T>A]GG 3 2 4 1 3 0 2 3 4 3 0 2 0 1 0 +TG[T>A]GT 18 1 2 4 4 3 1 2 3 3 0 0 1 1 2 +TG[T>A]TA 3 1 4 5 5 0 2 0 3 0 0 1 3 1 4 +TG[T>A]TC 6 1 2 2 2 0 1 0 5 1 0 1 0 3 2 +TG[T>A]TG 12 0 0 4 2 2 2 4 1 1 0 1 3 0 4 +TG[T>A]TT 5 2 3 3 6 1 0 6 3 3 4 1 3 2 1 +TG[T>C]AA 15 11 20 5 6 0 8 11 3 4 2 2 7 13 4 +TG[T>C]AC 17 5 15 12 2 1 4 7 2 4 2 3 7 11 0 +TG[T>C]AG 19 5 13 8 2 1 3 9 4 0 0 0 6 3 2 +TG[T>C]AT 29 13 24 11 12 3 6 11 11 13 2 4 7 18 7 +TG[T>C]CA 18 10 11 6 4 0 7 5 2 12 1 3 1 7 0 +TG[T>C]CC 4 5 8 2 5 1 2 3 3 3 0 0 0 4 1 +TG[T>C]CG 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 +TG[T>C]CT 20 6 18 6 8 1 6 7 4 7 2 2 13 20 3 +TG[T>C]GA 9 7 9 4 3 0 3 5 4 2 0 0 1 2 2 +TG[T>C]GC 7 4 5 2 3 1 3 5 2 5 0 1 2 7 1 +TG[T>C]GG 3 5 7 4 1 1 6 5 5 6 1 0 2 6 3 +TG[T>C]GT 9 2 10 7 5 1 6 5 9 6 1 1 3 1 2 +TG[T>C]TA 8 4 7 5 5 0 7 12 4 3 0 0 3 4 2 +TG[T>C]TC 21 6 14 8 7 2 7 4 7 6 1 2 12 9 4 +TG[T>C]TG 9 8 12 9 6 2 11 9 7 7 2 2 6 10 3 +TG[T>C]TT 8 11 17 11 9 2 11 11 10 12 1 1 7 13 6 +TG[T>G]AA 4 2 0 2 0 0 1 0 2 3 0 0 2 0 0 +TG[T>G]AC 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 +TG[T>G]AG 3 1 0 1 0 0 0 0 1 1 1 0 0 0 1 +TG[T>G]AT 4 0 0 1 3 0 0 2 0 0 0 0 0 0 1 +TG[T>G]CA 1 0 0 1 0 0 1 3 1 2 1 0 0 0 1 +TG[T>G]CC 0 3 3 0 1 0 1 1 0 1 0 0 1 0 0 +TG[T>G]CG 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 +TG[T>G]CT 3 2 1 2 2 0 0 1 0 4 0 1 2 1 2 +TG[T>G]GA 0 1 2 3 2 0 1 4 1 3 0 0 1 0 0 +TG[T>G]GC 4 1 1 2 0 0 2 2 1 0 1 0 1 1 0 +TG[T>G]GG 3 1 1 2 0 0 0 3 1 1 0 0 0 1 0 +TG[T>G]GT 3 0 1 0 1 1 0 5 1 1 0 0 2 1 0 +TG[T>G]TA 3 1 3 0 3 0 4 2 0 6 1 0 1 0 1 +TG[T>G]TC 4 0 1 2 2 0 2 3 1 3 0 0 2 0 1 +TG[T>G]TG 4 3 1 0 1 1 0 1 1 6 0 0 1 0 1 +TG[T>G]TT 4 1 4 2 7 0 1 3 6 3 0 1 2 4 1 +TT[C>A]AA 16 6 16 14 9 4 5 19 5 5 2 3 4 5 2 +TT[C>A]AC 10 3 16 8 7 2 6 13 7 5 1 3 2 5 6 +TT[C>A]AG 10 6 5 4 8 0 3 7 6 12 0 1 3 2 4 +TT[C>A]AT 26 5 18 9 18 2 8 18 20 8 2 2 8 4 9 +TT[C>A]CA 13 8 8 12 4 0 5 10 17 7 3 3 8 8 3 +TT[C>A]CC 17 4 16 11 7 2 2 8 10 6 1 1 7 1 4 +TT[C>A]CG 2 0 2 1 1 0 0 1 0 1 0 0 0 2 0 +TT[C>A]CT 12 11 22 12 9 0 6 16 11 12 4 3 3 10 11 +TT[C>A]GA 2 0 1 0 1 0 4 3 1 2 0 0 0 1 1 +TT[C>A]GC 4 0 1 0 1 0 0 2 1 1 0 0 2 1 0 +TT[C>A]GG 0 1 0 1 0 0 0 1 0 2 0 0 1 0 0 +TT[C>A]GT 2 1 2 4 0 0 0 2 0 1 0 1 0 1 3 +TT[C>A]TA 13 3 10 3 10 1 2 8 11 10 3 3 3 6 3 +TT[C>A]TC 20 4 7 8 8 2 4 10 9 10 1 0 3 7 6 +TT[C>A]TG 20 4 6 8 14 2 5 6 15 6 2 3 5 7 5 +TT[C>A]TT 48 10 12 9 21 3 7 18 28 11 5 4 2 12 10 +TT[C>G]AA 5 2 15 2 8 1 4 13 6 6 3 2 3 4 3 +TT[C>G]AC 0 0 5 0 5 0 1 0 2 0 0 1 1 2 1 +TT[C>G]AG 0 4 4 5 5 0 1 3 3 0 3 1 4 0 3 +TT[C>G]AT 1 0 6 2 3 0 1 5 2 1 2 1 0 1 0 +TT[C>G]CA 9 4 6 8 4 2 4 11 12 2 1 0 5 3 3 +TT[C>G]CC 2 2 2 1 5 0 5 7 2 5 2 0 2 5 2 +TT[C>G]CG 4 0 1 0 0 0 0 2 0 1 0 0 0 0 0 +TT[C>G]CT 8 3 6 4 2 0 3 5 3 7 1 3 2 3 3 +TT[C>G]GA 1 1 3 0 2 1 1 1 1 0 0 0 0 0 0 +TT[C>G]GC 0 1 0 1 1 0 0 2 0 0 0 0 1 1 0 +TT[C>G]GG 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 +TT[C>G]GT 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 +TT[C>G]TA 13 5 8 14 13 2 6 22 6 8 1 0 4 6 6 +TT[C>G]TC 8 3 12 5 13 1 9 12 5 5 2 2 3 2 3 +TT[C>G]TG 5 3 3 0 7 0 6 9 10 9 3 1 1 2 1 +TT[C>G]TT 13 8 12 9 10 1 15 32 16 14 1 4 4 5 5 +TT[C>T]AA 14 7 13 13 14 0 2 7 4 18 0 1 5 8 9 +TT[C>T]AC 11 6 11 9 5 2 2 6 6 5 2 2 5 6 3 +TT[C>T]AG 15 5 8 6 9 1 5 17 7 8 1 2 3 7 5 +TT[C>T]AT 17 15 14 13 10 4 9 16 15 21 2 4 6 12 5 +TT[C>T]CA 7 7 10 10 11 3 7 18 5 5 1 5 6 8 6 +TT[C>T]CC 16 15 10 16 9 5 8 22 8 9 3 1 10 17 2 +TT[C>T]CG 1 1 1 1 2 2 1 2 0 1 0 0 0 0 0 +TT[C>T]CT 19 18 23 15 18 4 13 22 12 20 2 1 11 21 10 +TT[C>T]GA 20 7 11 7 7 3 5 5 10 11 2 1 3 5 2 +TT[C>T]GC 7 5 2 3 3 0 3 3 0 6 2 0 0 2 4 +TT[C>T]GG 15 3 3 2 7 1 5 4 1 4 0 2 5 3 5 +TT[C>T]GT 11 7 4 4 3 4 3 3 5 8 0 1 4 3 2 +TT[C>T]TA 13 4 8 5 7 0 3 15 12 6 3 1 5 7 10 +TT[C>T]TC 19 7 9 11 10 0 10 17 11 8 2 0 3 1 9 +TT[C>T]TG 16 6 14 5 9 0 5 9 13 9 1 2 5 8 6 +TT[C>T]TT 32 12 18 18 18 1 5 15 8 6 2 7 7 14 8 +TT[T>A]AA 63 3 14 17 6 3 12 10 17 7 1 4 4 5 6 +TT[T>A]AC 13 2 4 2 4 0 3 3 4 3 1 0 3 2 3 +TT[T>A]AG 45 1 1 2 1 0 1 3 5 5 0 3 4 1 6 +TT[T>A]AT 77 4 11 14 12 3 6 21 7 9 0 4 2 5 7 +TT[T>A]CA 16 5 4 9 6 2 2 7 3 4 0 1 3 2 4 +TT[T>A]CC 7 2 8 6 5 1 1 6 6 6 1 2 1 4 2 +TT[T>A]CG 0 1 2 0 0 0 0 1 1 0 0 0 0 0 0 +TT[T>A]CT 21 6 12 8 9 3 13 21 10 7 4 3 4 5 4 +TT[T>A]GA 26 0 5 1 5 0 1 3 6 4 2 0 2 5 1 +TT[T>A]GC 13 3 7 5 0 1 1 3 1 3 1 0 1 2 1 +TT[T>A]GG 32 2 2 2 5 1 4 9 3 1 0 0 3 1 1 +TT[T>A]GT 47 3 6 6 6 2 7 6 2 5 1 2 3 1 2 +TT[T>A]TA 26 2 8 3 11 1 2 13 2 13 2 3 3 1 2 +TT[T>A]TC 2 3 9 4 5 0 4 4 4 13 3 1 3 3 1 +TT[T>A]TG 20 1 4 2 3 2 1 4 5 2 2 3 1 1 3 +TT[T>A]TT 27 3 19 8 11 1 5 6 9 16 6 2 10 10 8 +TT[T>C]AA 23 22 43 20 12 2 9 17 10 13 2 9 19 24 7 +TT[T>C]AC 24 11 24 15 13 1 7 8 4 12 5 6 8 18 2 +TT[T>C]AG 36 5 27 17 11 1 11 9 5 13 2 4 11 6 3 +TT[T>C]AT 68 30 76 40 31 2 22 26 21 25 5 8 19 41 3 +TT[T>C]CA 25 15 28 16 8 1 12 15 7 11 2 5 11 19 0 +TT[T>C]CC 24 11 32 16 10 1 9 12 7 9 3 4 11 14 4 +TT[T>C]CG 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 +TT[T>C]CT 31 17 45 23 15 1 12 20 12 14 2 5 22 28 4 +TT[T>C]GA 20 8 20 8 11 2 3 10 3 9 1 2 4 9 3 +TT[T>C]GC 20 5 26 12 4 1 7 5 8 7 1 4 4 10 2 +TT[T>C]GG 8 7 12 7 4 0 7 10 5 7 3 1 10 6 2 +TT[T>C]GT 33 15 32 17 17 3 9 9 9 12 4 4 14 25 4 +TT[T>C]TA 15 8 33 17 4 2 6 10 11 5 2 0 3 13 4 +TT[T>C]TC 16 9 34 20 8 1 10 6 7 12 0 5 17 21 0 +TT[T>C]TG 17 11 19 9 9 2 12 7 6 9 3 1 6 11 2 +TT[T>C]TT 31 25 40 23 19 2 18 14 11 26 2 10 21 20 4 +TT[T>G]AA 9 2 2 6 8 0 3 10 5 7 0 2 6 1 2 +TT[T>G]AC 4 1 1 1 1 0 1 2 0 1 0 0 0 0 0 +TT[T>G]AG 5 1 1 1 0 0 1 6 4 5 0 3 0 2 1 +TT[T>G]AT 8 1 4 4 3 0 3 5 1 3 0 0 2 2 2 +TT[T>G]CA 4 0 9 2 3 1 6 13 1 7 2 3 5 3 3 +TT[T>G]CC 12 2 3 2 1 2 3 5 4 4 1 0 5 0 6 +TT[T>G]CG 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 +TT[T>G]CT 9 6 11 4 11 0 10 7 2 10 3 2 1 3 2 +TT[T>G]GA 12 0 3 2 4 1 1 8 1 8 0 1 1 5 5 +TT[T>G]GC 2 3 2 1 2 0 1 4 2 1 1 0 3 1 2 +TT[T>G]GG 4 2 2 0 2 1 2 5 2 2 0 0 0 1 1 +TT[T>G]GT 11 1 8 1 2 2 2 4 3 2 3 0 3 2 0 +TT[T>G]TA 11 5 8 5 7 2 6 15 8 11 2 1 3 5 7 +TT[T>G]TC 5 2 8 6 6 0 2 13 6 11 2 0 4 4 1 +TT[T>G]TG 7 1 4 2 5 2 2 5 1 5 0 1 1 1 1 +TT[T>G]TT 15 5 15 18 13 0 14 27 11 17 2 8 5 6 11 \ No newline at end of file diff --git a/input/examples/samples/test288.all b/input/examples/samples/test288.all new file mode 100755 index 0000000..ddb15db --- /dev/null +++ b/input/examples/samples/test288.all @@ -0,0 +1,289 @@ +MutationType Sample 1 Sample 2 Sample 3 Sample 4 Sample 5 Sample 6 +T:A[C>A]A 15 22 10 8 15 19 +T:A[C>A]C 13 12 6 3 9 22 +T:A[C>A]G 4 3 3 0 2 8 +T:A[C>A]T 12 8 8 5 19 4 +T:A[C>G]A 13 13 6 7 5 7 +T:A[C>G]C 8 9 3 4 4 3 +T:A[C>G]G 0 2 3 0 2 1 +T:A[C>G]T 6 9 5 5 9 8 +T:A[C>T]A 32 12 23 10 17 18 +T:A[C>T]C 10 11 12 10 14 14 +T:A[C>T]G 26 15 15 13 24 16 +T:A[C>T]T 22 11 14 14 23 11 +T:A[T>A]A 11 9 5 8 10 6 +T:A[T>A]C 7 3 4 2 2 9 +T:A[T>A]G 6 5 6 1 7 7 +T:A[T>A]T 4 6 9 7 29 11 +T:A[T>C]A 40 55 22 22 38 46 +T:A[T>C]C 17 29 5 3 19 17 +T:A[T>C]G 24 38 21 10 43 46 +T:A[T>C]T 26 42 14 26 24 31 +T:A[T>G]A 8 5 5 1 3 4 +T:A[T>G]C 5 2 6 2 3 3 +T:A[T>G]G 6 1 3 4 6 3 +T:A[T>G]T 7 4 8 9 11 8 +T:C[C>A]A 17 24 16 8 17 14 +T:C[C>A]C 11 21 10 3 8 20 +T:C[C>A]G 3 2 0 0 1 5 +T:C[C>A]T 8 15 11 6 14 12 +T:C[C>G]A 9 8 3 1 4 8 +T:C[C>G]C 11 7 4 2 10 8 +T:C[C>G]G 0 0 3 1 1 1 +T:C[C>G]T 7 8 2 5 10 5 +T:C[C>T]A 16 12 12 7 21 6 +T:C[C>T]C 18 14 15 5 18 16 +T:C[C>T]G 12 9 9 6 18 16 +T:C[C>T]T 14 20 15 10 19 10 +T:C[T>A]A 2 4 6 3 6 6 +T:C[T>A]C 2 9 6 1 14 13 +T:C[T>A]G 5 7 6 4 11 11 +T:C[T>A]T 1 6 5 3 13 7 +T:C[T>C]A 7 17 9 6 18 17 +T:C[T>C]C 12 16 6 5 14 20 +T:C[T>C]G 12 16 6 8 16 11 +T:C[T>C]T 18 21 9 13 25 16 +T:C[T>G]A 0 1 1 1 5 5 +T:C[T>G]C 1 1 5 2 8 1 +T:C[T>G]G 4 3 2 2 8 5 +T:C[T>G]T 7 3 4 7 13 8 +T:G[C>A]A 12 14 12 4 9 13 +T:G[C>A]C 4 9 7 6 3 9 +T:G[C>A]G 3 1 2 2 1 1 +T:G[C>A]T 3 6 7 4 5 9 +T:G[C>G]A 3 5 2 1 2 6 +T:G[C>G]C 7 2 4 3 1 5 +T:G[C>G]G 1 2 1 1 2 1 +T:G[C>G]T 2 6 3 2 5 6 +T:G[C>T]A 22 21 8 9 15 16 +T:G[C>T]C 20 14 13 3 10 10 +T:G[C>T]G 15 6 10 8 19 15 +T:G[C>T]T 11 11 11 8 23 16 +T:G[T>A]A 0 1 3 2 8 3 +T:G[T>A]C 2 2 0 2 6 2 +T:G[T>A]G 1 2 3 1 6 2 +T:G[T>A]T 1 10 5 1 5 0 +T:G[T>C]A 14 25 5 10 12 16 +T:G[T>C]C 11 16 1 5 13 9 +T:G[T>C]G 5 14 2 4 12 9 +T:G[T>C]T 12 22 6 8 13 6 +T:G[T>G]A 0 1 0 2 2 2 +T:G[T>G]C 0 0 0 2 0 2 +T:G[T>G]G 0 2 1 1 1 3 +T:G[T>G]T 0 0 2 2 3 3 +T:T[C>A]A 14 16 11 10 17 14 +T:T[C>A]C 14 10 14 8 15 19 +T:T[C>A]G 4 2 0 1 1 2 +T:T[C>A]T 10 13 17 11 13 16 +T:T[C>G]A 4 8 4 6 7 7 +T:T[C>G]C 6 9 6 9 7 8 +T:T[C>G]G 1 0 0 2 0 1 +T:T[C>G]T 10 8 10 7 13 19 +T:T[C>T]A 9 20 12 16 17 24 +T:T[C>T]C 11 21 11 21 9 26 +T:T[C>T]G 14 5 6 7 11 13 +T:T[C>T]T 13 16 15 7 17 17 +T:T[T>A]A 2 6 6 10 8 4 +T:T[T>A]C 5 15 4 2 11 5 +T:T[T>A]G 4 4 1 3 6 8 +T:T[T>A]T 7 8 7 2 13 8 +T:T[T>C]A 35 41 2 9 10 40 +T:T[T>C]C 13 25 3 6 11 9 +T:T[T>C]G 9 14 1 1 13 14 +T:T[T>C]T 23 29 8 10 12 29 +T:T[T>G]A 4 4 4 7 6 6 +T:T[T>G]C 7 4 4 3 3 3 +T:T[T>G]G 2 7 8 1 2 9 +T:T[T>G]T 12 5 11 6 11 9 +U:A[C>A]A 21 15 17 5 18 19 +U:A[C>A]C 13 7 7 2 14 10 +U:A[C>A]G 0 0 1 0 1 1 +U:A[C>A]T 8 6 4 4 9 11 +U:A[C>G]A 3 8 6 3 7 12 +U:A[C>G]C 5 4 5 0 3 6 +U:A[C>G]G 1 0 3 0 1 0 +U:A[C>G]T 7 9 5 3 10 12 +U:A[C>T]A 19 15 21 7 15 11 +U:A[C>T]C 7 10 9 8 5 6 +U:A[C>T]G 27 8 7 11 18 12 +U:A[C>T]T 13 11 13 6 11 15 +U:A[T>A]A 8 9 4 6 11 9 +U:A[T>A]C 2 3 1 2 10 5 +U:A[T>A]G 8 6 8 5 13 2 +U:A[T>A]T 12 9 11 8 41 9 +U:A[T>C]A 19 25 10 19 35 22 +U:A[T>C]C 8 15 8 6 16 14 +U:A[T>C]G 16 13 9 20 42 30 +U:A[T>C]T 14 21 12 9 37 21 +U:A[T>G]A 3 2 3 5 8 4 +U:A[T>G]C 3 3 2 5 8 6 +U:A[T>G]G 3 7 2 2 13 4 +U:A[T>G]T 10 7 6 10 17 6 +U:C[C>A]A 16 30 8 5 15 17 +U:C[C>A]C 9 13 11 3 13 18 +U:C[C>A]G 3 0 3 2 2 3 +U:C[C>A]T 9 13 12 6 21 14 +U:C[C>G]A 1 9 5 4 2 5 +U:C[C>G]C 7 6 8 3 6 6 +U:C[C>G]G 1 1 1 1 3 4 +U:C[C>G]T 9 7 5 5 10 8 +U:C[C>T]A 14 26 9 5 6 17 +U:C[C>T]C 9 11 12 6 19 14 +U:C[C>T]G 7 2 8 12 7 11 +U:C[C>T]T 11 20 5 14 15 14 +U:C[T>A]A 7 2 4 9 10 8 +U:C[T>A]C 6 8 7 4 12 8 +U:C[T>A]G 15 8 8 11 34 12 +U:C[T>A]T 7 6 10 5 18 11 +U:C[T>C]A 6 7 15 12 21 9 +U:C[T>C]C 4 8 7 8 17 7 +U:C[T>C]G 6 8 10 15 30 18 +U:C[T>C]T 10 9 6 10 26 10 +U:C[T>G]A 4 1 1 3 2 2 +U:C[T>G]C 3 3 4 4 8 9 +U:C[T>G]G 1 1 4 5 4 5 +U:C[T>G]T 5 12 6 7 13 8 +U:G[C>A]A 11 12 7 5 12 14 +U:G[C>A]C 5 8 6 6 4 5 +U:G[C>A]G 1 3 3 0 0 4 +U:G[C>A]T 8 8 5 2 5 3 +U:G[C>G]A 2 3 2 2 4 3 +U:G[C>G]C 3 2 1 4 5 2 +U:G[C>G]G 0 1 0 0 4 0 +U:G[C>G]T 6 4 4 3 4 7 +U:G[C>T]A 14 13 11 7 21 20 +U:G[C>T]C 10 19 5 9 14 12 +U:G[C>T]G 14 8 1 14 12 9 +U:G[C>T]T 9 11 9 7 12 8 +U:G[T>A]A 2 2 2 1 5 5 +U:G[T>A]C 1 5 2 1 8 4 +U:G[T>A]G 4 5 6 3 10 5 +U:G[T>A]T 5 5 6 4 7 6 +U:G[T>C]A 20 14 8 12 11 15 +U:G[T>C]C 7 4 1 12 9 10 +U:G[T>C]G 4 11 6 12 20 12 +U:G[T>C]T 11 15 3 14 13 8 +U:G[T>G]A 4 1 0 1 1 1 +U:G[T>G]C 3 0 1 2 0 1 +U:G[T>G]G 5 3 1 0 3 3 +U:G[T>G]T 4 4 2 3 0 4 +U:T[C>A]A 10 13 15 7 24 18 +U:T[C>A]C 10 14 9 9 12 17 +U:T[C>A]G 4 2 3 2 3 2 +U:T[C>A]T 16 19 11 15 19 11 +U:T[C>G]A 11 3 3 6 6 11 +U:T[C>G]C 3 4 4 5 9 10 +U:T[C>G]G 3 2 1 0 2 3 +U:T[C>G]T 13 14 9 12 20 17 +U:T[C>T]A 16 19 21 13 20 34 +U:T[C>T]C 23 19 15 9 17 25 +U:T[C>T]G 9 12 8 4 12 5 +U:T[C>T]T 12 10 8 9 12 21 +U:T[T>A]A 4 8 11 10 11 16 +U:T[T>A]C 1 8 5 5 9 5 +U:T[T>A]G 3 4 3 8 12 6 +U:T[T>A]T 13 13 8 4 23 23 +U:T[T>C]A 12 18 9 7 14 26 +U:T[T>C]C 8 13 4 4 9 8 +U:T[T>C]G 12 12 6 3 15 7 +U:T[T>C]T 13 12 13 6 25 18 +U:T[T>G]A 8 4 2 7 6 5 +U:T[T>G]C 7 6 5 3 14 5 +U:T[T>G]G 4 5 2 2 7 7 +U:T[T>G]T 16 20 17 19 19 15 +N:A[C>A]A 73 105 64 40 45 110 +N:A[C>A]C 30 43 16 17 17 54 +N:A[C>A]G 10 10 6 2 6 10 +N:A[C>A]T 46 48 37 17 27 46 +N:A[C>G]A 43 36 20 17 21 32 +N:A[C>G]C 10 14 16 8 10 17 +N:A[C>G]G 4 4 1 4 4 0 +N:A[C>G]T 25 24 21 12 22 23 +N:A[C>T]A 48 54 36 25 58 39 +N:A[C>T]C 31 38 24 22 30 26 +N:A[C>T]G 83 51 36 36 74 56 +N:A[C>T]T 40 43 32 21 50 49 +N:A[T>A]A 27 20 18 11 36 49 +N:A[T>A]C 18 13 15 6 13 26 +N:A[T>A]G 23 24 16 8 31 29 +N:A[T>A]T 12 22 28 21 62 43 +N:A[T>C]A 90 134 45 53 63 116 +N:A[T>C]C 44 80 11 16 32 38 +N:A[T>C]G 62 85 28 41 75 70 +N:A[T>C]T 74 105 39 38 55 85 +N:A[T>G]A 15 11 10 9 14 17 +N:A[T>G]C 6 8 7 5 12 13 +N:A[T>G]G 9 16 11 8 19 16 +N:A[T>G]T 10 17 15 7 19 18 +N:C[C>A]A 80 102 40 19 41 86 +N:C[C>A]C 38 63 24 16 36 52 +N:C[C>A]G 4 6 13 4 9 8 +N:C[C>A]T 55 56 36 19 34 47 +N:C[C>G]A 13 18 17 6 10 20 +N:C[C>G]C 10 20 12 7 23 18 +N:C[C>G]G 4 2 4 2 2 5 +N:C[C>G]T 24 27 18 16 23 36 +N:C[C>T]A 48 51 28 18 39 44 +N:C[C>T]C 41 54 33 20 55 45 +N:C[C>T]G 36 33 23 27 30 34 +N:C[C>T]T 45 58 37 32 47 62 +N:C[T>A]A 17 14 13 8 28 26 +N:C[T>A]C 16 39 14 9 27 24 +N:C[T>A]G 20 21 17 13 39 35 +N:C[T>A]T 17 21 23 10 34 33 +N:C[T>C]A 23 38 26 31 46 50 +N:C[T>C]C 28 60 15 15 11 48 +N:C[T>C]G 25 53 13 27 40 35 +N:C[T>C]T 36 67 18 29 27 56 +N:C[T>G]A 6 1 4 7 7 9 +N:C[T>G]C 11 10 5 5 9 12 +N:C[T>G]G 11 11 8 11 10 14 +N:C[T>G]T 10 10 7 19 12 22 +N:G[C>A]A 35 58 31 24 20 43 +N:G[C>A]C 19 35 24 6 14 32 +N:G[C>A]G 10 6 5 4 4 9 +N:G[C>A]T 24 37 21 16 12 35 +N:G[C>G]A 8 15 14 7 7 12 +N:G[C>G]C 11 9 8 7 17 17 +N:G[C>G]G 5 1 2 1 0 1 +N:G[C>G]T 7 12 9 8 10 15 +N:G[C>T]A 38 46 34 23 33 55 +N:G[C>T]C 30 37 31 18 28 47 +N:G[C>T]G 42 32 33 28 61 42 +N:G[C>T]T 36 55 47 27 42 55 +N:G[T>A]A 13 7 8 3 13 11 +N:G[T>A]C 11 18 7 3 6 9 +N:G[T>A]G 7 14 4 5 15 13 +N:G[T>A]T 14 11 17 9 19 17 +N:G[T>C]A 40 83 15 24 26 69 +N:G[T>C]C 26 46 7 14 18 32 +N:G[T>C]G 31 44 12 14 17 29 +N:G[T>C]T 35 51 23 28 29 48 +N:G[T>G]A 5 1 5 1 4 5 +N:G[T>G]C 1 4 4 0 5 5 +N:G[T>G]G 8 6 3 4 11 8 +N:G[T>G]T 7 7 5 7 5 5 +N:T[C>A]A 36 52 40 29 28 59 +N:T[C>A]C 43 59 40 24 21 76 +N:T[C>A]G 3 6 7 3 2 15 +N:T[C>A]T 34 55 38 39 34 75 +N:T[C>G]A 17 23 14 15 17 23 +N:T[C>G]C 20 28 13 10 26 38 +N:T[C>G]G 1 4 1 0 4 5 +N:T[C>G]T 27 40 31 28 41 54 +N:T[C>T]A 46 59 44 31 45 64 +N:T[C>T]C 56 71 36 22 46 66 +N:T[C>T]G 18 14 22 14 31 23 +N:T[C>T]T 35 39 54 42 47 52 +N:T[T>A]A 22 20 23 24 29 32 +N:T[T>A]C 22 32 20 4 27 33 +N:T[T>A]G 16 20 11 9 20 21 +N:T[T>A]T 29 29 30 23 44 36 +N:T[T>C]A 74 113 15 27 45 61 +N:T[T>C]C 46 76 9 19 22 35 +N:T[T>C]G 33 70 11 11 25 56 +N:T[T>C]T 60 99 13 30 39 78 +N:T[T>G]A 17 13 7 14 12 11 +N:T[T>G]C 15 12 15 8 24 23 +N:T[T>G]G 9 10 7 6 14 23 +N:T[T>G]T 32 28 22 23 36 41 \ No newline at end of file diff --git a/output/examples/BRCA_example_CNV48_counts.pdf b/output/examples/BRCA_example_CNV48_counts.pdf deleted file mode 100644 index 66ffa637dddca4ae6f70386c50d56826aafadc3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35368 zcmd43byywC(l49@g1c*2XmDG=f?&Y{1eX9og1bAxC3uh!f&>e0!5snwcPDsocXzq7 z$jQEYpLgH=o#)>3$M^6wJ!^WptLoP^-BnXFMJ+G-f{Bfp1Bv?U3@E=Ai4DXGveq+0 z;^PCc$m<##+Jo4EGm0P<<+nD5AQll_2VDzmV~~IVlA)CW^g`}Gbr5rL5La^0bua{R z{Oa_=+R6b0{&g&`>)>E$X9ePf{zPJtx3kt)GIRiG0CYrO0OK3FIDl9rEdiRs|Efj) zRZD`jKrBiox(23J#vra=-PPpu%nbD%K#=>v|2I2qtiXxi0ti`ISv%MRB!K=R04s)8 zz%QO(1BlyMJKBJtVu~n%SVRq-O!W;F#R1a5FJ(JjD|;JVJ3}k|x4$L-bv;0cMaIy; zR9D#A1sE4fjE#+hgPEO^8^Q_V0&_8QazNPFIiVEgp#wPl#!u1E-rCVl9{?1J7y!U8 zK%p4_2~8+-zqx;5Y5@QSVtHW!AS!C8Z*2fffV82Nv4aUf6gmjBqrHQjp{^y8OJbj< zOaw_4X8l=_2`CoUhqhF$Eh6+G^2;#2?m~!u>hu)+pD+R7wdX55#)v{ z+giG*N#io5n7SgLLc=e?0NN?YnXbnqCQv6y| zDv&wML(rNN^P4ihOE_IE$tv0ITI0Z6|A1h&5ka4qce>3i?#`_PM9}N)-H2C1?cLVT z(2M*tCF+h=y4Bfp+}*G7w_G=dx3{AK&Ii{pg&OukoMT!IU}rg&H+=(MWUG;@szpsU zaVd|Z^SVB%DHgm|jMsM*!&3J=DL$UaFUr=wGH$xMyS;)OYf;0Aq$dk7b}j@wgtbJ9m51s3P0KiY zX2*n<1<^CKYkH3lNLT^~vh>;a`?5>Ti&fX?{`*3Weu)+XCylq~BQl5MS`SAh%nO zX|8zJD)&4EQHx3}XZ&jNBKq!d3AwimjqXbi0DTH=vdM7Hrz@@2-;X033 zi)l-XpqKL4Rbza?1tgORw?o1Ji4M1p|_i97<@&`Ga*n_vn!`Opsnu^oKOUQ^&9$xLi27{>( z`u6e%+SV#HI#j%Y`ANj`mBLZKRt|UDvQHhZ+-$ukhTTPNgi<^o?=-&FTwysHe2=4e zniSpBi~*k(VAv>+=>qI~y^%MHjUmU)VFUPzC7KFI(v%ns0gy!c7A)x=#M@&p_CP$% z-~`a-lpWNrl^{$S38u~2!}o2krgNpB8WNWrrxi2RPn~eO!!+=!dS`?hs(8H-II+lv zK?A8Hr!i}vGcCt{ot1yl>(aX?z$iDm%REq#RjC`xLS@nhFE|_e$zSAAOsWv|?#({9 zHrH~(kU{9O*~F9fxs$LD!jI}JG>83?a@0BtF$rygK8%kV$!~BEZSS9^_MR!hCR!onIek+`&&crhsM;j>dx)1){G zv4S00UBp~{yD&PX^odGA(6yoKIgh5Owgm~x9Qw-97{rvOF6eB3tSZE<7 z+&?Z{Kb7AvMM{E|F2fZkyhK!#xlqPmlphm`?73*Gc1FrLIfoLaD zTK5N-JBZ!BY(vSrA%Q_(>_r*H7Nuvr3_;0u1dC2Kmf30AeRK86dtSA7ryXYywy6eY zEQZHTizbf>*3hdT9qbb(1(phaYchU_>UqGkF&$F)g#j$%6Lo|rS$2~*6BVJ{TeWK5 z&M?~$?(JxpL8FzIjCN=A`OS4>_|c@w1XG`9H)AT#lae<}n_ZXnc=1KJ@px5)J}Lyc z?`(N1jKAby5mu=tDqRgbNqgG56=b(q+Y)bmO~?Lt`v5(x?DBIxCNqshu=o=lH>WO) zjMAM++z71sPv{NIg(+Jb`x=^ziEO>dVm_feB`bbAKXJDTYSVh8vrtG_OrE)7UhPn@ z6tYu{9~U&Ia!X*vD5W{qCZjcW9XMQf6}tt?Xos%tcKa`F;c6MN8)gMJ>jg}dNRKA- zBK-(A4AXDIWHU+dswH|nx9F7BO}^aPXPMby`NMtndv$%x28TPl;k*+H+8H%(45EIS zo>Q6r>m@}^J?+?UBID@?3GIhNj~gY5qS6&*`QNhT4T!Cpi{T-*yu{Rd^O1BeI`2p# zYx{h6f0KQ&rZr&8702_V-BPT2d2&)h_~lpT@BSpDhFd94)_c#Hib9ZUy9DRGQ}xEadMLsHn}4PO6rf~XjZi|3s+_re~1 zouonnZ|E*s_}SQI)9v^#xn^krAoaqE>rjvBIDKuGhYg*rTXv)+v)tM<2>6r|2s6V+vtm}+i0_(oHI=zp z=)~Jn_G(=@Je62HyEAR0PPu$ZuG{R}+e&m^>s+ZU&|8oF;8T3&Q5vuQjLBRy?QAS# z5>SnJ$M~-3_$hLPQbt5Q{bw!+U58jqOVthD6GAN6IEQw+1$lKgen&egyJm4;XJ)FW z!Wkp^$-i5|!lUcb*~|slcnP6)G~{&{R-;q;fzX}KQOHiY1zZqG7(N3^(=kY)U8m z>=4PhYhE#(j;tL1z8I)qzSp7TV%&|}f{z@_^t2*&sCVjn7DE^XVqs1F)4@2q7j<|= zgf6A9Ok|(6Z{xVO+NHNYoGiy#+|ho^_n3~+zuPw*o!p^)n$7uL;eF8zPdsln!>N!j z|7x7wfl3SR?sna3U(+sn*nS@u8O>Ljsc5^4**4rgqI$h0{nqnJI&=aR!dfM_D_I@m zHqLZG<_5@=d66fTDg`{T84^UjSa+^seYWr$B85=IbnH~v?N=AoJ5GJs4|XQwDbqg- z8%YhkB?ic+oK#7W5e>F3ngLyZkA(d=>5%>-Ss`3~b6wV$85g74o3~RD9fc+4?r)B^ zK4VImLrD2P2q4zFFy)$6X@AfhYFcUNHeGVeQoC zy5$F?JFQbZW!swbHk9eSt*&Kb_A=%tB)g@$n(q{2N>Zsc?Gd3gZP^!vXYXfMUU-13X|@M$!q+{`0fPe zusFJUEG8yiShq|%Z4s8o-D*xDhwO!D_>eA-dc8PRPau|po^5>BN7x95W0>Ha_p_f! zzG&_&Y@k!>k-`nu#n>A-U7Sx4y!1Hu*;2-^A}eRBaN09sBxB!`JJWOJoJBB#MZm-T z&a$-`H%6=6>2Ap=*RlOr^CQzqhoF}&z2o3uotU`X)9xPfZ%aixp>uOE0 zEDEo0$1h;tUXneand*l+ZvS!`{^i2mI}=c^0}S{wzx_HksN44275Q67itXMrL}K|b zds6IB_v!!Lle*{bH~;_WO8xRx|Kdt%$wW|9q1KNV(E_eilNt2~tlZFt#IpCU6kaEJ zCwa;E7Izuf^~0;ZwcM<_P(4TDEonK&h?4!|{9*W%&ZjR6@+6N`l|Ik)+ukDGd49fQ zyTiV_bC*40xOU?eb9aSgwvyP%*32*Y-KgaTG!J`ueD7=NV9DMH-B=0CS#`s4Z~9mSJ&%^W1l*3sRmu8NJOoerZ9=0bPCVNJZ>7BwZrQ!uEU4k0 z-FWZJ>ah2r#%kBpWkRbCs{_Fm#>l%V~@?T;6q5i%^zWRh!gaZ+d4`^HP) z=2?RT+wIw0W4yK(=iTnfaMIQw*m2M17zZ&krgwAw^+D1`?iX<)YM01kSyB|pHRJX- z39qSO@(=PnG&13-xO4I3edKuk(gb7#xjx*_@E`Hmq}3Cc`8HEivtTeZu!!)iM%uL? zh~a*wULNvzjpm#vE34@}^SmQ1 zU&L#lS1F#XUM8ltgsC5u815%sr*S``hv=4frLMJ$Fgunso1q%$jYhrdiD zjvJ);Oez8;4C}%CA)04A+A4qG-GL--ZV@u8-<~wuaZON&gk|PW^^{-^12cI&@qv&% zY4qb7yr_4EFQOB+z_{<67Z>#b7LH&%V&3O|{LpYjx(*f!l+<`lgWNM1ve%1o{F;)y zUGMz`+Hw4smiG^*TPH&HdN4#%Ug5;^D%BM5fdk+t;V#bE&--VdCu@+u4;iDWiZKpA zQGFkU&I~Ytt`zhda|WkoMl+fGd#YKFKsibSSg@EzEG;@xaD=oIEE14Ok=V&rzQ_xH zH-=@W$Sk=_?$%DkK|A&=0Yl@!15tRDgx!@~J$=)1rAEhHeQ`Z%4R<#Fv$RhsjYB~0 zta>7{Xmu_ZnL6BD{F5MX2Xn7Gy4yfzImVVQanoVhA|RW&8Z5(N4DC-JZhTYn4|(WC z*x$f{CI!(miZn4!@Kc)V$UG+oEtuttSM18EeVn1}D)=?CDhcL~5c8r8s5<6(Kf*Z1 z#9`{x$n8K>j1i=tKmO4+h6Dgy{(AqT9TU$_%>)Jxg3zF}U2`SByRBj(U^!0f z4C?P>^UceWaW6RUN1=lc;ju3$m}yBx^+AHfrOb?H!Og{z`}1KRl7$5?hM`;1ZiZ(3 zQcd{7-ng+3svvNE$uov@f!;KMYG96d<=3Lv8YwGGsszhYaZhqN?hz*Iv=7TAZw=a8 z=nXJKsWJN5Iu6y6<(ik4!Nt{Icq7;F+#1EM$0C}}40D8%Gj$emLfn_Y#Hc5>-HR~2 zP$=KN(4!^#kTiSU`@#>c>?PAKF8~@;E!(JqKMwAUtih4)?pW)Yw>huEU(RHx#1Nf4 z>9^3yLimKS`wQU681Jw7Ce1ib=*C>EPcSpVSD-R{CjtB?`iLG^thRSpOO;qj6!bX$ zB$px!tIf05%UE{X+Z@tZRVt<~>{hw)?vazoZs1lO33^kCnCX;R3Cxfgi9@c=F=RI- zWvMSwv?V6}&R>4erESL94R1=Svuw*?Er0&dS$3MV{#lr&V+g*EiPLka%zQjMKrcH> zLLzk3n72zDBmevfdw8Q^y&Vi7vsbvWLbP&LoduBR`X! z#UPA6A-c}LNMKoo2sT_?2JWSZ(jIClWR0$U=8^G$S=-O;ovUwKc{H-5mtAk`1d&zh zX0i!uy=80Oh2b&!p%4tG`JswYdqVL23Bh%b>E-$z=Z6oL2(c45a9ls6sUf=@yx8N! zYkgs?A2ev6w+fnt(v_93n3fHR`sw=zxo5Y1i)$FuKgf}fDu zb^(7m<*L9%G1PIfOg(KK6BG?KEq*E8CP-etSW|>I-xcAWm{+p@@x|$=(sAwa?Ad|F zOj#X`v)&CsN=R>Ph;-;s$Sge`@og9XSK-I3MbeNbj?(*rpT*(piQ2Vfz<5iop|NY2Pb~OhZgE;Nk(o@Et*YY{bz8fA!R}08=@x)WODdnt zYe;w@r|4>je>kUmTdwY=kuWMUdA2LuwPcAqD>-ws`Le`#SEu+%Zl`;0CxvcJ8wRqP zO}K1HK=fx9afplDPtahLYnsU>;r>%P$nDB*(bJ_YKY;|~5z*W&_E6{77!j|Lw%)Hw zs~t3P%J8e&PdX)nHRKq!$e%T2decOKGL{UP zbY;AyYLP25!p{{U>ikKe-n*e*$2QYnZXVzD$!Fm)sY-_Tt!arm3|nm2NZ~og$E@W1 zw#`VYPaSim#}_o($uSl&6*2Legapjc%lIMwCbM=xa-yd>@Et?XUymd4IbPT)AD><==8MH>5>z5rttgCN4M`ubUhOymw_xkaNs6SJD(mxnK>H9je7>na~) zFJK~#<`_AhzMgsCB0u0^Y5mGYP`tns7L%bfyT=F?)oKJqsjs3m!uaP*-Y~DIhm?Cc zF=jwlV3NaEo83UYjORhmzKyZZJJ;5{!Zdyy{La}}NKK`>!Flar)vm=>P0X_3+H3^q zmWuvj2(L9?xv$Ui?dus?#L8rI8Qg)|GfD(0h3*7Qae@}@L!(wytBeU1duo5ru_Q7f zO^S~_U4k#YS*;|MY&G8Ck+n~c+7}#nj@`h#SMc_FVO?Ds&|34hg~Fe{Du^ zFlq>uYQkzsl;N1}L_8&F0j{GcjxyhALRo*l?kB%|7rBzkL0~EFYQV#jHwUXn+v9CFAXntY|I+mTNb7E|-=yE=v&?wl+_ zPgsgF1w9vMGbb7mJ_@Ab+(q&EQFcAbUl|;)NPejO=F!d+ser&``+#OL^Ks_hJLeJm zL+cRs^TAjt5ADn9j4+y&O;TPz8GQ8}H>aB~GOz9y$^Fm^-fXUvKxp3woa9>}b4t?Tw z+wjDz;nlL(ck1>&YIj2A!Ab4gQ)TUMS7;BHGL+H?eQ8FI31|zNgxD zrJQk|4{m0@d2@JvbmH8Uk-SrS2~In09&FBhLdw5Zvf^TPA&h)O^6F(O*~7D^EIa;f z;P9fEs#mD^m7a^&ddkKld(QZjP4oIs$6Wi5buaW`^b^qvv@%Z8EMqTA%Fi;EtS6Jj zr>`X+jOTGKQ*@svtqrs`)SaJ^$S>oQ z74nat4^(2{Z#|JCEc9Ah+&NGNF~LV*OL^TYl?%Ez*$bt|SC0=xJTh{Q+Al$gfmg#a zdf|K-J6niSKVO!KkpG+`T1P3OvPAxEsxfkEn7ou%HYpx$U#wXpzXrl3(o1^#{DL5s z=>C{o+7`9oQ%dyC$+=MYm|)XT*!Jnu2-9I{jiT8hO4a_3%Sjt zlpGh-Uo2SUj-U`-O`E#s3f^9P)Xx>i^{AlTIMCU$!*RN?r>e;&nGsx}v_s z|9|vg{|JKqDHu2%zFdjvF|LZxDdnqE!x$x2`UYjfhW$k(sOs?{#xi+H#}+p~m%Go+ z6_2vE@>eUux?MI-@Prgu@YlTbMcogIp{p!U0sqzW7R$>s@s8&X`OcGTGPzv7I&6OSIbC* z*Iy2l)AKLhX}fL=woO2en6Q^c9LW3G#E&6fSKN2{w`QIpY~mW7ZxDNSXWar9f7AZl9R%x_xr zpgqM~B@G8yQ8)DWzD*oo=n(MxOi)wV?M}X4C|QQ}B`^*lH;}7iu=j=)zxMZZb%I8f zbTV3-KZ(#DJPxw=MxacU;v9ws%u2YI(X;%!Wze1R*B)S=QeP>fiZB2nGYaNlYfiln zwME?UlCrGtJ4d0RJhWDxRT3$x6jN*4@MulcPoYE5kl9n=WDz8uW(Q;|V~=pm9+LN8 zOpI87pc(voj34xzb{>dr_RGuFQTXZ5pbUoU)8?GiOfJb8trUGpX7Z%65BFg+WmV+N z2P1=xS|>chfeYqnU6EyreqA3nR ziO6PnFsujK`xSg?kvpd!Yg7enw_FLtPzjIYAGOD{YC6x&=!As(OT53Ob!X&%f3VCS zh%$oFSbq|)?|^8U7zU0136@l=2g69SL{(P_fE~EA)V7oGp~2Nq2F;gDatwWyD{(Um}PL&G{#N8{tRxf)H#owoRU9Rvtq{$ zwDUz)>b$bHTqYpF>&%QB1)|2Dpg!_IB3;*DXKT}b5)!O7@v@3kU;>3c(;=yS$GWAq zuw2H{JjJPp4x$qP>U(0f97JKVRuIP6sk3ZX`KTO<=XRdX(Bl#L#-x)P9dGgQAF~9? zKsXo4P?a4{1y%EOZi;qr!JDJ-#eIY|PD?hJAPZk|Mk9qyhWn7GRN+2&T(&fi-Q@7G z_2)?qj-BrZQ6qCG%Jh?BT{Q+FZvlc7?=at(m)sNd5eUShYUUWVHufkKEd+f?zZcP! z{y07gb`-Z_x3NNjvPL@k+db2sUj_thx)E^)r6#6wW?Y$hh)iU zBgo`VBqiIvra^N+tapgF34x-l5x@?(Q6q^_SYBRGZ(Adq^!PIWF!g@AgF9`DJuHPFUUCrF`G)hrr=o4XHfG@4G=)fDxrdP zAbC_#)Z#z|#Ptv#QjKDG(5H@-?|;{S8^knA&q??M=eFm-oBG_AueIGz{;(}pQ?{Ee zCg@!_<+!)*6lUuFLs2RWaz?csRcT&v3TDC*j$klS?kz9vS`BZ;DM#q1dF?)JF9BfP zJpXYv_p{C9D%=Q-cKO>VVyLhBG{lOEldQobwB`N84c5BrqPycFhXSpdqWpnM2v)|0 z8KT|#zBe#6#mvxl(4~84y0gRsaqG*~#=hGlIehH}2;^=WHv`YbEssVwys@@BmgY$1 zqbVXU{^(tor)elFwsD<0H!U}LFKF0>KS%c2d2-}r3QXK_;FiN!$96CRdQB`jx}FoB zZ$x;J*{xr@4|fcPJRhlpAgQNZ5T~vKw_PL(oq7P?MPp0_1x&~cpE_3eiNX3>M6KJbHT*kFV1z+MaSs`fTq z1ADEsu^Za!8@L=J6E#D}w?EHquXPvR4c z)M~2?RBjy32hbA>`2=M|hEO(cTPG8_We^J=$Efv@9=wy!>DwF)%sHTy>4`~`cTS(L zE8N~(r~9(ua53s*sy7hF;DJ}R6tIy=U7cHuM%rJ&iECAsvn#&jOt()@>Va_iKp0^= zuC&-gle39xQhj4^VK@NC&KyzbB>kYSJX)@~lLpq~0XbE>SVWUR`A?NAz3yZ`U%ztW z7>4&Own@Aj^L1vEp{H7KZO4O4HUeM{HN}eA77$jOGADc(e0N-fu#ln4ARvMV=Z5Wi zDZ%Z@!*}wN3VN*u$s|XS2?kpqMFO4EpPw9Qrh`&mnDdtP$*jq#zKRvF<$5Y>6VH|p z%eX5YbPj4#p$J4%jmoHdOOxrE#i@&iX#UM?Z+nrbnnDkm{_)oOm_V{r088j+6|v+( z2{W)U-zr&i^=F+EVG~PmJl6;;94n3o?$L7@|04{<-VBdH(n9*6!W82?#(wjO!90mK z_9cctGF3QyiY$$O8nIgz>l_M{tC~-W6C!SGDzZ!347#`tiDxC|GM;CqpfytNpXSHj z*r@uuEYT)DSBSLw_VJzjSLT3LwkezAhmK8`g~@9#nVFAl8~o?09sw^|gyKwHUT)%2 zyc=~K45x7N%Hkb-oKaVc8`=0qey;hmDxtk=?kK!WwnfBnLxsoGE=5iNm+fHD&_a8#lpw@i zZFXleVx)hHrXZoj@}gv-ZmUvh@XV)h_IvL3X=ov87~fB)OaE^}$8m&Sls;F}I^qn1 z{d=xG7pEF>Lu)&3Lvjg4a$+CP8ge~)&gInir5rly+_o4D=aQ}4+g1Vu{kOl#5nw!Q z1Xm?wvsDO8kyh(i&67^Q^TzdBp^e@*pKev%Fk-+7FI;|Kfx5|6S#bWUev&>Fml{E% zi(32QX=D8)f@4k#5z`Bk7xi|LR+U|}x{q53K3Z9r-7gCvmEY5=?8h_zO0wzA2(R1anN8Ys^w8*JYg(4GFDylO zeZ#ZO(^h5F`;MCnEM!ZU(O%lSAh|pE2;NxIzj3LcPQ|@T#m3J5hfDS6_Y?o#rTW*~ zjsHcL3c|(A!OivGdB2kF&#$ZglTXDCeYNwiFIfK2(kP;=LiJ41W_zx!j*~A>;kY2> z4QmRaRX?tLP8K3i-bG_t`&5Wo;?`5JuY@0`1Ff{ed7FlNVo5GWRB>7S<=A=aMGswn z$^eH~a0(gl{^Q;E#*}_r&)}4Sr_K4|6HbaiV^FzR^vT)sl zK{+P9tWO;LAo3|wTN+1i^|oC=XejctwF{U-Vrj5DcY$Nrn?=bJoRUJT*dJ-N>O02m zb>(_Hef{Hl7Csj_Zgoz`Fpj+Z2Zj=))s3wFc402%+igz|`kGurLaivLv7zI$ujinl zWe3Ju1@fD{4seIx@ptiFBAI?$UHy_Q&s)+#?CyjgJfv70d1V>Dp>SQ)hi<=SH66 zF0p-*c?ZOB;2y~se^C6qI{d^t`=g=+L1)J};_Re=&IVS6yk6J}x!Pw+=^+W|DB8qq zYPC5A{YyfdTx#kK_%L<}lVQ-SRQbFGbl$ zb5C{7UrkBqp}{_)Xs=}Chn4fQ6!zy97)AleaR<_3)y!A9jg)&M5*r>W80{w&z+@`I zLiDAwPHsh+K+7taX9BG%?#3{$2qgRw`~#NZL1quh&0{K|(alNW&oKH`O%o{eg0Ko} z1TfUwv(vxOMM=Y3P@x;^$jN3?4w_Iue-1wHr+Fl|HbG>YI<_k_+PO-u!gLEeInSGr z&5)_7P=XYDh3#0#mceL#~2A&vSI#sHJd6mD+v1>iinMH^IP+F55Y>ntbwQ}Y}F z!M9Z(MRlSX$ccfMGxT&6hozncpf2)E4<+B%#3U}lusS}Zq_m{6BdZ{CH%2x^WUExB z)YUk}kk)GItS~#)HQM*ERHn4ZNGxU$N#uuBQf0N<5+7o|N3;5!vifpfO=o?4t?vg; zx(il7=+&;rvMtJ#^l1)WS%sXBg&iw{O90@W-`vVrhz?`l+yvLsqbO+P@3yG;?OA{@ zD!w}tp1$rs-jy4TYm69okA^A>Cx#<)g-<4Ti=wM)sCm4=l73`i}XKNd90;^NqG|=h0^3HDZ$ytAOg1PI?fnnDuQ2cBD zK$~zKnGKZg?={G1d4y$Ue$k@~BI1OzgXJQ<#t;p=6u{B*dRN)Zs}W?r{`8!at?TEW zJMB8b+fN?9?uR(>kMeLzg5L|!ACryu=GMw-paK(UhFYTB?gXPz20w55n5=3vDgp@N zmU-ZiQ`5at9@$~rbr6Nb)L@K;ghXPVCfpohyF-aZ``Vn6%)C<98thZ> z8k_4(F@H9pfDHluTK*XB*@D|NyaQ9Fq6{t1llfiojP8d~>s+H_0ri%!?fp?fNN4Ej zy8{y+qD3ey6d^v9T-%mZgHBDm$(U<&{BV|MB_HNBju(uGoVb)=E%Cz&>;#LM*{GaU zT)pIA>Q^Z3s;bbHs?a59nZIJ^rqa9NnFi-ScPb=J+hcQ-EUNt{D_^!0>$9S)M z74{ZLW}Y8+a?cWopZ|%g#Gk+`ZWL~d{&>z#cnXC-VmJ@uzA?U`YHeW3A%!fdT?4ECzL%<^ zy5uW%Q@;?T*~P@mKEuP8h1Q7>>vvI10Rb!Wcd*>u1!IuTHagS&&#BUd{I4fX;cI31xJH#;Ffc$n=+4! zzRwHSuXBg7e;LnBLPr|JN^7^AeyJh5Rng;~+q1Zth_$KFxsl@HF9jZs4c*6GML97O zncdre*6poLxNt7{QyaZoCYzfJRbEJbRsN1+RM2kHH`n$;F*sReio2-_A_OUq=kFD|M) z%dnrg$@@U4$094o1wL+pWggiHy(Os6NAAoiC#laT=9BcntQ~1AX;C}x7H&1dtqkc1 zWe_l60czW}$FNF>JY#}kZ~}S$oprTsma7#@GxU@lKnO4d#mUsgeQA3Zff_RqwXUmg zlfvqgG9=%8e`V_BkKINm0vPR$u?saExf`KVzq-@j1eU_xDdS2HnsMXL81GW&V)qXc z6?o*wrWSLm+pd%p)5O#}`heMu>K=PVG!kj)jkTVHA-hecoacc||2DlfgmUFO)uDTa zVLRbI!?<-=xdP(!18O3g@s+EWGwJL^+~(oCjKhl(`CA>2!&+ z5Nk*YVbpm_X>EvgF>NoJ=7WjMe)Nu>J%#E<)KfX?X>#=}82mzRWeE~dw^*@;#ARc2zr7cxE~cVw0C^`MKM-F|6sfq(>jd9m7UGSj7OA03yB@v?=84}AtW}+ z`8CRUyEZWy`E3W+d2yvtB5~ncfgN(1E4{6W%DzU-mq_oF+B~}iMZe@MC%AT0Rx4+~ zZcMj9S^%)v=aP_&X%W|WBm~PXHa}IgoyKdD<%IL#hF02czwkNVw^UJa^qa124Y#jz zT}gTpHLp!2Y~}ew!^=m@%YID+PA;i|?gw??XIr>yUG$e2f%8==H=ijjM7nQe>y>8a z)oz=Gd!Dj6k%S8F(}^%(5xll4TaDC4c-5e7?>8M*LAvHdyzA^b{6Gbbf9=vObaX_( zxN#kij6*x{LXgK)zBSvVXSt|6EBT_>(l&&6B09c>wu(V;ZbcHNTWY&T?OR#?v5w(s zzrehTBX570a^s{V%pnSG%GOneX5et5}|Ic#ly$~0gTZ0TPj_x$Zg^r*sgl=DNTRjaXu zm9myQ(Iba9QQ5%{r8dqy#Su{jg6xD2#hMN0^g}k7#|SNISvN+gGVw>$FpZi0(97On z9nzv2dEx0^7}m1hjznKk3sPy_eF(5$JW5?AAEHdiz>FCgvSGc7oyAXjl{c zYv!(7rzc*XDjCZ2oTo~&LUFiHR=-g#QF{sUy2=?F*1V*;MJlxuN_R1gUiq04;wGtyDsuWms*E2ArJR51FWj&{Deb!G%7}FTb*1paBy|e{2~F zL3aIl$K_)07`uiyc35muVi&U4QpHBrwt}}(EHAEIVk2Xvc1xN+R0#TuzI(>3KMN}? z8JOR*d%IwtG8*#{J&z=xYA#T_bMnp1Gh{stv5Ao@*$Xk=X~{vvOouzT7@Qwx!`dl3 zuqsH1ywU{HCH_uHi<1J6JuWk8f>Dz^lS$2_e5hVJKbxJ{jUrWVG$a<1e7sOrGD|H& z>-x(7<&E0D@l=zj=(Zf)3cbgByY-WUaXA*|V_ty@zoeHt5j)QO(t-#w~~ft1zX-dYqXarOBZi`&+F-gQJo)F;0_S!w>-u~pndI(4$QNoA3DRiPz> z>PRpzM@DyjnUcL#G~)Hp_o}wxfBMV!4&%MQ%*n(3+g}FWWc|-Vc--87`Ie7Ayb05r z6#@26SqSl+ALxd=LGMmm*PXr1Mm(mh@L7OiVTvymVRp>TEH&$nMboAW$xgvEE1<~A`2>r^ zAtFG@HL4N}Zrcv)iTAOS()Cw$h#=F4V@?%cC)#c1d7rY-kR1EAw)ym}+gI5-wPYtl z_to-d1C_{k{OH755>l$ecRNSNqD&S>#2QH>*dr(vK{?{imR+z59FoN!KOcbY3RPZr zdRNjgm!h%b?ms4tSg&~|5UpHWRV-XW=$2;!hs`>47n-&bcnYr3*4(=EYiz{V8ioZY4_{#s%X{-ANU4gxrRQ zF6zvEW0SW1x=k6*`Z7=V=MB9C<~v8kJmDOsY#3H!wyTU8qs>H$1q{_nrXa_ZQ{W4Q zxe$9f!sX=3z}JWMaPQMwc^|6gS=6S(Yi%`68mY01G_V@Y@+V>c$kA&m&oR?5mZc=M zaHB7`7zzn1Q@YGx=&$On^cq?}xxHPxy1aSt=2q+F-+=g^K8@k|Hw?p@aKD2PME0aV zVB)~`2zc;s+>X;%R^Xqr_;}Zlr>@gxA$}q?rYV6@M}B6gU(BO!l90tKVfNKwSWk$_ zq_6M0%ogTtD_wTojBkQ#f$7U#$|AxmuKl1vgiH3mxGS5uC_qVX<5brAs z#P2VIZn%^6?o|Ek+>YW6?SyroJr^6sG+t!SwKJH%P_~s!iXS^9(5S!GUC{V|NL2UZ zBlQ_F;#ZtU|C1r`pTBVaCx$pV{=yKLjpG%oJS(RHD?5iOD;HRqm8(Kof^GRxh__me zCTj@^D{=;XAaWibd=`Bm1L}jFBh;n8q5kI&#Q%vpH|t-hbN1DserH8^JUFYw>f3U_ zb|spdcr&ddN_1TPFkMm#3`*A@_6Qr}ok%N}N|P{M%}RchLH%%%TWho+(Jsp?;%$X& zCj4c`lL7b$BEpcr;S2gP!hiCz1oywGQf~>AFWBz@UysoHdAG4M?M|)rmn39ip7Nvn zr9C>2E2rrbX2$t~sJTMt%1ZGQ~m4o$B)QeR-qyW4aB)R}i&_fJxEHX_Tj1l1j)1XC?>dz#F z91jM`P>uhF^6$4|{=e2JE}p;46}XH;37`yy#|$t+T77X(_qjmOr=G{yJrB!z-@o@^ z)Yqr{vPr@$f-S{rsb`X^V`hq=s2{HL+#&Pf11AQoguh|tKivx1S^vrnzdTPAEE`Jq z4N|gBQp_w^gShWjP;0a>J|k6BM7I>1IQydOCwJlbhs;+P4A%ubXl{ZQ*aP^xKlyYz z0t{QGbU)cFR3KXgkK4KO@BWbECvb~k?O#fb%;nlnLAThk3+Nv zNX8l-H`sM1t(ijv^DAAX0faY%D4c)_CQx%jkmlp2m`YsL07@3Vb%*Yo<2?2#Q%)IQ zhK#2g+{Ei*q=s?hnyCGPzQ{Gw>ab-sLN?gotY_MGSvSTfXO}nd1eMYie}l|_ya}^$ z{bio`BZaIUvmuC_*&{K_(|MD3z0JC;oAuI=9%g<~!f`$s$!mxZuCZ|JedqLwcVb1Dj=^dzF~ZK=wOHRNSn z@EX^0X>LuF4Ak6Cn0K-$BB<_J;RqC4ig_X1XelN z;{KZ+Bo;9%AZr3NYXl!35{sy*k&z)Zrvs3KK?B6W31TsMYhz+)1!A!=v@^9f0C8}G zSX>S5tU)Z+RzRu+2WM*#uz9l>0eKsM|E5lcAWoo@y`dA(hl?GF#TdxE0L{<HfeIn~D~$vb(2Ets!~x7N8xI8d z#|9*m05V8GFA+7g*S9mZaj>=nu|wB5Aaextw2ZEUo#}lF3T9ST=$Z`t{c!|zmDc?i zC3Yy!vbvUlK>r395{r_fp2K}w4`?n5@b63)ztB}RHE=Kiko+Uj#J@fkyJzC}LMvpi z4^45w!_EVsuWKV=XliWY02L0(HME6^9n5u~!NS-c1O_1c4~70e@GA)r>1mR)_LBJe9BY+4u_`Y!8a|J;HLzw{zlYeHa0HEeHTEc-|B+|?G7!_?)L@Eb1&N;L;X5{G6)@ll?UJqDn67efXm;S z0M&r|i34sSXbpwyHzU7B;DU<8b&nrZ6aE+g*D-~XW6aIXkZW%#$k#>&kJj0F(>muCE~e{06?`j=|`(hR6p{G|Z2?|-wgBSAIf zcez&%pbf&tbFTPxvw?h@+cY!Jg zpg>5_TI-KR;?HK34Cvmc2NELbf!LuNH*j>nHL(AB3HR4-!G0eF2mP@_0PExZ%Kfhm z=iY<|I+}yPzn0hg4F`O`y#KKq0e92==)d+G0P*_~pqmmfPxmeNdlfLH&>#PMO#?jj z|I89*=YaghoRCqdvlL}R*_y-AoPV%o{x%s|QR~!NqzfUk8I;OGmrad#+Af8%0Iz}G zu>9ebh}RQAwrwyYf7kM;;A%~mGEM_-UP7EazTU!(3G6pK2Nnv3Zuq$fLlpb|v-xz4 zSREP;ov+rCH26Qhfeo62Q^Q+?5|jy?WpEe^ar?lXJ1UUUXJsG@7i#Rq_6MS{llYN+ zI_d9AK1H_KJ;_0edaSN9zCo-I>dO#4hUkzs)>_*;pTBnM1QB65oX@Fs@j%&=XWWF4Chx}14lQ=xU`z||I^w4 z)|3AXKj1C_Q2*nVYq9rrP)|bCElUU1lg228_EVV`G3e!tja;o;^)oDXrCHs8K-gpy z#sH-QxcGD(&gvJ6VM*KR#a7ymKC7-u`6p-a^m0y4w)}lPgvWow*PpGRfAS;Pfg9w{ zj4>(jM8OCl^sM2!3fqtDmGpc#yW2qOe&`n<0(!<|E8i}M5yLQh*!ik_VK1Jb$+;RPFS~bb2%e< zb_RUguGYs&juV~nEpl1!k#{r)P=WCMm?1$%!l(B4?!3rk+A9c3h7}a zZJrxFlu5d;D9uo=G^M7;?XmlbIC$~$`FJwLRTF!<+K?IGZ@%??7gHw6=fl9VX`B|h zN!(tB%nsL-wH=?ou`m6`imP_8T0tBsQ*jPqSv==o+Pb)g$;s5f`x^lNd>{WKfIt$l zKLf}q--9XwJhCxH!pp&V~Psf z%Q!j+5U|Cb@VynwvRNz}bN<1BHEM(`8}qPGR`5OA109Mtuf4YmMR}x#!!uK?zjd6U zKYyT9{y(7sHmLut^M7Yy|Jk?(Y_0pH=nvBt>R$evas4-zG+A}Ro1qQJ}fQ^!k9atCtr)dnV=l4AQznjMYkyQ*>Jbztu@9F=Stm6Npy#H<$ z1L^VpY!CyP>HaW?!N4l^e`65e3kH?r{|5#!@U9jI;M#C-{W4|%;{}NaYF+~CE<0ct zfO!Bb3n;&h9WZb`n2QbAQh^$f18VI2LqYo82E7(qeivLThL{)S3kHY(Rki z&@p+q0Skxw*Ewi?FANy4uK|Iej6j8g7A_zS2edCIAo#B_fNKG|_s4)uzz!He(83Af zxvzNubBzmXodK5B|0?ZEz`1&&zm-U$P)M?7$?m(^BM~7xrNzE)*<}|+No32u6`@Y}jnP=vnJ2Q9YoO5U9%$(2tZsvg&nJ~0ffdIRx z&^;80c>t537#%jhxABi@=*1EAY>0s%1`Nf8o{0iwb}ccX2ErgsgPsJL6lgORZ2&=C zgR0mpj+O~j90Xj{mdyTDwV41~zgYz^Z=hl*s8yilkT@YV*cR7z3`B;z%_VdV;Jb@Z zx6$l_^x$9pP%fxXXk`L5q4~O{98m4x8W(+Us{&rI9kv}HMcC8w{!r~gFS&4*b8XA084+a9bsE1 zwquAXK<>Ec7)tL5XjyOGhw}UjkX}Gih2nn;Vf4ViJ; zg)2wP2SZDzEJ=w^ruRnL{>iLz-tfs}%MkzGb<_9f#rs(wLIkK*u0M{XH`JO?kok&y z!!;9K2ouZj%2T4eqiXgorfxJeJX@MAtyB4whLfzlIMIFVL`f_LEK%)fOpC}i8;sK` z-!k%+7Kv`CGQ4p*@h0V2?)e9nHr<4}^Kba8XFfjXp_&{!D)&n|ab!@~na!dI^+OBa z<;m%M8_)UKH03Okpgcd-%3x2eX%aJu&y^pJTt%upDKj}nM)Wr!k@FX}7iqwA{Q{v( zx9?NlSCx{R%1A}=O~)J0I*d~P(k8ll^m7wu7Od_VwM^&u(b#}_?5DI>*qVD9a!Q@f z4bb-!Ia`|Qz03a?6X~QR$-;G|tD~jIaF*qH{D8x4rw#$C;*HafZ8P^z`(RM{Z`%J~ z1p$Vboq~{7bdYgby&4P$;y zvy_uP(UY_~g^f`fZyJq_oHH+GkrhZwx_|Ma6xYe-d)eN~to@^h)^bq|HiTQBieydq z)JvQ7s?uG{sdNaXxXI`Hplc?`#OJH{tsnRPw1h`CUVeYaSlgJMKlx%D?=p)*Ri}*V zXNGuod5`ZSl#Di5Bj@CE`32k46{|e>Z_+s^U$(Of38|AYQWARBkN=iSp6t^VY#QHD z+vV}!!y@DKCm5ZaMS5oJC1ToUgvycemkto&p{+eIg6|Tcyu|%-PP~u6Dsa!~nvrPw zR=1Hs|I$#tyHy95S05zHmm#d5(eXNw;X12e)xWcCZY`hnnDr`J7tEv$5xXD!{Ud zX}*@5E7FxFja<#B?OKmxa#-fbI{v4#Og~W&)8wM|aYr|DmOF~gS{?#^x@iP!UMi1> z?X>aLUJqT$M>>*U5J|~?+%12ufG%{@x=J{8NQ3DyxyQ{AU)Cq0OOD zP7hiCO8$@tsfsK=Q!4Kqy|C`s-L|-f`I<(Z`T!;#*5reub|3Pg{H5-LWAI0tJMe{9 zEu)hQCfD-T`frgEMiXd9B=cpJXE+&N_oz+}FmqltiLIGAb4!>>LR;MYg42kzk*dVv zE00N~2Q#O>3`!b$kp%uGRE~Qe;!R<|_sqq4VnxN-kCM2naP(~t-n0?x9i5OD$25>W zw;5{mi9C4yIuoK0xf_p=kE}DF4ik`fNOU}YhgY4XH^eqg@-2unW};P-y#AM{k6j(5 zuzGxzdjH*D+#}APUklU8X4XuOBPG_0=)LSR>!O2{x*5scBam!DEv9_2)LMG5g#ND- zUhy$+8A-=zOVm3$YrRB0{7hdzS{HYXi4mI8zUO%W7Y}Wqg4MxJRlFvjZ&SgEH+dOL zoWRVGatu0w!~815;UhecLGw;Y*Na{-AFYU4YJ^jiTgfrsKzg%Kca1!>dn! zvfW4Mcw|3nlM|MaPd*Y)$Qm$0MZI>97f15>lnYq{!31-2YWjmHBl997MLf5OP_ydT z1}`p#rrRuf+21=b)8S`0LnzppWrs8Ku42(LyQ>l0e-=k^x|b;CQft_y^Y8rwp1Bq- ze9F?$SPBi*ps!@87md#dei)6{-mK`xeEK+fFOKR!Qc@FxAZ3v+h4zmz%B6d+SOr5Y z5*@9M&MaY(OhJia@O8l7E7KF8TTlhH&DO+S3l;$ucYr9 zV=Z$T6ZxN9k5~XVw*$C*SSuC@Cgh!5W($gA~nA&cNN(_-0S&f-!1OJ!EoPLxY7G1`V*Y}kEz=QU$T zTU|>8Pq(hMAB|5}t?Ok@q{hxfurc5GIe3qD4qm%n)XV3@A;pY|YtOI$O^<-)j?758 zXXmx*k0i7KhJ-D_U!MN{o;g@jmP{PZkzh+Z?_SUez9F4GmhfEXLZ4>7$LOHwcdrD! zpr3+2|4a+=Dq(t)_f$DzGYWB`GCPULGOCUaei*1ACc&x>U?^%2xnX2)sbUa_JCq@Y z!hP_ZG_R)5ezevrQrSd%$yvMT!McEizWwd*?qO0nTB-R`UF08s)#}eY49v>8ry-7{ z=~%Lz>yGNG{un3X$lc&8b459Iso2`rk8?RPLvOBAX(Pzrwy-Z;8S`FOxFWMIMmY7? z;acHSO7MGRxN+$^)J1gnU&irX1967fzn8EVaP= z#rwwP@4Lv(+ZkrZgl~2k9H|b>_VaES%6q|zN}%yDC&6TW){{EIzk(m?a!#EjW^7F8 zn(*7j161J9N2$On*{K4T<*R+bn7@(;cDo_lRhyuKdb{ zLRLRPKh&&tNYYsOSk~XHCv}?q_FSwa-A~KR)uS53yGVnYf8K47}F%gNe<*> zp3G$II?0kJnduU|#S#R4#@|oHs4m~mHDz3LWc5ry`R7dyG zrC#shv!eqt6}SbI>@Sfz@GJmD>L6+E&(tF=BD5lZ zt(q;~n^89vSF=5Uk%v8bMS^Ylos47)to5gZ;fT)YVx7A2cv&(lk?}Xzy84pv;+t1k zlJGOi>GV)nXv?KecZ%@9cdqP zCLr{6bW=U@e1t#In^|F{t@;p{Oqvg;!!8wQeVt7pH-+i_6)VA7{D?E!|GKY>rOCnZ zd6&$KM+@OYY>Be$0ADcBMx2%PqyA*TYm?`k=Yo&_E)}|STPFVK??}$n*&aLA#c+qK zxKTyZbTKM?sdOTF(Lp+%0~(RGxoyNbCE^)z6RA&d8^}#IC`a1HZ}wgh0$=T18=RX` ziOXVr6gY=8DO4I|=HY8`82SJs>r%Xct#YIjrD9i#n7}GYv>zwXIX0d&&3ga1@6t+) z?z=ZGg|Nx~GspV7ndp%1&kWB2OL$H)I=0wa|dv3 zj$=~2@D#D{#g=F%`l9)vTB{Z3H0P>=7ALp0CZqE5f?R)WyJ)OR>$y}P0;NSomktbV z6q`@GD^Wyz#=8H6yUisHGa@YiD}LUJ-$+J=&sk#MLF7cA*O_q$!@67VZmMOSTKTDY zg71y31(sR(wVWsJU2dcw;pfucOyfE-DMTdPGF3q@u)@`axfO-@F#GP z%JSoPxy*iI9o2OFa+03wMe#B0bB&*j2{0L>!ee#u6dAubc{-fZsO>y%uFPM@${X68 z6K2Ce%rtU|dob!ViGg2@{GdSXkc-{~Cv0?<&w05S+o8#*d1ypKeDa%CwWOzOt_7#e zYqCbH`Grr85rX_f!a)sh7uxH2N_6bMXyAYP8%I99vEi)VS4_8|u5|z>4{J1o-Kw38 zl=eX%OJG6A5`x%On|@d4G_knN%>^_?uV2cQeDBsvVdjbQCj1l|{_zB#3@$$n(Y5Y$ zQ}54SU47ra90{ArqN=-Qg_By-sOdTsMKM5nP@VnFk!w z-YIcramqnXX)xid`S;}VFA!kTg_U6`24miOS@seeV}<$@(E(3CtPunQr*u1+b6E!3 z*~cr;#}!KwqT!g&o?tTDFwRW9`OL%}V`%a-=6#f%n{}bd2m7**P0>8+HE$xXKXRl# z+Bon^c7iaM|8x55+nFPO*_!lqW~#INo-+NgjMvU=Mm?|!GN_i*FuN{Np~#+LN6&fl zPiTt-%Vdhp~gGy@1&R@%8((4&0w&7}7 z8M#N>EqP&KWicpK=1#>=zLymOG^dM>w-{6Kshbw@6NGDXz9;ye!-O}q(lMpwC2m!T=A-|6~HK*Wo~9{Mo8#-3C#iOacBbz>^|;N4+VZp z;3zh^boRoLi?d?_)$yI(#XgT2Gup3dUlIGP{H@z>RhhMRTX#Xjc2MY43P zm?ZC6tyD~cNv9^=sA|KoMbE^t6CxbBYD&#cNpb4I0NTUFOz!jA1QXlP+umBBddCj;+#^jm;m z#G3eIQ&9iW4^Lt_(s<+)E_6K03BSqOe|gN+ps2+%nJFQsmbHids>}_cKgE*tvDwyc z2onqZ1*0EW$L8a|GJ8LZzo(feyk^wfxMB|s+HOk=?gRLJSW^oD&d+x88x@dmK?lRT zw&r{EMA9=JiAqFDj_v$|r6X))swD(5{Xz_F0rcr}Z`kE&a-=>j{^9-8Rv%E@C?S7l zvDAp7I;c@QRYx7h(PUFT_f%}5pS3Bv`z(SzjUe^%nd7%s2Tu|he!o3xf`fJXbJ&8| z#8^}Jx8y9Jb@LIvM?8bJf65=^5p{0}^jrxQWTVf}S^U+zK%T&$%js!zZE?LQKD@D} zsgJeb^9lT(eD?|pSq9BD?9*p!j)u%#IFZ5U*N~(+*Rf^0oQfR0Zo^J17vep8wdt=n|I1a+OHNL6NZBYAs1-fj=28y zvh4i15w1_pmG47#>@+_DrkoIRsYAo4sOj#rj`VI_WI(bt@q&PyGsY;MUuU(7?~3sI zk*Qa&9QooG>2lv0T{N^*v62lqZ>zf+S9HUlE=m7`uB&wbORsSAZ|Cd%0mrP~#*&m@ zHgUp{RQZJ6ca5eISNR17+*n~jbz~kZDqHm70lhn{VFCwd5<7c`QsA`&%ci<9Vy6=2 zuMg>Z5$yWwt`pd4m@nIf7b+4`l9mHFth|Vc?v8X(ic0@k>F=(|q{~{qNnbeZT)5nA zX1@e_4(d!lk)p1y^rg9j$2!5qN*IkAC$`?vRC_yF-!xxFzT@!==&wz ztyN+)1m%kw8>#fT3^op6@?nhu*q$X7@JJ>CDm1wSwoYLoYti-bmg{|D?*fs*Vj48F zFiwKfssvj2Y=D$Lat(O~6{&ak72>vgN(tuD8`f|U>DVJS72Whtv=#2)-hP*fJDsZM z7s>D_bp28Al9Sx%C0gq@-a*FBAxRQ`O6Ppw18Q>tcZ7pq;lI5Y(qPizqSH&mPY*N=!| z9KeFZF3)*(!+)gfx4h<~nOu(HxwUV3^PlPXAyc@V7g$Q*$zON2l{x*Yh1@LxI@=qI z$^N#@3a&NQtM?_0)eDF*Z)f@4zQLwbwsury=0fiQ4Lj^=7Xc2zcD?|Y6{IY|N~mjz z$=XdR?1hhWv`qa({aT*CIkWeD&PwXXT2y$$B_UW^3|ZKpex7(R%(uKDig%1d=*4>5 zeB3Z5hxmm@vf4gAOBO=cW6Y!BM7bHxRH=pj6*YBPWZ5Fz5{-ByPW6Ozk@wU?(cC5=`SKpoa^f>5}7Ong8)4$HNq*Ko+zqJ-}NpjCUrOtXs8bkLq zz(W5m!NqnQ89FHny#eo^pCeFI9l^1`eGHHcp~Ol(Vx>4XvsRJK8_w-da&f(g)+*cU zYz1HV$t1oXY-4I^=Q;W2i7#&ipKs$?%ORxr#gjDNUo9Ak2N{~Q9gK?2vv?jv%$=e# ziIVvIP9`r}d`24OnKY)=dVjDz#JZiAwl?21M>fra{Fl+?iVqCmg&UY}B##(8T#&-E z;(1~r-5h0VT-z`tc1Pyk2PxL~rR<{yI9k=ig#pUF6)(s;o)Lt`hp^R%RG;Y7)G>-l ztyo*HUY%cEIdYrt#mD_(1k2RJnFTO#F1t&NKKb}%SMZKm-OR+t>32tWJ(nh#arssUfuF9`rxnRLDY2_w7?`c_HH4ulZ+n5f!74 z>wAdbFX@EQh7L785FpfH*2xXd@?{P8sQ!Q=9-}-Fg+0L1F-2ceIAB95@8nB9pgX3Q zD{Th8UC-@X%BO06$4d!*_W_6btvghco<^_fiejmSZs?a}pD#o2z!agqN0He$0FbM=zG1R?F6W4`|Ff1dT` zmMkoP@mv==SHWJE$|ZQ`YS5EEVcaS{jxy?&D_jQI9!gZJKF*h#Wa(S&3R*wN>IyOn zc$S3pO**UfZ5(m6aZWoxJcqT8fCunS=^)@Jxho}SMc6UUOC23Mpx(nSt6{)%VQ0nC zep2_rakR*iAQlHf$={AFzf4KgWxpI`kJn-pb*beuT4yVdD0B;) zCOqcL@+9$Fq+331kKuWlNA=PLiZ;FviW=-*WKdZRi|8J}hC{D*0is|h8^CHe?Ho9j zpHFkgKSv;&HgS7M+;$_Giis!O{}Lra3G9Vt4~Gf8use*W6)KHDBy|MNsMB>K@w(?d!|q?gZNUSWNP^0#Dt-S~r2wLXEdAyzKZt73*>Ig)T3yAYTlMfdKvsuc{lfR)cG>); z0*=vuZMA6ki(hVCmX)nb`3sJKRNh~Km)tm0$E*7cOFUjOEr5#RmFlwZU01&302Ia# ztvhmDnp*m``YLR{RJ0tQ#T4?6Hyb`qY4MM=us2NQk0cW}Nzq9jcbL~tDl&+OCk>&q zl|NnudoCw&^oRS~cBbNTWO6W{i+E-z_k8;^?+YiD?{?>h*AhWpRu>Cm)FqNsE>Y!PL$yJ;;K^y2gvUZ4LHK5P{>(N=5tol;}q zG6QaAI;s95>*pyW&w1iR{b@7fh1HEtgv$oTfY>d?12}i+l{N6*+NtH&${l?5Ij7e=m3Wh`BZfsaK@<+K$<(mhx%&Jr9MRw5zt6T0E-#RJE`fi`M@oaSK zP5M^edsPyAclmDz8RbRVyDTaW;o+7k^!>PH^D!&Ce1w^<36*PFIi;Hj}YTz0FND{*^yJ zMyUwOTz^BW9E}JwZy}6#(I3nb=ej=5KxUdsARQdIOt=X_LdL}9?->pMm5uh=BG zWfZE(oo^`Xb${_~=tnr}J;u1UUSVo_U5mY%>hnoGMRE8tHCQs9p5|1G8th2o`VLjX7)90E4M zI00H?zuz!G&-_364dZS>>i#Ez90FMfn7rGE7~Pg__qr`)9S`uo+kvd(0`8?duyruN zLh$d<2Vm>|=gx0B5g*)c+}#evI}vse4-e~53@}}|V3^qU_S>GT?gFn_$cy&>JK+Am z)&U0&ZwTN&jsh!~E#FZHV+Xm1BGB%$&`op(KtloJWxD_rqup#F`oZC!Gb(idUp=4> zs2+3xbY3ukasvb<7eI|c@pc+=_uTFj0{nvkR0nho<>LkZljywA^>#i`76lIXch-aM z$j(YZBXFTcqdNo)`0a+FI{*qJLB&udQ2ejc;QC*gtu(|OkZ-etfcCEp@L@)mgJ@8L zp+KsNZ3n3QwvhJ5|0D>Bbt~XPF}fpAXSTw>f`FsjEZL5s z#-h_(>h&)#_=+o}K9KabI=nB2@{?DU$ z=l+u@z-^+3L@-wXj-efhZvdC^&6F(Aq0N*WHSoei-_-;x-%O#Q+31mcbM^rbLg&x} zg4s%;@!ROx5zICaq#Mi+=sa7XJoFJJ@L4tiZy9t07tBNe35(7G@ZMXG+?>_6p1Nc1 z1lUY;PBS35trRrIKTVMF+0d0EmFjV++l%=oA_j2r%i;#ec)_E+ZF4jmFf2-iiT8?N)2V5CAZ{ zr_@fHP#6Ya^k6m;26?t2Ja*RNiq-%GPtBnX=5pw99K!JJY_R`1+m429PYtgIiw7AAdEl2aY0N#|CK3-Hu(dvr4aES3`tH?AAAsC z$5VFdqzDA@H#EC13ia`lC?A{?tR{Fk0a72Jb~)KNxfwY*8JTc7(D?vF|B|VuwYiCz zwTYn?HG&<^4riq{u(memRvy8cp9<`RHwlSDHH_J2a zXqla*t{yIUyLoZJoVE1>$P*M;#_3W2qe0z-e$@B3Xb1!nQlC9E$l+oy4gCM>J{l5Y z;-0cd2)4SH2ECrUXy5{REB4S3ynz3EXmGIf+e1U3z$dZx(s;lw;a(aL#9kVJI`8EH zCpUzU*;AGq0niw`X#l|jy*beDAO8SAn|JSXK|X-|*pm+lfztQTxVfM)1p56~A2$Sg z-%I0!#-H8!0P=sY++auujkG5pk_TEk?kSEJMHl#wyQok90{=dduiPJcnSxv^j==U4;T;N2;P0~8yvjmd)o}K#jt(P1*ool z?L(pVw;9E?U%ueA-1iI=5a!;#aY2i#J^kh4-8XK)0f1^>K5o=L8G)6|zHtc714HfA z131tAF%ixKUh2JV0ixXZTwVmQGxoF@tmgOeikBOF-eY$@1Q7XNJ|j4h`}7&ux4<=Z zPg(HT9W-!4YG|Tsi3`o$68H7MiUD*I0%s|hnE~5+Gp%UopbMGiU>dZt*0i)nPc;By P$H{|BPk&8T4EO&4EZiXz diff --git a/output/examples/BRCA_example_RS32_counts.pdf b/output/examples/BRCA_example_RS32_counts.pdf deleted file mode 100644 index a80c4ce8f7854c08a2d9918d85a4144962e8f776..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30756 zcmd43by!y0w>GSj64D_dNJ>BO&?(a04bt5$El77sw{&-Rij+u)w6xM)-+FMnkNbD_ z+24NO>;27W(4x$dE%l*1V&;Iv9+EV0yj4? zgRHKxp*=AZ@QXY#gQAO#Au)r1u7j?HwJ|X-FM^?!0i+@OZyki*IEW}X=sFk@Gym)) zY;EO04E}j8tLxxkXlF&t0=YzBkhQbcS1@!S)&Ry46b9rQzHuOC5VHiveD%js;E$si zu@*6df{Ctysg*G?>(B10GJ0l)`VPcw_rm{69YzrF!>1r7DB4S)rZG_*2yFaZXI2!V98cd#?mwM2N6GNdUL zK~RU*a#m(S9KS{!taM#0@qkO(7uqH=0>%#B&Zf8q-I%;9TL12*d3)w*G|Sh1>Zfo9S1mmWHeVe40 zIljGQgNaQF8C8^6Jd;F~U#ZmU1F2!3w{IvfVQU$$jg*!$4!nbXV{2GAqmDn53yo}- zGxiH*U$;OT_})b84$;0>^ok>TH&(z265K zL=LJ*tyO~2wnlO4XdgP+T7HZwiGCJ6F&N(h)ZrieMpnh(EmpF85>bjC^6t4W zpAi{EdvZG}gW-qIpJ?A~Qj>EQZxJh}10c$viLB`(z%y*0NI6W5RlQ01_TeP}%u9GP z%~HlLP+z1~ho}m+iau?R`1pP*Il|}`;XbObE>xL$wmCJuyq_BLJ?KmvqN^OP1>XP& zV7#JU_TM)yT*+dP3}m!xZj8d#i?>4MlS%K?`!w9``E`M?)l!KnGY|0=GH~d zN6g*L7}=Ux`^7Yll*KD4)(0rGCvu0*{;G`3%6UhZ~eyh4@A7j{+g zA(Oy$UZ!ZB9gbE#zqsp18-RI^AJC270W#Z-vm4^yqI0i)lRY<;c*Pl00JT1Sj%$q& z=Yl4wmp{QY->EX!5ZEBC-hpHryz*3l;gh$7qyul$_s$tj_;7ZO%CepXI>Q#j$RY;+ z0qoX=;U0pB9i||=4(nswB7P%l2RJ613}Kb0s+2*Qz)m9D^B=NI^n zG%^aB@0^-za2S?xGWxO`v2XJ3Sm$f?V99;cR8xfF#6EaII(y_S#s-T->*b>FnjhVD zmnu9@BoS^>#wd=IjeqP&<~~WFlzQR6XP9ViA(?Ob)at$+HzB*u#kL+#=|p)#seY8< z!uFs?YXA7dqpbc;taq$~XlI=mVGDv#$q;pa9E}Z++fzT28ke=J9nlceHfD0neT+#! zY7p-4GOo(1fZk<;0YLC--7lio1<&26+{AnqWbFvc=f>pN&TZnvK-BTWw_48 zdAm#{5qm)?#+H$!3m>PQJTMlyjn2I#713p9zA*6L!nGWxtr?<~gNVum68mv30V1Q&t-eARpz5*JI@B2w(VktA z${>RtxBxn=KIiUduqhunr8p|>c4xN^Gy*L`%IM{gJLaF$@#i(KnQ=J18OgEUc*?;m zVSpI3(ri=d>@86k4%*b?IIVAg+Zhq(=QbrBuxMqVVP~_A8fo}i*P6X+7H=IHB`J^a zrHZru)bLwKt#8UY-kUChz6Qhvd!|7*&BCLK*v8_W($r^dUq9AHuPbyGRSc4@(J%@R zG(((nqi1ZVb`Qo5l*H(WsBxiAa!QOu91A%^tj zs-erO>kx~rBbdqR?zr-^WkMO{s3+@*(VbpJl0kH9+Kx$Uy&q6n)gHTmVt^Zs6}F;o zkjq_Xq2|b9kk8ZrQDIXD%Ds9}qDNhfpZ4h4-thO#)D6xNK3#*57Zb}i>pE{@&OoYU zrtZm`x=lJQIUaf%huH;h87ptPeNZ}-9_OTtZX#Tgb26V;n4bk5&|MT?m}ri)<}Met z%eC`6_I|)B7k0PF-O0>gVZls!qk}tCHAdM27etpkq7K${k7KM6PhSzN?>X0v=I7*w z9l|+q$2B)MZjXmQRMvoQxtHqLxOk z)fuM8I5<75r745&$9mxxr5`WI6AQjvUu7la4YdgwHC^jc2Rq9uU%d(~p?dIeXCXAR zE1bYh7!Gb)EHAaod1=LjBdp_k3O) zC63$+Z{|P<`Uqp05$S0uFY0c|8LAu7_|KeFI)BxY+f^Kc^03{ zIrGh`2N-lDERAR2QD(lGoVqGoC^>U-^&W%sh&l}Fo~02gwm#*KQj@Tw9Afbz0s9<5 z!Lhk{wC9%9-&vbQN=;A-pDQp9lD)RSt6=&>6?CYAa(BDmb#rw!RpdA)VR*Z5H6?p? zw%Fokt9+-!@S2WwHNn@J*ycJ~6Z<9u--P|#{Gy_S&)pm9Z7ZkYSE;*)8s;Ip5KrZg zUGg73%l+;dvdv~*YKtW!d}up~#cfau)EtGeg#NW$&OnRYQl+iR~IyQ%ad`08ECK#UhE zp&porj~w0gy@P#Ksa3xzZd2oB3DZ@*g!ZeA$md3!*eRpP6m#9wDFCKB8K!ofdr2 zbB$@i%!!Y_ZgY$Pi1Ay3Wf}dbD0mcRS#9*hx8+p}Cm`1G$GJxaI$xkB&nX`Tnf{|1R;5alaOpEp@3rOIylu7s1DZ$;M%$FshcRlFI z)5(rmi-dkw6=TxQ7AHzo{es+Xz|Yz$8>3K|oqwj^-j_`|Z~bN1)65Kb3RE%Fvf;)s zCN=wfA0=j*v1LoZai}n_74)&~uUiBh2Y!u#?KO^0{DBzr{Njek#Sy%IB{XbLN=&ev zAhQor?@d!P6ADFGJg(JHS@svFu23*;2h?FyF;UCUFIVfDv(_SydmsSsHFytzI6<^g ze=w?uRjcEBbg1=e)-stsw#mHec1cF6&Jb5O3@ytuTHh9TY?JmnEO>sYk1R&G>-k$$ zxLee8)qy1SULV?_}$|_fn^q?7Al5 z{eVLGXkd(GWbm6H&ejS+p{2Jq@*n6*@aHxs(Z$({Df6WJ01#_rMKyv-)=vR@h!M?) z&*+CKTJ;N4z!n8rihoOC?{l{YTgo6ks_1qlk!vfj5mb5=o1!OfvC+oHjd*GMSZXR> zxIY`>IE<^4s(!Pxj>~*xS?mL!qG*wUTOsE6aPcJ!bC6JsPJsEBdJGavTHo0!y&>e$ z1+wn9d}*kSZlOjc9l;foWMr{BHxv%CdMbj-LH3Q0itXk`$agV<6CZ0qfTKCG5_MPRM@HEh5KnXOwAPb<6E=|u+} zTPn`7(6t3mQ*)=xolJNFec-fUOf|g!=&QO|bL9_ptNQWAjrxg>v{m&?I^j>zR_~NSucGxx`KLl`BhfL^!>!tE9oc+HYvUwq&b#C*Fy3hvu+x)< zKcRMdY}RX=Z`@7v@c_i201kJ+ZBPim>7DpmPis_GFMcGFruWDF!pc?8V&hJtYH^L6 z8>T9`6ieiTmWG3(>Ua)D1O2BU5#}sV-w;@YyA)J23U2dFFWJaE4SI6g)9ZBSC2w&} z_RMH2$b&OZt&b^$25NoiFh-#`yg@xXb(x*hpOikXG~msrK$Hoj{Vw5a6GLo?o6l~D z26Nj&P4ffA`iVX7)v)KB^!YKjT{NJ>GOplBgDanC5nr^|1qAFRh#(q(^VSn0*dKA!I8Yq<_qhsR^ACm)NFFh{4C;(-RO>Gc zNWMN@`Si9y-3)L(jMMf76bjNV-lF(h6tAnFmaJd#t@6+D8s%c^=I_1Yj0Lz>!IMS2=^Yw z8;K3W_nf*C>?H2P9n@B^kiL)DjpJ!L=&U5GwU`mU?WTDyDD}7s%=Ls&#g9b2I%$!6 z9K4LO`Z?90Pq+TTlb%y;=1nFW`L0)4n&bAH_3Ew}@)$=U0j?C+-nWNJS?YpInauWC zTG67k9bY!5Z3zxWRd9D2l28uv;83#kjB-8ou>zR zs1u#p(70i1C~qYSy+^lJIG&udzt-nbnR`scQb?!vjsto(QDqvxzq~g50&>U5a1_#o zy~}wTsUQBG`$ZI4pG`O1nN{&RCEA2?t)TchbDFd78}i;w7nE}ouRd2#JUPp-IHH;C zM$OG6^FXv@RmVX%cW!fnorW(@*GNTbYE*xG=v_%wrj7Sn_>NSrf1g&!s$F}BW$4;cb^D>nh z>J2;ymAj6|5@i|B%}M#Zi39yQFw2}{kN&tY7g3|TR&wUc=j=3h!FOhem=#i~``#;D}6L|E8Z1!@7o+_OlQ*@H|qQpZnEy>YI`L5kQ-Kj`>yy(&7 z=Nwa;Y`Zh`)S}_@_8fV%&SIF-JPkV(Z;fj~eAB{oJAo!?Rl?SSXYP#3JeAY(aL?BU z&CTUGnD7V6m{~+;Qppd~UEc(aR&0!E+UHRk&%JWDjJU-*S~$^d&#R?B`QC~`#8EX| z7tBtg@zI;7yTyccNuem-^MYYK+`iVr#%;-HZEz-9yo6*3CzV z(z_FZdspRGW|Q0jd6V?^_za;Z;Vh}uXXWGMPg^a8^7gV%{5J&Z5QTN6wPx!Mx7 z+JD$EzsqHnfhH*5TDF6dUSTAzO)&O7?(RVlS#Z+dxFC>C_`M6l!N~ll3jzsl{My3* zy$kY3^yGi33j)#Zm;V3gg8Uh_`RDKjjrbqo3lI>#c#m!fgfB>e@I}&n_+prvYYvPE ze~Otb)Y_+4QP|XI>d7{G?R0v?b$w-eYjn%?D}0d(gfG(n2w&{|3SUHC9c=LBZ4Dh? z)8t?HT9xG%M29H3@p~8fQPV4Y%VZxB_M93J2n&~=9*9tf-LfhtTF-g@F>g&ig(GD3 z(^22th4oRu#f3^Sc=ZD1CBktj>vhbE*X`lyQCn-%%|H>(k#jml@Pg1mT5zIg3<^fl zE$5BP?J_9XdHEc!(edT>=CdU2#G*VLwxgrPQAw9p7pQ1cPvOm+5Mtg-k_y)(eLFvS z*yH50Cc`Edo}1{jsJk;hPnN~zWG}a>xQJc*Ao$Xi)Crd+d#+_NDpk6b zkxNr^Jq5$b`K9>-6+PrlbI=;whZim?X7oMs<7@Z|(2AfeJf6p_?3(f?aar2dA7u*Y z4H#w)$JX$V6lUH>yYD}rvT>m#bhkrCCl`>VT#Wk_zR-Rb(QBaPgDf&28)H3)+WANL zqLcTJ@Wn3kMepvK?|zZN9*p!Qp1VW-#Pg*WwEkHXiwPtTsr-W5eF`<_MMOS@Lp^@# z$$3$GP0Z}5CP3Uiv~|eK+4~mj(;6MWR4XHY1<6+de*v3ecVuZ!Y`aWXY{;}F<-8|E zeenkcPdcSJ#T}!|&Eiri7UKxJ`QY2k#G&CZ%R0m;hv^wfj0EH;7Zb9UQU&Rw$Z#6# zW29xn96F5!M&z0qxmdUu1Vv#Ibzi0tYB;T1CiFjV`ZO&>3YKc719PBDONpgb&|e$| zs0@$7L=hnIh#d4DuWeKN(IV|(lrC?6dL=EMFX^8NnNUAFSfb>k99r`0(@knJS$UqP zPQa9Qi8t(`XX4wl7xoWDRDyas&`6$vF+>z!SUnJB6nurrflFruQUto=%zA|NXu^Yq zz2INri}w5QMXs=`0wjFFwp{2gH&R-<-*Xp)w(b)eCZHGe5|_nMqG3H_-|0=Yi|^c7 z;uUYq7Svk#n?W|1kY;#n#&I*W(tey1ZiEJU^$r9`_(Fjp7!tl{Y`hO>Dtc!WXoL zE&4$C0#<@@>Pu~8AuoOX&I!_?h#vQ}A$rdy3XOAcg%*1F<-EXEXQ;Hwsg?@i!zSxe73OFEDvpVD5gi+F!xXCHzUo_|+OSn$$JY9>J z&5^(HOx~gnZ|xmxX{u>&~1eYRxwL8z5Nd;CcCZVlyDXbNyZ zG#zf(pA{c>^ATPRdZhOsKeQXYT*EBlf5tpE3{QaE$#PMd)>nElIwGlljrPMM@>y|F zTEodb7GNpwntfcCe4$bfX6$&nLzauIG!c@;=lkW_JTb4@)~kb?e>Q|#6Wa+AsBwmU zm)q-`hOHZe!doW|@3f;-9+1$*i_kGBSUbC`m-jpiZO7X!?%8)VefK zNQ&umKb*|u7DswOQD17oh9Y-;e&#oW^t!m#5ra!f3}SZSUIOI9`~nN%HPgtlPr!))?qd zs>5D=;m`Xr%~63wuKXhl+Zjm@iN#?@As5d^)#*4<-}uF@I!b~xB)Gxgoaj_vG`XTD z49iCUQWTX6e?FDl#8iF1lWSgTgxCwyN=w60;Uds#_QMW-?&JQ95R!$36LC=m1s@Ni zcbWYGEZfH^*54an&gg97z5N;IQ2Hazp=WZq%)ND-0yg56Fbbia#~OV(iy7R#QXLzP z)GN)a161wNdVCpVrKH2b6vKA$?x}#bjw%BzQB%Yygbb^QsDCmFi-@3Bkw6=*N#i}k zPDA)$?fEwP1nMC27j%byiBfF9xZ-BF8X5<&>3cd{DBUpXv$x@6=pnzSwT;=gVl0b+ z=c3<@y?sk-M*!;wZZ6@6*p2;Aq9vN0y4e!49l-|un~{EE%@{!Z`e1EzoB~N<#YfUj zAbt_z4uLiaJcm~!E?=J%yqQ!Kg4Ubof=Z`7?-#eJ~lxk&IYTX8q=$S}7lW~D9Mw$Z_(s|4Z` zZowsz=`}{a=d}8U?|FNI;6o0&#(f+PajP}Ek37YJHDC1T@^ccNBWM^l;%6-hz4Q!D zvpwwnw62sQ%^TXtI`GxPLH9{V)a9VV9{(6F!w+1I20JDdX&SIQAGx4}cjUuF>p6!* zU4Qeya4?a@&^*5y0U}3j+ym(8mP7$cqF(jnxf_CKCTas8Na8;xIW1u_GNd>j>WhE}SK{ zt>J1UkI0&Dq4o9d+yd3nl}eL;tJn2yS5?fdo7aKa2Kb548@C4mDE)?`dkqi$^`$Rf zPo=-^WF_}-qissQMWiVRG5#CZ0J1s0cMaGXL4UdizcYjW-Zl7xSM z6NFRspUft$G6D`Xk3H>CbcTJ@J|%ju7Gg`)z?bUXeed7ApcweExS=?b zTA?+D%qIB-9F=7dK1T#Z_*MSGY`Xo)Z1P|kyGHj~lzi5#}l9uM>ZN!@~J77w^mTf}Eyd<9MGf;gHnQHuw@A%D&l^6a{o@RzGA*a z-~b0hd_r`Nh$<3QM}Y9dN!5Atss9S$p4b$-vSedWDh%jME9dtj(XI!9`ed6`{RPJp z#s1B)<*RL|sc~{g@0V;nJ98#cZ=Z^KSNzc4FxayM8!$cV~$MR6LmhR zvMA}mV#qaAM#ZUXh9$5RNq3$7j8CAGc0A~(!`=GWFXZ26LADLy04*pj(<&*QK@`{H7n z`7AJ`Baau<(iAl_BdNPCeKpt{<;hj-Uq}iAye?WfDR!_uRiNB*^6RtBPl}_W2Y)h~ z%=FTsV${2Kh_uuy|BKlqWXDJ*{gc`BNsVCAA^#_{sWkkf1QI;MCxF>BItF(8joCyU zt&>3BtpWPtS42a?p#f0Zss#B{79OHxGFdD+hB*YyJjO~8`XCLg1!dGb=Cq!vXn+ZZ zvtPy{TaC`*ZX6`;xB|w|3nf!w`|^IeC-%gtGeag|uSh0m&FuLB39+*yzE%$x`scb! zfRN@Pjc}C=h9_A9=Ht(1o_DZ*Xlpmoe$(3b+i=R#n6-BavSG)i&=ZPX z^@wZ-6Ham6oj7-tBD6TZ76c?J4+Tc2>2jlezG$4A9EjGHfzKQ%6yOFc4j313X^%7+ zgEIf%#E`6Wnmz@0%M}_U@zB5xqi?x8&G}U|pc2^Dl4)1AXnb-VAjV2Zj)xFqLO7mH z85VyUB{KezqTgi0iX)A2n){)1V&TXj?81*DXu006tk#~fZ`EqmBtBz#n!b7mp8%@4 zEx}e5KOC>2Ya%EPAV|#)`!!W#drcd0hI}YFI5x4`rMGk(MpDy;8$=6-PFOWdBqc@x z)#&}?6`7@9kG5{kKfCQy+lct~7h+RcQU*Z|?z$`O1oZziVv~r}izht`cu08o7-m1I zRX9u$a8FcQ8&xCBS!i>2R1FgAIPD>PrFL%fN}G-hWc%)x0)qnzyyz3H+R^HUsBre@oRnvXIK&MlXB05X@xhVqaiXGQXp z-Afv3s8II|Sdy>~K z*em)Ywp{&y5}|1f70HY#J>gS&!qT!q)NuOGuA6gD_W`bt!nk{f`Uk_bij{g;>qKYv z@R5Z4Y(JMN>4?Qw1|h^)RSX6g{go(BG{k!$%qGoPY$KNynPK143*v z4hqcWo-A1@Nqq=VmsnNolFXNo?e86eQP7@^G|VtF_GM>t4S1;ze+K)DyZB(FA$=r6 zNTA`uzOGf16Ytj)ugQ zwSzRY*!t{o7ZA&)6RCY+yYH!+GAQ6sFIQnCR^e^p78))r7cY31ZDoi;I#ctcM z+k=|>-Ee6OZ6VYq+Q@HBM6VE!N^_nqlGc*TBq6-$JjFodg;p{9co8bB@)^b1WP9x3 zjk>$UCUP2Xd{vq0xlbnilS1&b65>sBn}-VqstD=|0v$nc{-fMn9$(xdr}Zw2Svq<) zICGV^6bL#V^`XQdeOX37?yuYEQq|ysYIX1SixZkdY6v%iNoIBR;0oFx|N3^QiTyta zPVUtiwtpo!q5Yo{oXGwMg43Jd2u>S+5}ZU8hY&A4IzYX2(lTlq_${W?NJ_q#Hh#OH zMxRkdi?BU+kHj37*`m_Y1(8=sucLd9R=2loe2u=HlNSMWGrmyW3-`%-|A2+sh7%Z% zCJzbY8?Cs`?yn-H*B1k(C94O$bN+I;3JFgeGu@!Hc2*FR%0E z+nbxBiN^0aOkQv5%=53V_7-@!ioD8k7;utpB|EuL**(SRmF@{n>j}^1F1zAw__lTw zCchpN6)J`-{C5xHeh>ZAgJ9Zecy&(3^d!F-jK{I=F4(hwv&-eh@Z*-Qo&xRHUQXn*GL`17(=QF%olOC?1x@v1~{il2VlEWWwnoQYbod}pDzG&og3{~ztRNFbM=gQZ; zyI`)x)hnDC63yAaLGG8s2+3yoN90(T{(_v8oLD$CBYe{o&9!%2Cw8Zs8FOCRo%Wop zyt%ZKD5!U)rXn&Z9=Fyi8{2a&`s8yP%@_Zc0HMc;y|;bbGF6)UA3m>kzg0%VI5Uhr zRRHnqtAoxuuI#FGD==Fz&;(f)cFD_&D-5FFndMo3Bnv)5?7>D6bY{P?$=X%xQG~U= zEY$saLoJHt>-f0vRX$xF6v&wIDtq2&JB4H!Ri&0L&@uhgoyue}*k0!8T3T&@+F=W9 z=!b5AR8wft_yJC9r(?!Ql}Vr#WVFDOiZPL|*HN8sreQ2iN@(FmU2QQM99E@pnN2fX zH(2X6x_NSYyK!}S^WgQZmiXU*_-`Flj{m?gyaTJ97+zpcG71e7dVtr1XX|!~y0!-A zoWc8T!}H9|7rBq$6B<)gK&c~g8tRvGsGB6`a*3K1JABdOr!yHEYL`-5vt`Sn{QiC5 z>7sl4ZQIypUh-QfK#EI7)gWbwFNJn)7+P47gg5Rn(Xo4yTK#1AY0f>d%aJke0 zG{_IWA0e;)&FH@;tNqjH?4ZAl&N9@1+zx_=`MjV2^65HYyb>%(xtY@u#5=Bk_(4np zO#DIri$~Zb*K}63M3$)OdT!dIZ1RUI>{{a`DR#MD5iT{-IdGSK&qm-P@SX<$jb0F* z=)Vbrvj2xE4OT$(f^G-&dW15}wTqEscWSM_Dk=>{$%FDP>(O~aHO0^?dd!T+n%}6L zTnqE^ag#RSE`sF1HMD2)LFvlQtqWf)ezZhi!AJ_@4gQU0zjIvw2{A^tzaR!?t&j!1 z?ZOnGe}LEhXzyN4?q;j+L)qFE#*?2MZJtxzmLWIK+AoOIgEV1-Z^=butT}6;nkTuyF}hzL2Qsz zhpuYix4{7Ca%$V<-WZ>pUEaXq)=Jj=4Kn}swadiF`d4Hk`K@3W;RVj@5$I*9-ahYl z$-Qh^@Y0a{LN8pwd_EJ&We6YVULY~arF&R{Vi#!qQHDlvG7nvO_Boow0vso~Q(zf+ z0cxMiVqc#etFw&i>N_B5`?1PgH;Ur zq@5pw?Rx6qgFCx1{fc1k``M3g57a9jQmSsfQH_pm{(LQSas9~3RZ;H01H|;ZO}^5# zH@r_81u`M z3?UhtK!&9TF_?*%0m$Ig2QpDvh#5>=Y)lNTh?&`m8C(tRtce+{t$#km5HTGyu&#_8Y``DJpLwB>CW40c`gW!^4%T+WOn!@bAwvAf;4N_m7d7Sb%9s>skWS_z$2E7!(}!9PX2KAsMFNU-_#)QB^TD za4-Q7{4;&@4@UgG62Bf<{Py~g#8nO^4oJeUji{liv55m@auBT{HFQj1*899vV|xH; z0D*ru>Hk4rF(9SbRG;6<*uoGph?MS|do789yjtK=!NJf{8S?wjeA)j1k3scM?SQ5D zHJM-U1r1_W5a|C!LHNIw0|so4nS~XwGe%-|Fgr0T2P*<22*gCp&c;Lx2C)K_Z1;r) zxD6l;z`(nTnUUrG2xeu0boieN!tZs=z(gShBI8$K0b~J#fdErxCT0U{n+?niR04>w zgYOIby;f`pV2Cn6VFL`570gD=!NCHwV-jV5SfgO zATV&k2vh(AFtH#&W&_b0a)fBX0t^l*kc?@de13eiTS=sKp0CW0fJ_wNRkOJv`U%(vqbNf@& z&l8A(5D_2_Kr_hnAzA@i{;~v!1>7$ja0@|>5V(FR@>2pUWJ;{}_(3e;Px+8m5Kx)_ zD8MxW8$=3FAc{fiA$2T&2mlrb()-sRh&9|B0>l{pqcDQlSpZqUz<*fAuj4Pv_;vhg zT0boVVikWWz}WZKj7$g+3;9*~1RdDb&Q{7~TR{)NEwlc@Id z9l>-TVf(K)1n_*ke-Hifdb!^W10BtY!9O3b_pce?O>{5r=i3OlneMM3?;Zf|`}6x( z60k}TS^xDA1D<{VZW9Rx{>y{kb9q?g8*G6c)qoNV-hSx0c%d;*`0!00tiy&u&^IXF z&vt!+((YG`K6>i$9lWw8 zBzIi@e7a#+ubWLxxji|};SKAI0vdw>*1X9^Gb=kSsbK5Y^ANW#{fCenLtb1wAjKXC>b&Ai_wXDa|2iFsls-@^kW|f}kxXZYRpj*M_iNjF92z1Qy5%}=WORVk7jt3!_~jn6v|Gtv++pwKq~Ls3cm-PZ41km z96(irL z`(mq3jw#D)x%rMhXdu%E-ehT_whQ-%f5+~#1aT!n5St*r4+hD~^k!m*mK5yZ8 zj@iXGf)$`h;V4aZ zt6)Xvy@jj3Dg$l-bcrZWlU#_;cH}w zpBN|(MQEKJrn^yO(%wn-m9eC=-PWi+M(I+*B-Jh)i}E1$@tW(*>mm4v1~0LelF+1b zT}`6gJUh4kd?7k6>Rg2V3;o;W8_U6uqdlP<5nA>N>f%bN|`V~@r3l$GHVreuV6^1eO{wl1%Dt! zSwK&JF`4)RuPQ1!*sJ-twNgjtEFnRMyq97~FuN@7Z5q<_7X@!>6gd0^c&+99{80+t zXD#7``db^%&NMS=dE;&K-0UCioxyfvyjwb8J0!s=#7|Db*L&_}BXIs~-^E4-MvjyD z!@DGo7~`RXC8*)%$$RfTo-OH>QwPm*XV#LiNebaou2CZB8G9@6RKfcmsx{MnCNd*7D^$u+q-LP_ftPvTzBCs)y2Mk0G`m-aOU z*{^i%ejPJ`H_{Q0fpL=Q^%at%=Iq1x!NYzimY7|pXJ?-2`lfSqu!}}`x*6+}UhTXnlQ+|kvP-oF7pU`yVJpCN z)RNy2N-EuD|JnfE(Lzxb#baG!UCZPB7>IGtAh^*#k_^{A~ zStOYAPwleql$K|;(K!3AEE$Ns2@p|wJ8Yp2IC4BM%Ts36%B-RJmFG+z_QzC5h77OP zMbNV3KKHZ1hN2DrTJ(+U3OT_OR~tKhV}nnKzxd>DOyJ*stOo;I!rx7RC%Vb9`z2&! z(E*DTxcIeX14(4#R)J5R9qv&98Xs7|Fm8TDq;;H}C;QWyMwzPHm&N|^_~!Io<*j<_ z$7xuHje5zkN3CQEE7@zvDRpAL**;r?;of4jxEmQQC;f*GSrVE(!{{s(j@_H(SvF%1 zGA&za=Z(xn3$qa{d1kz(pNp|`8n_ZpR;0Jv)36rar}22yx#vK^j2B=8 zrZOh+{mdpBQG_{19#!Og9Lv7qF9mOD$fzlzzb*1z+7@2v=s5Zd#gFi)bq59{zj*oO z8EwUWRGa*;S_;a}9PpEqTfUj9jxmk}T-VK2R^8+04Wu3>1in1pA9@!)Uv!o(IrSEJ zz+LM4jksP&AzkGG&gNUk>B^mcz1NAiZ4zeX zh~3XWyhC3d?0!kmOdH7?$+E8>pTE()QF&PzFsRGr!b*!hAJ}E1od)%OUr7~~PsB!B zSIVcx{CVyN@#UHd#0tteM2^aDKc1PD%Gu^ZD?N38!yb~Vzxr)IcwveZe{Ue4!AMxD zkG0s~4HHw`?#%q7vxSf~%=KmI9)!kc^zWGsm?~xN;DGq~QiTy(x0pmoVj2N6eh$Nv zjKwyhJi~sI^D)|MF2z*&7`N@iRDCBcXK^-H5}aWjiUP5_XH8L0zebZdNH#zMt`E>W3RtM1AaxQy4$2Zj9cb%YLBVV9gwfd6F#cIN`gyApInP z=SZBzZ{o7BFeTSvs1`dmYo&}Y8udQ!=i*y38eIyv!<;n1 zuPwfQop$i4t4U`+I!yr; z?SFkkdy?e(3L&-S2U)r*XAzk|U0SSx|FTYsQ|%O1O}j|hhwY*OgkgM(yJz2~HkB7% z@>L2~+^ih#s(z@XeHU}cY|*T^PR-6a;ksJS_;gNz09N(kEQ{)!4)8Wid!EZCssZ$7 z{tsF!xbU;9bi?u-&t}G*r4pu@Eq?>J34#xEaX;W1+uoPej~wmsJ${mP{ofZH_zdtb zcj&<9j^7ttN?yVVSn#a~D;M(r|!BODY_guj5x0<73H`bXXRe!WR}6wtM+9*E6Bms08cSavC6S};R( z61OM}Rq;f@bLN3Q3tiZ>7kYAb*=^LekK+p+Yjl{Xmysa~W7yx;aP45#!8K`k279iF zFd9QXmU<3Fy{%uiIdhzBVXTvcY65&VH4BBp@nq1d{cCɪ_ZJxRYr;U1CnjhkUL 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 diff --git a/output/examples/SBS_384_plots_BRCA_example.pdf b/output/examples/SBS_384_plots_BRCA_example.pdf deleted file mode 100644 index 437b059737ca77e43d61d9bd455aea0f945621a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72395 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%0DLvNW}vH-m+c6 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 L1`mE_T#Du21pTB9 diff --git a/output/examples/SBS_96_plots_BRCA_example.pdf b/output/examples/SBS_96_plots_BRCA_example.pdf deleted file mode 100644 index 26021817b59bbaa98e9bd0a236e1f4007164d3fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57488 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", "C>G", "C>T", "T>A", "T>C", "T>G"]] + inner_bracket=[item for sublist in inner_bracket for item in sublist] + outter_bracket=[x for x in list(itertools.product(first,first))] + result=[outter_bracket[f%16][0]+"["+inner_bracket[f]+"]"+outter_bracket[f%16][1] for f in range(0,96)] + return result + def install_plot_templates(context='SBS96'): + #WOkrks for both 96 and 288 package_path = spplt.__path__[0] install_path =os.path.join(package_path,'templates/') - if not os.path.exists(install_path): os.mkdir(install_path) filename= os.path.join(install_path,context+'.pkl') - if not os.path.exists(filename): - make_pickle_file(context,path=filename) + make_pickle_file(context,path=filename) def make_pickle_file(context='SBS96',path='SBS96.pkl'): - plot_custom_text = False - sig_probs = False - pcawg = False + if context == 'SBS96': + plot_custom_text = False + sig_probs = False + pcawg = False + + # total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) + #, extent=[-5, 80, -5, 30]) + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='lightgray') + panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) + seq96=['A[C>A]A','A[C>A]C','A[C>A]G','A[C>A]T','A[C>G]A','A[C>G]C','A[C>G]G','A[C>G]T','A[C>T]A','A[C>T]C','A[C>T]G','A[C>T]T','A[T>A]A','A[T>A]C','A[T>A]G','A[T>A]T','A[T>C]A','A[T>C]C','A[T>C]G','A[T>C]T','A[T>G]A','A[T>G]C','A[T>G]G','A[T>G]T','C[C>A]A','C[C>A]C','C[C>A]G','C[C>A]T','C[C>G]A','C[C>G]C','C[C>G]G','C[C>G]T','C[C>T]A','C[C>T]C','C[C>T]G','C[C>T]T','C[T>A]A','C[T>A]C','C[T>A]G','C[T>A]T','C[T>C]A','C[T>C]C','C[T>C]G','C[T>C]T','C[T>G]A','C[T>G]C','C[T>G]G','C[T>G]T','G[C>A]A','G[C>A]C','G[C>A]G','G[C>A]T','G[C>G]A','G[C>G]C','G[C>G]G','G[C>G]T','G[C>T]A','G[C>T]C','G[C>T]G','G[C>T]T','G[T>A]A','G[T>A]C','G[T>A]G','G[T>A]T','G[T>C]A','G[T>C]C','G[T>C]G','G[T>C]T','G[T>G]A','G[T>G]C','G[T>G]G','G[T>G]T','T[C>A]A','T[C>A]C','T[C>A]G','T[C>A]T','T[C>G]A','T[C>G]C','T[C>G]G','T[C>G]T','T[C>T]A','T[C>T]C','T[C>T]G','T[C>T]T','T[T>A]A','T[T>A]C','T[T>A]G','T[T>A]T','T[T>C]A','T[T>C]C','T[T>C]G','T[T>C]T','T[T>G]A','T[T>G]C','T[T>G]G','T[T>G]T'] + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + xlabels = [seq[0]+seq[2]+seq[6] for seq in seq96] + i = 0 + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 6, 1): + panel1.add_patch(plt.Rectangle((x,y3), .15, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .159 + + yText = y3 + .06 + plt.text(.1, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.255, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.415, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.575, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.735, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.89, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + # ytick_offest = int(y/4) + y = ymax/1.025 + ytick_offest = float(y/3) + + + labs = np.arange(0.375,96.375,1) + + + + panel1.set_xlim([0, 96]) + # panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + # panel1.set_yticks(ylabs) + count = 0 + m = 0 + for i in range (0, 96, 1): + plt.text(i/101 + .0415, .02, xlabels[i][0], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + plt.text(i/101 + .0415, .044, xlabels[i][1], fontsize=30, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) + plt.text(i/101 + .0415, .071, xlabels[i][2], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + count += 1 + if count == 16: + count = 0 + m += 1 - # total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - #, extent=[-5, 80, -5, 30]) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='lightgray') - panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) - seq96=['A[C>A]A','A[C>A]C','A[C>A]G','A[C>A]T','A[C>G]A','A[C>G]C','A[C>G]G','A[C>G]T','A[C>T]A','A[C>T]C','A[C>T]G','A[C>T]T','A[T>A]A','A[T>A]C','A[T>A]G','A[T>A]T','A[T>C]A','A[T>C]C','A[T>C]G','A[T>C]T','A[T>G]A','A[T>G]C','A[T>G]G','A[T>G]T','C[C>A]A','C[C>A]C','C[C>A]G','C[C>A]T','C[C>G]A','C[C>G]C','C[C>G]G','C[C>G]T','C[C>T]A','C[C>T]C','C[C>T]G','C[C>T]T','C[T>A]A','C[T>A]C','C[T>A]G','C[T>A]T','C[T>C]A','C[T>C]C','C[T>C]G','C[T>C]T','C[T>G]A','C[T>G]C','C[T>G]G','C[T>G]T','G[C>A]A','G[C>A]C','G[C>A]G','G[C>A]T','G[C>G]A','G[C>G]C','G[C>G]G','G[C>G]T','G[C>T]A','G[C>T]C','G[C>T]G','G[C>T]T','G[T>A]A','G[T>A]C','G[T>A]G','G[T>A]T','G[T>C]A','G[T>C]C','G[T>C]G','G[T>C]T','G[T>G]A','G[T>G]C','G[T>G]G','G[T>G]T','T[C>A]A','T[C>A]C','T[C>A]G','T[C>A]T','T[C>G]A','T[C>G]C','T[C>G]G','T[C>G]T','T[C>T]A','T[C>T]C','T[C>T]G','T[C>T]T','T[T>A]A','T[T>A]C','T[T>A]G','T[T>A]T','T[T>C]A','T[T>C]C','T[T>C]G','T[T>C]T','T[T>G]A','T[T>G]C','T[T>G]G','T[T>G]T'] - xlabels = [] - - x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] - xlabels = [seq[0]+seq[2]+seq[6] for seq in seq96] - i = 0 - - x = .043 - y3 = .87 - y = int(ymax*1.25) - y2 = y+2 - for i in range(0, 6, 1): - panel1.add_patch(plt.Rectangle((x,y3), .15, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .159 - - yText = y3 + .06 - plt.text(.1, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.255, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.415, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.575, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.735, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.89, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - - - if y <= 4: - y += 4 - - while y%4 != 0: - y += 1 - # ytick_offest = int(y/4) - y = ymax/1.025 - ytick_offest = float(y/3) - - - labs = np.arange(0.375,96.375,1) - - - - panel1.set_xlim([0, 96]) - # panel1.set_ylim([0, y]) - panel1.set_xticks(labs) - # panel1.set_yticks(ylabs) - count = 0 - m = 0 - for i in range (0, 96, 1): - plt.text(i/101 + .0415, .02, xlabels[i][0], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - plt.text(i/101 + .0415, .044, xlabels[i][1], fontsize=30, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) - plt.text(i/101 + .0415, .071, xlabels[i][2], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - count += 1 - if count == 16: - count = 0 - m += 1 + # if sig_probs: + # plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + # else: + # plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - # if sig_probs: - # plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - # else: - # plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + - + + # panel1.set_yticklabels(ylabels, fontsize=font_label_size) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + # if percentage: + # plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + # else: + # plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + + # image = plt.imread('template/SBS_96_plots_template.jpg') + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + pickle.dump(plot1, open(path, 'wb')) + elif context =='SBS288': + plot_custom_text = False + sig_probs = False + pcawg = False + + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='lightgray') + panel1 = plt.axes([0.04, 0.09, 0.7, 0.77]) + panel2 = plt.axes([0.77, 0.09, 0.21, 0.77]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + i = 0 + # seq96=['A[C>A]A','A[C>A]C','A[C>A]G','A[C>A]T','A[C>G]A','A[C>G]C','A[C>G]G','A[C>G]T','A[C>T]A','A[C>T]C','A[C>T]G','A[C>T]T','A[T>A]A','A[T>A]C','A[T>A]G','A[T>A]T','A[T>C]A','A[T>C]C','A[T>C]G','A[T>C]T','A[T>G]A','A[T>G]C','A[T>G]G','A[T>G]T','C[C>A]A','C[C>A]C','C[C>A]G','C[C>A]T','C[C>G]A','C[C>G]C','C[C>G]G','C[C>G]T','C[C>T]A','C[C>T]C','C[C>T]G','C[C>T]T','C[T>A]A','C[T>A]C','C[T>A]G','C[T>A]T','C[T>C]A','C[T>C]C','C[T>C]G','C[T>C]T','C[T>G]A','C[T>G]C','C[T>G]G','C[T>G]T','G[C>A]A','G[C>A]C','G[C>A]G','G[C>A]T','G[C>G]A','G[C>G]C','G[C>G]G','G[C>G]T','G[C>T]A','G[C>T]C','G[C>T]G','G[C>T]T','G[T>A]A','G[T>A]C','G[T>A]G','G[T>A]T','G[T>C]A','G[T>C]C','G[T>C]G','G[T>C]T','G[T>G]A','G[T>G]C','G[T>G]G','G[T>G]T','T[C>A]A','T[C>A]C','T[C>A]G','T[C>A]T','T[C>G]A','T[C>G]C','T[C>G]G','T[C>G]T','T[C>T]A','T[C>T]C','T[C>T]G','T[C>T]T','T[T>A]A','T[T>A]C','T[T>A]G','T[T>A]T','T[T>C]A','T[T>C]C','T[T>C]G','T[T>C]T','T[T>G]A','T[T>G]C','T[T>G]G','T[T>G]T'] + result = get_default_96labels() + xlabels = [seq[0]+seq[2]+seq[6] for seq in result] + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 6, 1): + panel1.add_patch(plt.Rectangle((x,y3), .11, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .117 + + yText = y3 + .06 + + + plt.text(.082, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.1975, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.315, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.43, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.55, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.665, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + y = ymax/1.025 + ytick_offest = float(y/3) + + font_label_size = 30 + + + labs = np.arange(0.375,96.375,1) + + + + panel1.set_xlim([0, 96]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + + count = 0 + m = 0 + for i in range (0, 96, 1): + plt.text(i/137 + .04, .02, xlabels[i][0], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + plt.text(i/137 + .04, .044, xlabels[i][1], fontsize=25, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) + plt.text(i/137 + .04, .071, xlabels[i][2], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + count += 1 + if count == 16: + count = 0 + m += 1 + + panel1.yaxis.grid(True) + panel1.grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') - # panel1.set_yticklabels(ylabels, fontsize=font_label_size) - plt.gca().yaxis.grid(True) - plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.set_xlabel('') - panel1.set_ylabel('') - # if percentage: - # plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - # else: - # plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) - # image = plt.imread('template/SBS_96_plots_template.jpg') - panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) + [i.set_color("black") for i in panel1.get_yticklabels()] - [i.set_color("black") for i in plt.gca().get_yticklabels()] - pickle.dump(plot1, open(path, 'wb')) + yp2 = 28 + labels = [] + y2max = 0 + tsbColors = [[1/256,70/256,102/256], [228/256,41/256,38/256], 'green'] + + y = int(y2max*1.1) + if y <= 4: + y += 4 + while y%4 != 0: + y += 1 + ytick_offest = int(y/4) + + panel2.spines['right'].set_visible(False) + panel2.spines['top'].set_visible(False) + labels.reverse() + panel2.set_yticks([3, 7, 11, 15, 19, 23, 27]) + panel2.set_yticklabels(labels, fontsize=30,fontname="Arial", weight = 'bold') + panel2.set_xticklabels(xlabels, fontsize=30) + # panel2.set_xticks(xlabels) + handles, labels = panel2.get_legend_handles_labels() + panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) + pickle.dump(plot1, open(path, 'wb')) + @@ -187,6 +309,30 @@ def reindex_sbs96(data_f): return data_f +def reindex_sbs288(data_f): + result = get_default_96labels() + mutations_df = pd.DataFrame(index=result,columns=data_f.columns) + T_mutations_df = pd.DataFrame(index=result,columns=data_f.columns) + U_mutations_df = pd.DataFrame(index=result,columns=data_f.columns) + N_mutations_df = pd.DataFrame(index=result,columns=data_f.columns) + + for row in result: + T_mutations_df.loc[row] = data_f.loc["T:"+row] + U_mutations_df.loc[row] = data_f.loc["U:"+row] + N_mutations_df.loc[row] = data_f.loc["N:"+row] + mutations_df.loc[row] = data_f.loc["T:"+row]+data_f.loc["U:"+row]+data_f.loc["N:"+row] + + mutations_TSB_df_T = pd.DataFrame(T_mutations_df.values.reshape((-1, 16, len(data_f.columns))).sum(axis=1),index=["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"],columns=data_f.columns) + mutations_TSB_df_U = pd.DataFrame(U_mutations_df.values.reshape((-1, 16, len(data_f.columns))).sum(axis=1),index=["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"],columns=data_f.columns) + mutations_TSB_df_N = pd.DataFrame(N_mutations_df.values.reshape((-1, 16, len(data_f.columns))).sum(axis=1),index=["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"],columns=data_f.columns) + mutations_TSB_df_T = mutations_TSB_df_T.append(mutations_TSB_df_T.sum().rename('All')) + mutations_TSB_df_U = mutations_TSB_df_U.append(mutations_TSB_df_U.sum().rename('All')) + mutations_TSB_df_N = mutations_TSB_df_N.append(mutations_TSB_df_N.sum().rename('All')) + mutations_TSB_df_T = mutations_TSB_df_T.reindex(np.roll(mutations_TSB_df_T.index, shift=1)) + mutations_TSB_df_U = mutations_TSB_df_U.reindex(np.roll(mutations_TSB_df_U.index, shift=1)) + mutations_TSB_df_N = mutations_TSB_df_N.reindex(np.roll(mutations_TSB_df_N.index, shift=1)) + return mutations_df,{'T':mutations_TSB_df_T,'U':mutations_TSB_df_U,'N':mutations_TSB_df_N} + def plotSV(matrix_path, output_path, project, plot_type="pdf", percentage=False, aggregate=False): """Outputs a pdf containing Rearrangement signature plots @@ -586,6 +732,339 @@ def plot(counts, labels, sample, project, percentage, aggregate=False, write_to_ return buff_list pp.close() +def plotSBSmod288(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): + plot_custom_text = False + sig_probs = False + pcawg = False + import pdb;pdb.set_trace() + + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + + import pdb;pdb.set_trace() + with open(matrix_path) as f: + next(f) + first_line = f.readline() + first_line = first_line.strip().split() + if first_line[0][6] == ">" or first_line[0][3] == ">": + pcawg = True + if first_line[0][7] != "]" and first_line[0][6] != ">" and first_line[0][3] != ">": + sys.exit("The matrix does not match the correct SBS288 format. Please check you formatting and rerun this plotting function.") + + pp = PdfPages(output_path + 'SBS_288_plots_' + project + '.pdf') + + mutations = OrderedDict() + mutations_TSB = OrderedDict() + total_count = [] + try: + with open (matrix_path) as f: + first_line = f.readline() + if pcawg: + samples = first_line.strip().split(",") + samples = samples[2:] + else: + samples = first_line.strip().split("\t") + samples = samples[1:] + + for sample in samples: + mutations[sample] = OrderedDict() + mutations[sample]['C>A'] = OrderedDict() + mutations[sample]['C>G'] = OrderedDict() + mutations[sample]['C>T'] = OrderedDict() + mutations[sample]['T>A'] = OrderedDict() + mutations[sample]['T>C'] = OrderedDict() + mutations[sample]['T>G'] = OrderedDict() + + mutations_TSB[sample] = OrderedDict() + mutations_TSB[sample]['All'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['C>A'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['C>G'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['C>T'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['T>A'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['T>C'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['T>G'] = OrderedDict({'T':0, 'U':0,'N':0}) + + for lines in f: + if pcawg: + line = lines.strip().split(",") + mut_type = line[0] + nuc = line[1][0] + "[" + mut_type + "]" + line[1][2] + sample_index = 2 + else: + line = lines.strip().split() + nuc = line[0] + mut_type = line[0][4:7] + sample_index = 1 + tsb = nuc[0] + + + for sample in samples: + if percentage: + mutCount = float(line[sample_index]) + if mutCount < 1 and mutCount > 0: + sig_probs = True + else: + try: + mutCount = int(line[sample_index]) + except: + print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') + if nuc[2:] not in mutations[sample][mut_type]: + mutations[sample][mut_type][nuc[2:]] = mutCount + else: + mutations[sample][mut_type][nuc[2:]] += mutCount + mutations_TSB[sample][mut_type][tsb] += mutCount + mutations_TSB[sample]['All'][tsb] += mutCount + sample_index += 1 + + sample_count = 0 + pdb.set_trace() + data,tsb_mats = reindex_sbs288(data) + pdb.set_trace() + for sample in mutations.keys(): + total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='lightgray') + panel1 = plt.axes([0.04, 0.09, 0.7, 0.77]) + panel2 = plt.axes([0.77, 0.09, 0.21, 0.77]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + i = 0 + for key in mutations[sample]: + for seq in mutations[sample][key]: + xlabels.append(seq[0]+seq[2]+seq[6]) + if percentage: + if total_count > 0: + panel1.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) + if mutations[sample][key][seq]/total_count*100 > ymax: + ymax = mutations[sample][key][seq]/total_count*100 + else: + panel1.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) + if mutations[sample][key][seq] > ymax: + ymax = mutations[sample][key][seq] + x += 1 + i += 1 + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 6, 1): + panel1.add_patch(plt.Rectangle((x,y3), .11, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .117 + + yText = y3 + .06 + + + plt.text(.082, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.1975, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.315, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.43, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.55, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.665, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + y = ymax/1.025 + ytick_offest = float(y/3) + # ytick_offest = int(y/4) + + + if percentage: + ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] + ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + # ylabels= [str(0), str(round(ytick_offest)) + "%", str(round(ytick_offest*2)) + "%", + # str(round(ytick_offest*3)) + "%", str(round(ytick_offest*4)) + "%"] + else: + ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] + ylabels= [0, ytick_offest, ytick_offest*2, + ytick_offest*3, ytick_offest*4] + + font_label_size = 30 + if not percentage: + if int(ylabels[3]) >= 1000: + font_label_size = 20 + + if percentage: + if len(ylabels) > 2: + font_label_size = 20 + + labs = np.arange(0.375,96.375,1) + + if not percentage: + ylabels= getylabels(ylabels) + + panel1.set_xlim([0, 96]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + panel1.set_yticks(ylabs) + count = 0 + m = 0 + for i in range (0, 96, 1): + plt.text(i/137 + .04, .02, xlabels[i][0], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + plt.text(i/137 + .04, .044, xlabels[i][1], fontsize=25, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) + plt.text(i/137 + .04, .071, xlabels[i][2], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + count += 1 + if count == 16: + count = 0 + m += 1 + + if sig_probs: + plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + else: + plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + + + + custom_text_upper_plot = '' + try: + custom_text_upper[sample_count] + except: + custom_text_upper = False + try: + custom_text_middle[sample_count] + except: + custom_text_middle = False + try: + custom_text_bottom[sample_count] + except: + custom_text_bottom = False + + if custom_text_upper: + plot_custom_text = True + if len(custom_text_upper[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + if custom_text_middle: + if len(custom_text_middle[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + + if plot_custom_text: + x_pos_custom = 0.73 + if custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] + if custom_text_bottom: + custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] + + if custom_text_upper and not custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right',zorder=1) + + elif custom_text_upper and custom_text_middle: + if not custom_text_bottom: + panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + else: + panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + elif not custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_middle[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + + + panel1.set_yticklabels(ylabels, fontsize=font_label_size) + # plt.gca().yaxis.grid(True) + # plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.yaxis.grid(True) + panel1.grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + if percentage: + panel1.set_ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + else: + panel1.set_ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + + [i.set_color("black") for i in panel1.get_yticklabels()] + + + yp2 = 28 + labels = [] + y2max = 0 + tsbColors = [[1/256,70/256,102/256], [228/256,41/256,38/256], 'green'] + for mut in mutations_TSB[sample]: + labels.append(mut) + i = 0 + for tsb in mutations_TSB[sample][mut]: + if tsb == "T": + label = "Genic-transcribed" + elif tsb == "U": + label = "Genic-untranscribed" + else: + label = "Intergenic" + if percentage: + if total_count > 0: + panel2.barh(yp2, mutations_TSB[sample][mut][tsb]/total_count*100,color=tsbColors[i], label=label) + if mutations_TSB[sample][mut][tsb]/total_count*100 > y2max: + y2max = mutations_TSB[sample][mut][tsb]/total_count*100 + else: + if mutations_TSB[sample][mut][tsb] > y2max: + y2max = mutations_TSB[sample][mut][tsb] + + panel2.barh(yp2, mutations_TSB[sample][mut][tsb], color=tsbColors[i], label=label) + yp2 -= 1 + i += 1 + yp2 -=1 + y = int(y2max*1.1) + if y <= 4: + y += 4 + while y%4 != 0: + y += 1 + ytick_offest = int(y/4) + + if percentage: + xlabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] + xlabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + else: + xlabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] + xlabels= [0, ytick_offest, ytick_offest*2, + ytick_offest*3, ytick_offest*4] + + + if not percentage: + xlabels = getxlabels(xlabels) + + panel2.spines['right'].set_visible(False) + panel2.spines['top'].set_visible(False) + labels.reverse() + panel2.set_yticks([3, 7, 11, 15, 19, 23, 27]) + panel2.set_yticklabels(labels, fontsize=30,fontname="Arial", weight = 'bold') + panel2.set_xticklabels(xlabels, fontsize=30) + panel2.set_xticks(xlabs) + handles, labels = panel2.get_legend_handles_labels() + panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) + pp.savefig(plot1) + plt.close() + sample_count += 1 + + pp.close() + except: + print("There may be an issue with the formatting of your matrix file.") + os.remove(output_path + 'SBS_288_plots_' + project + '.pdf') + def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): @@ -650,8 +1129,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%",str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, @@ -3005,128 +3483,52 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust elif plot_type == '288': - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - if first_line[0][6] == ">" or first_line[0][3] == ">": - pcawg = True - if first_line[0][7] != "]" and first_line[0][6] != ">" and first_line[0][3] != ">": - sys.exit("The matrix does not match the correct SBS288 format. Please check you formatting and rerun this plotting function.") - - pp = PdfPages(output_path + 'SBS_288_plots_' + project + '.pdf') - - mutations = OrderedDict() - mutations_TSB = OrderedDict() - total_count = [] try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[2:] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] + plot_custom_text = False + sig_probs = False + pcawg = False - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['C>A'] = OrderedDict() - mutations[sample]['C>G'] = OrderedDict() - mutations[sample]['C>T'] = OrderedDict() - mutations[sample]['T>A'] = OrderedDict() - mutations[sample]['T>C'] = OrderedDict() - mutations[sample]['T>G'] = OrderedDict() - - mutations_TSB[sample] = OrderedDict() - mutations_TSB[sample]['All'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>A'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>G'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>T'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>A'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>C'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>G'] = OrderedDict({'T':0, 'U':0,'N':0}) - - for lines in f: - if pcawg: - line = lines.strip().split(",") - mut_type = line[0] - nuc = line[1][0] + "[" + mut_type + "]" + line[1][2] - sample_index = 2 - else: - line = lines.strip().split() - nuc = line[0] - mut_type = line[0][4:7] - sample_index = 1 - tsb = nuc[0] - - - for sample in samples: - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') - if nuc[2:] not in mutations[sample][mut_type]: - mutations[sample][mut_type][nuc[2:]] = mutCount - else: - mutations[sample][mut_type][nuc[2:]] += mutCount - mutations_TSB[sample][mut_type][tsb] += mutCount - mutations_TSB[sample]['All'][tsb] += mutCount - sample_index += 1 + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + sample_count = 0 - for sample in mutations.keys(): - total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='lightgray') - panel1 = plt.axes([0.04, 0.09, 0.7, 0.77]) - panel2 = plt.axes([0.77, 0.09, 0.21, 0.77]) - xlabels = [] + data,tsb_mats = reindex_sbs288(data) + buf= io.BytesIO() + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS288.pkl','rb')) + pickle.dump(fig_orig, buf) + figs = {} + buff_list = {} + ctx = data.index + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + colorsall= [[colors[j] for i in range(int(len(ctx)/6))] for j in range(6)] + colors_flat_list = [item for sublist in colorsall for item in sublist] - x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] - i = 0 - for key in mutations[sample]: - for seq in mutations[sample][key]: - xlabels.append(seq[0]+seq[2]+seq[6]) - if percentage: - if total_count > 0: - panel1.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq]/total_count*100 > ymax: - ymax = mutations[sample][key][seq]/total_count*100 - else: - panel1.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq] > ymax: - ymax = mutations[sample][key][seq] - x += 1 - i += 1 + for sample in data.columns: - x = .043 - y3 = .87 - y = int(ymax*1.25) - y2 = y+2 - for i in range(0, 6, 1): - panel1.add_patch(plt.Rectangle((x,y3), .11, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .117 + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + panel2= figs[sample].axes[1] - yText = y3 + .06 + total_count = np.sum(data[sample].values) + muts = data[sample].values + x=0.4 + if percentage: + if total_count > 0: + panel1.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + panel1.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) - plt.text(.082, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.1975, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.315, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.43, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.55, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.665, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + y = int(ymax*1.25) if y <= 4: y += 4 @@ -3134,19 +3536,16 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust y += 1 y = ymax/1.025 ytick_offest = float(y/3) - # ytick_offest = int(y/4) - if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - # ylabels= [str(0), str(round(ytick_offest)) + "%", str(round(ytick_offest*2)) + "%", - # str(round(ytick_offest*3)) + "%", str(round(ytick_offest*4)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] font_label_size = 30 if not percentage: @@ -3160,54 +3559,14 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust labs = np.arange(0.375,96.375,1) if not percentage: - ylabels= getylabels(ylabels) - #ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if max(ylabels)< 10**5: - # ylabels = ['{:,.2f}'.format(x/1000)+'k' for x in ylabels] - # elif max(ylabels)>= 10**5: - # ylabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in ylabels] - - # if max(ylabels) >=10**9: - # ylabels = ["{:.2e}".format(x) for x in ylabels] - # else: - # if max(ylabels)< 10**5: - # ylabels = ['{:,.2f}'.format(x/1000)+'k' for x in ylabels] - # elif max(ylabels)>= 10**5: - # ylabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in ylabels] - - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp + ylabels= spplt.getylabels(ylabels) panel1.set_xlim([0, 96]) panel1.set_ylim([0, y]) - panel1.set_xticks(labs) + panel1.set_yticks(ylabs) - count = 0 - m = 0 - for i in range (0, 96, 1): - plt.text(i/137 + .04, .02, xlabels[i][0], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - plt.text(i/137 + .04, .044, xlabels[i][1], fontsize=25, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) - plt.text(i/137 + .04, .071, xlabels[i][2], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - count += 1 - if count == 16: - count = 0 - m += 1 + + if sig_probs: plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) @@ -3279,43 +3638,27 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) [i.set_color("black") for i in panel1.get_yticklabels()] - yp2 = 28 labels = [] y2max = 0 tsbColors = [[1/256,70/256,102/256], [228/256,41/256,38/256], 'green'] - for mut in mutations_TSB[sample]: - labels.append(mut) - i = 0 - for tsb in mutations_TSB[sample][mut]: - if tsb == "T": - label = "Genic-transcribed" - elif tsb == "U": - label = "Genic-untranscribed" - else: - label = "Intergenic" - if percentage: - if total_count > 0: - panel2.barh(yp2, mutations_TSB[sample][mut][tsb]/total_count*100,color=tsbColors[i], label=label) - if mutations_TSB[sample][mut][tsb]/total_count*100 > y2max: - y2max = mutations_TSB[sample][mut][tsb]/total_count*100 - else: - if mutations_TSB[sample][mut][tsb] > y2max: - y2max = mutations_TSB[sample][mut][tsb] - panel2.barh(yp2, mutations_TSB[sample][mut][tsb], color=tsbColors[i], label=label) - yp2 -= 1 - i += 1 - yp2 -=1 + y2max= np.max([tsb_mats['T'][sample]['All'],tsb_mats['U'][sample]['All'],tsb_mats['N'][sample]['All']]) + + panel2.barh(range(28,1,-4),tsb_mats['T'][sample].values , color=tsbColors[0], label="Genic-transcribed") + panel2.barh(range(27,1,-4),tsb_mats['U'][sample].values , color=tsbColors[1], label="Genic-untranscribed") + panel2.barh(range(26,1,-4),tsb_mats['N'][sample].values , color=tsbColors[2], label="Intergenic") + labels=list(tsb_mats['T'][sample].index) + y = int(y2max*1.1) if y <= 4: y += 4 @@ -3326,48 +3669,16 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if percentage: xlabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] xlabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: xlabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] xlabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] if not percentage: - xlabels = getxlabels(xlabels) + xlabels = spplt.getxlabels(xlabels) - # if max(xlabels) >=10**10: - # xlabels = ["{:.2e}".format(x) for x in xlabels] - # else: - # if max(xlabels)< 10**5: - # xlabels = ['{:,.2f}'.format(x/1000)+'k' for x in xlabels] - # elif max(xlabels)>= 10**5: - # xlabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in xlabels] - - # import pdb - # pdb.set_trace() - # from decimal import Decimal - # xlabels = [str('%.2E') % Decimal(x) for x in xlabels] - #'%.2E' % Decimal('40800000000.00000000000000') - # xlabels = ['{:,}'.format(int(x)) for x in xlabels] - # if len(xlabels[-1]) > 3: - # xlabels_temp = [] - # if len(xlabels[-1]) > 7: - # for label in xlabels: - # if len(label) > 7: - # xlabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # xlabels_temp.append(label[0:-4] + "k") - # else: - # xlabels_temp.append(label) - - # else: - # for label in xlabels: - # if len(label) > 3: - # xlabels_temp.append(label[0:-4] + "k") - # else: - # xlabels_temp.append(label) - # xlabels = xlabels_temp panel2.spines['right'].set_visible(False) panel2.spines['top'].set_visible(False) labels.reverse() @@ -3377,11 +3688,29 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust panel2.set_xticks(xlabs) handles, labels = panel2.get_legend_handles_labels() panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) - pp.savefig(plot1) - plt.close() + # temp_plotsave(output_path,project,figs[sample]) + # pp.savefig(plot1) + # plt.close() sample_count += 1 + + if savefig_format == "pdf": + pp = PdfPages(output_path + 'SBS_288_plots_' + project + '.pdf') + + if savefig_format == "pdf": + for fig in figs: + figs[fig].savefig(pp, format='pdf') + pp.close() + + if savefig_format == "png": + for fig in figs: + figs[fig].savefig(output_path + 'SBS_288_plots_'+fig+'.png',dpi=100) + if savefig_format == "buffer_stream": + for fig in figs: + buffer2=io.BytesIO() + figs[fig].savefig(buffer2,format='png') + buff_list[fig]=buffer2 + return buff_list - pp.close() except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'SBS_288_plots_' + project + '.pdf') From 164e91187d21187b20463ef070cb6ca20b7fe61a Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:15:06 -0700 Subject: [PATCH 07/21] SBS 96 288 modifications --- sigProfilerPlotting/plot_example.py => plot_example.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sigProfilerPlotting/plot_example.py => plot_example.py (100%) diff --git a/sigProfilerPlotting/plot_example.py b/plot_example.py similarity index 100% rename from sigProfilerPlotting/plot_example.py rename to plot_example.py From 5a909e735d4f861a2c86c4dbc40cba18b2a12e5f Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:31:03 -0700 Subject: [PATCH 08/21] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4a225f2..d8a8165 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - '3.6' + - '3.10' install: - pip install -q matplotlib From 8cebaca97b670891df39fdf5c31ff7d93b067761 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:32:59 -0700 Subject: [PATCH 09/21] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d8a8165..3a252e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - '3.10' + - '3.9' install: - pip install -q matplotlib From 1842ef84913dadc6ee743c86de5d26f69df81254 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:35:37 -0700 Subject: [PATCH 10/21] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3a252e0..cba3405 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ python: install: - pip install -q matplotlib - - pip install . + - pip install . -v script: python3 plot_example.py From 22e5e316207ff5edd74a220380797108cc9ca7ad Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:42:05 -0700 Subject: [PATCH 11/21] SBS 96 288 modifications --- .travis.yml | 2 +- .../sigProfilerPlotting.py | 967 ++++++++++++------ setup.py | 4 +- 3 files changed, 651 insertions(+), 322 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4a225f2..3a252e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - '3.6' + - '3.9' install: - pip install -q matplotlib diff --git a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py index 72d9eda..545d4c1 100644 --- a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py +++ b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py @@ -4,6 +4,7 @@ #Contact: ebergstr@eng.ucsd.edu +from bdb import set_trace import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt @@ -27,120 +28,241 @@ import pickle import sigProfilerPlotting as spplt import pdb -import itertools +import itertools,time warnings.filterwarnings("ignore") +def temp_plotsave(output_path,project,figs_orig): + pp = PdfPages(output_path + 'SBS_288_testst_plots_' + project + '.pdf') + figs_orig.savefig(pp, format='pdf') + pp.close() + +def get_default_96labels(): + first=['A','C','G','T'] + inner_bracket=[[x]*16 for x in ["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"]] + inner_bracket=[item for sublist in inner_bracket for item in sublist] + outter_bracket=[x for x in list(itertools.product(first,first))] + result=[outter_bracket[f%16][0]+"["+inner_bracket[f]+"]"+outter_bracket[f%16][1] for f in range(0,96)] + return result + def install_plot_templates(context='SBS96'): + #WOkrks for both 96 and 288 package_path = spplt.__path__[0] install_path =os.path.join(package_path,'templates/') - if not os.path.exists(install_path): os.mkdir(install_path) filename= os.path.join(install_path,context+'.pkl') - if not os.path.exists(filename): - make_pickle_file(context,path=filename) + make_pickle_file(context,path=filename) def make_pickle_file(context='SBS96',path='SBS96.pkl'): - plot_custom_text = False - sig_probs = False - pcawg = False + if context == 'SBS96': + plot_custom_text = False + sig_probs = False + pcawg = False + + # total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) + #, extent=[-5, 80, -5, 30]) + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='lightgray') + panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) + seq96=['A[C>A]A','A[C>A]C','A[C>A]G','A[C>A]T','A[C>G]A','A[C>G]C','A[C>G]G','A[C>G]T','A[C>T]A','A[C>T]C','A[C>T]G','A[C>T]T','A[T>A]A','A[T>A]C','A[T>A]G','A[T>A]T','A[T>C]A','A[T>C]C','A[T>C]G','A[T>C]T','A[T>G]A','A[T>G]C','A[T>G]G','A[T>G]T','C[C>A]A','C[C>A]C','C[C>A]G','C[C>A]T','C[C>G]A','C[C>G]C','C[C>G]G','C[C>G]T','C[C>T]A','C[C>T]C','C[C>T]G','C[C>T]T','C[T>A]A','C[T>A]C','C[T>A]G','C[T>A]T','C[T>C]A','C[T>C]C','C[T>C]G','C[T>C]T','C[T>G]A','C[T>G]C','C[T>G]G','C[T>G]T','G[C>A]A','G[C>A]C','G[C>A]G','G[C>A]T','G[C>G]A','G[C>G]C','G[C>G]G','G[C>G]T','G[C>T]A','G[C>T]C','G[C>T]G','G[C>T]T','G[T>A]A','G[T>A]C','G[T>A]G','G[T>A]T','G[T>C]A','G[T>C]C','G[T>C]G','G[T>C]T','G[T>G]A','G[T>G]C','G[T>G]G','G[T>G]T','T[C>A]A','T[C>A]C','T[C>A]G','T[C>A]T','T[C>G]A','T[C>G]C','T[C>G]G','T[C>G]T','T[C>T]A','T[C>T]C','T[C>T]G','T[C>T]T','T[T>A]A','T[T>A]C','T[T>A]G','T[T>A]T','T[T>C]A','T[T>C]C','T[T>C]G','T[T>C]T','T[T>G]A','T[T>G]C','T[T>G]G','T[T>G]T'] + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + xlabels = [seq[0]+seq[2]+seq[6] for seq in seq96] + i = 0 + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 6, 1): + panel1.add_patch(plt.Rectangle((x,y3), .15, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .159 + + yText = y3 + .06 + plt.text(.1, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.255, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.415, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.575, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.735, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.89, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + # ytick_offest = int(y/4) + y = ymax/1.025 + ytick_offest = float(y/3) + + + labs = np.arange(0.375,96.375,1) + + + + panel1.set_xlim([0, 96]) + # panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + # panel1.set_yticks(ylabs) + count = 0 + m = 0 + for i in range (0, 96, 1): + plt.text(i/101 + .0415, .02, xlabels[i][0], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + plt.text(i/101 + .0415, .044, xlabels[i][1], fontsize=30, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) + plt.text(i/101 + .0415, .071, xlabels[i][2], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + count += 1 + if count == 16: + count = 0 + m += 1 - # total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - #, extent=[-5, 80, -5, 30]) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='lightgray') - panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) - seq96=['A[C>A]A','A[C>A]C','A[C>A]G','A[C>A]T','A[C>G]A','A[C>G]C','A[C>G]G','A[C>G]T','A[C>T]A','A[C>T]C','A[C>T]G','A[C>T]T','A[T>A]A','A[T>A]C','A[T>A]G','A[T>A]T','A[T>C]A','A[T>C]C','A[T>C]G','A[T>C]T','A[T>G]A','A[T>G]C','A[T>G]G','A[T>G]T','C[C>A]A','C[C>A]C','C[C>A]G','C[C>A]T','C[C>G]A','C[C>G]C','C[C>G]G','C[C>G]T','C[C>T]A','C[C>T]C','C[C>T]G','C[C>T]T','C[T>A]A','C[T>A]C','C[T>A]G','C[T>A]T','C[T>C]A','C[T>C]C','C[T>C]G','C[T>C]T','C[T>G]A','C[T>G]C','C[T>G]G','C[T>G]T','G[C>A]A','G[C>A]C','G[C>A]G','G[C>A]T','G[C>G]A','G[C>G]C','G[C>G]G','G[C>G]T','G[C>T]A','G[C>T]C','G[C>T]G','G[C>T]T','G[T>A]A','G[T>A]C','G[T>A]G','G[T>A]T','G[T>C]A','G[T>C]C','G[T>C]G','G[T>C]T','G[T>G]A','G[T>G]C','G[T>G]G','G[T>G]T','T[C>A]A','T[C>A]C','T[C>A]G','T[C>A]T','T[C>G]A','T[C>G]C','T[C>G]G','T[C>G]T','T[C>T]A','T[C>T]C','T[C>T]G','T[C>T]T','T[T>A]A','T[T>A]C','T[T>A]G','T[T>A]T','T[T>C]A','T[T>C]C','T[T>C]G','T[T>C]T','T[T>G]A','T[T>G]C','T[T>G]G','T[T>G]T'] - xlabels = [] - - x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] - xlabels = [seq[0]+seq[2]+seq[6] for seq in seq96] - i = 0 - - x = .043 - y3 = .87 - y = int(ymax*1.25) - y2 = y+2 - for i in range(0, 6, 1): - panel1.add_patch(plt.Rectangle((x,y3), .15, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .159 - - yText = y3 + .06 - plt.text(.1, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.255, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.415, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.575, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.735, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.89, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - - - if y <= 4: - y += 4 - - while y%4 != 0: - y += 1 - # ytick_offest = int(y/4) - y = ymax/1.025 - ytick_offest = float(y/3) - - - labs = np.arange(0.375,96.375,1) - - - - panel1.set_xlim([0, 96]) - # panel1.set_ylim([0, y]) - panel1.set_xticks(labs) - # panel1.set_yticks(ylabs) - count = 0 - m = 0 - for i in range (0, 96, 1): - plt.text(i/101 + .0415, .02, xlabels[i][0], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - plt.text(i/101 + .0415, .044, xlabels[i][1], fontsize=30, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) - plt.text(i/101 + .0415, .071, xlabels[i][2], fontsize=30, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - count += 1 - if count == 16: - count = 0 - m += 1 + # if sig_probs: + # plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + # else: + # plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - # if sig_probs: - # plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - # else: - # plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + - + + # panel1.set_yticklabels(ylabels, fontsize=font_label_size) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + # if percentage: + # plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + # else: + # plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + + # image = plt.imread('template/SBS_96_plots_template.jpg') + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + pickle.dump(plot1, open(path, 'wb')) + elif context =='SBS288': + plot_custom_text = False + sig_probs = False + pcawg = False + + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='lightgray') + panel1 = plt.axes([0.04, 0.09, 0.7, 0.77]) + panel2 = plt.axes([0.77, 0.09, 0.21, 0.77]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + i = 0 + # seq96=['A[C>A]A','A[C>A]C','A[C>A]G','A[C>A]T','A[C>G]A','A[C>G]C','A[C>G]G','A[C>G]T','A[C>T]A','A[C>T]C','A[C>T]G','A[C>T]T','A[T>A]A','A[T>A]C','A[T>A]G','A[T>A]T','A[T>C]A','A[T>C]C','A[T>C]G','A[T>C]T','A[T>G]A','A[T>G]C','A[T>G]G','A[T>G]T','C[C>A]A','C[C>A]C','C[C>A]G','C[C>A]T','C[C>G]A','C[C>G]C','C[C>G]G','C[C>G]T','C[C>T]A','C[C>T]C','C[C>T]G','C[C>T]T','C[T>A]A','C[T>A]C','C[T>A]G','C[T>A]T','C[T>C]A','C[T>C]C','C[T>C]G','C[T>C]T','C[T>G]A','C[T>G]C','C[T>G]G','C[T>G]T','G[C>A]A','G[C>A]C','G[C>A]G','G[C>A]T','G[C>G]A','G[C>G]C','G[C>G]G','G[C>G]T','G[C>T]A','G[C>T]C','G[C>T]G','G[C>T]T','G[T>A]A','G[T>A]C','G[T>A]G','G[T>A]T','G[T>C]A','G[T>C]C','G[T>C]G','G[T>C]T','G[T>G]A','G[T>G]C','G[T>G]G','G[T>G]T','T[C>A]A','T[C>A]C','T[C>A]G','T[C>A]T','T[C>G]A','T[C>G]C','T[C>G]G','T[C>G]T','T[C>T]A','T[C>T]C','T[C>T]G','T[C>T]T','T[T>A]A','T[T>A]C','T[T>A]G','T[T>A]T','T[T>C]A','T[T>C]C','T[T>C]G','T[T>C]T','T[T>G]A','T[T>G]C','T[T>G]G','T[T>G]T'] + result = get_default_96labels() + xlabels = [seq[0]+seq[2]+seq[6] for seq in result] + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 6, 1): + panel1.add_patch(plt.Rectangle((x,y3), .11, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .117 + + yText = y3 + .06 + + + plt.text(.082, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.1975, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.315, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.43, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.55, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.665, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + y = ymax/1.025 + ytick_offest = float(y/3) + + font_label_size = 30 + + + labs = np.arange(0.375,96.375,1) + + + + panel1.set_xlim([0, 96]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + + count = 0 + m = 0 + for i in range (0, 96, 1): + plt.text(i/137 + .04, .02, xlabels[i][0], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + plt.text(i/137 + .04, .044, xlabels[i][1], fontsize=25, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) + plt.text(i/137 + .04, .071, xlabels[i][2], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + count += 1 + if count == 16: + count = 0 + m += 1 + + panel1.yaxis.grid(True) + panel1.grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') - # panel1.set_yticklabels(ylabels, fontsize=font_label_size) - plt.gca().yaxis.grid(True) - plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.set_xlabel('') - panel1.set_ylabel('') - # if percentage: - # plt.ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - # else: - # plt.ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) - # image = plt.imread('template/SBS_96_plots_template.jpg') - panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) + [i.set_color("black") for i in panel1.get_yticklabels()] - [i.set_color("black") for i in plt.gca().get_yticklabels()] - pickle.dump(plot1, open(path, 'wb')) + yp2 = 28 + labels = [] + y2max = 0 + tsbColors = [[1/256,70/256,102/256], [228/256,41/256,38/256], 'green'] + + y = int(y2max*1.1) + if y <= 4: + y += 4 + while y%4 != 0: + y += 1 + ytick_offest = int(y/4) + + panel2.spines['right'].set_visible(False) + panel2.spines['top'].set_visible(False) + labels.reverse() + panel2.set_yticks([3, 7, 11, 15, 19, 23, 27]) + panel2.set_yticklabels(labels, fontsize=30,fontname="Arial", weight = 'bold') + panel2.set_xticklabels(xlabels, fontsize=30) + # panel2.set_xticks(xlabels) + handles, labels = panel2.get_legend_handles_labels() + panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) + pickle.dump(plot1, open(path, 'wb')) + @@ -187,6 +309,30 @@ def reindex_sbs96(data_f): return data_f +def reindex_sbs288(data_f): + result = get_default_96labels() + mutations_df = pd.DataFrame(index=result,columns=data_f.columns) + T_mutations_df = pd.DataFrame(index=result,columns=data_f.columns) + U_mutations_df = pd.DataFrame(index=result,columns=data_f.columns) + N_mutations_df = pd.DataFrame(index=result,columns=data_f.columns) + + for row in result: + T_mutations_df.loc[row] = data_f.loc["T:"+row] + U_mutations_df.loc[row] = data_f.loc["U:"+row] + N_mutations_df.loc[row] = data_f.loc["N:"+row] + mutations_df.loc[row] = data_f.loc["T:"+row]+data_f.loc["U:"+row]+data_f.loc["N:"+row] + + mutations_TSB_df_T = pd.DataFrame(T_mutations_df.values.reshape((-1, 16, len(data_f.columns))).sum(axis=1),index=["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"],columns=data_f.columns) + mutations_TSB_df_U = pd.DataFrame(U_mutations_df.values.reshape((-1, 16, len(data_f.columns))).sum(axis=1),index=["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"],columns=data_f.columns) + mutations_TSB_df_N = pd.DataFrame(N_mutations_df.values.reshape((-1, 16, len(data_f.columns))).sum(axis=1),index=["C>A", "C>G", "C>T", "T>A", "T>C", "T>G"],columns=data_f.columns) + mutations_TSB_df_T = mutations_TSB_df_T.append(mutations_TSB_df_T.sum().rename('All')) + mutations_TSB_df_U = mutations_TSB_df_U.append(mutations_TSB_df_U.sum().rename('All')) + mutations_TSB_df_N = mutations_TSB_df_N.append(mutations_TSB_df_N.sum().rename('All')) + mutations_TSB_df_T = mutations_TSB_df_T.reindex(np.roll(mutations_TSB_df_T.index, shift=1)) + mutations_TSB_df_U = mutations_TSB_df_U.reindex(np.roll(mutations_TSB_df_U.index, shift=1)) + mutations_TSB_df_N = mutations_TSB_df_N.reindex(np.roll(mutations_TSB_df_N.index, shift=1)) + return mutations_df,{'T':mutations_TSB_df_T,'U':mutations_TSB_df_U,'N':mutations_TSB_df_N} + def plotSV(matrix_path, output_path, project, plot_type="pdf", percentage=False, aggregate=False): """Outputs a pdf containing Rearrangement signature plots @@ -586,6 +732,339 @@ def plot(counts, labels, sample, project, percentage, aggregate=False, write_to_ return buff_list pp.close() +def plotSBSmod288(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): + plot_custom_text = False + sig_probs = False + pcawg = False + import pdb;pdb.set_trace() + + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + + import pdb;pdb.set_trace() + with open(matrix_path) as f: + next(f) + first_line = f.readline() + first_line = first_line.strip().split() + if first_line[0][6] == ">" or first_line[0][3] == ">": + pcawg = True + if first_line[0][7] != "]" and first_line[0][6] != ">" and first_line[0][3] != ">": + sys.exit("The matrix does not match the correct SBS288 format. Please check you formatting and rerun this plotting function.") + + pp = PdfPages(output_path + 'SBS_288_plots_' + project + '.pdf') + + mutations = OrderedDict() + mutations_TSB = OrderedDict() + total_count = [] + try: + with open (matrix_path) as f: + first_line = f.readline() + if pcawg: + samples = first_line.strip().split(",") + samples = samples[2:] + else: + samples = first_line.strip().split("\t") + samples = samples[1:] + + for sample in samples: + mutations[sample] = OrderedDict() + mutations[sample]['C>A'] = OrderedDict() + mutations[sample]['C>G'] = OrderedDict() + mutations[sample]['C>T'] = OrderedDict() + mutations[sample]['T>A'] = OrderedDict() + mutations[sample]['T>C'] = OrderedDict() + mutations[sample]['T>G'] = OrderedDict() + + mutations_TSB[sample] = OrderedDict() + mutations_TSB[sample]['All'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['C>A'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['C>G'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['C>T'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['T>A'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['T>C'] = OrderedDict({'T':0, 'U':0,'N':0}) + mutations_TSB[sample]['T>G'] = OrderedDict({'T':0, 'U':0,'N':0}) + + for lines in f: + if pcawg: + line = lines.strip().split(",") + mut_type = line[0] + nuc = line[1][0] + "[" + mut_type + "]" + line[1][2] + sample_index = 2 + else: + line = lines.strip().split() + nuc = line[0] + mut_type = line[0][4:7] + sample_index = 1 + tsb = nuc[0] + + + for sample in samples: + if percentage: + mutCount = float(line[sample_index]) + if mutCount < 1 and mutCount > 0: + sig_probs = True + else: + try: + mutCount = int(line[sample_index]) + except: + print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') + if nuc[2:] not in mutations[sample][mut_type]: + mutations[sample][mut_type][nuc[2:]] = mutCount + else: + mutations[sample][mut_type][nuc[2:]] += mutCount + mutations_TSB[sample][mut_type][tsb] += mutCount + mutations_TSB[sample]['All'][tsb] += mutCount + sample_index += 1 + + sample_count = 0 + pdb.set_trace() + data,tsb_mats = reindex_sbs288(data) + pdb.set_trace() + for sample in mutations.keys(): + total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='lightgray') + panel1 = plt.axes([0.04, 0.09, 0.7, 0.77]) + panel2 = plt.axes([0.77, 0.09, 0.21, 0.77]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + i = 0 + for key in mutations[sample]: + for seq in mutations[sample][key]: + xlabels.append(seq[0]+seq[2]+seq[6]) + if percentage: + if total_count > 0: + panel1.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) + if mutations[sample][key][seq]/total_count*100 > ymax: + ymax = mutations[sample][key][seq]/total_count*100 + else: + panel1.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) + if mutations[sample][key][seq] > ymax: + ymax = mutations[sample][key][seq] + x += 1 + i += 1 + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 6, 1): + panel1.add_patch(plt.Rectangle((x,y3), .11, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .117 + + yText = y3 + .06 + + + plt.text(.082, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.1975, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.315, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.43, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.55, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.665, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + y = ymax/1.025 + ytick_offest = float(y/3) + # ytick_offest = int(y/4) + + + if percentage: + ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] + ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + # ylabels= [str(0), str(round(ytick_offest)) + "%", str(round(ytick_offest*2)) + "%", + # str(round(ytick_offest*3)) + "%", str(round(ytick_offest*4)) + "%"] + else: + ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] + ylabels= [0, ytick_offest, ytick_offest*2, + ytick_offest*3, ytick_offest*4] + + font_label_size = 30 + if not percentage: + if int(ylabels[3]) >= 1000: + font_label_size = 20 + + if percentage: + if len(ylabels) > 2: + font_label_size = 20 + + labs = np.arange(0.375,96.375,1) + + if not percentage: + ylabels= getylabels(ylabels) + + panel1.set_xlim([0, 96]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + panel1.set_yticks(ylabs) + count = 0 + m = 0 + for i in range (0, 96, 1): + plt.text(i/137 + .04, .02, xlabels[i][0], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + plt.text(i/137 + .04, .044, xlabels[i][1], fontsize=25, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) + plt.text(i/137 + .04, .071, xlabels[i][2], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) + count += 1 + if count == 16: + count = 0 + m += 1 + + if sig_probs: + plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + else: + plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + + + + custom_text_upper_plot = '' + try: + custom_text_upper[sample_count] + except: + custom_text_upper = False + try: + custom_text_middle[sample_count] + except: + custom_text_middle = False + try: + custom_text_bottom[sample_count] + except: + custom_text_bottom = False + + if custom_text_upper: + plot_custom_text = True + if len(custom_text_upper[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + if custom_text_middle: + if len(custom_text_middle[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + + if plot_custom_text: + x_pos_custom = 0.73 + if custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] + if custom_text_bottom: + custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] + + if custom_text_upper and not custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right',zorder=1) + + elif custom_text_upper and custom_text_middle: + if not custom_text_bottom: + panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + else: + panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + elif not custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_middle[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + + + panel1.set_yticklabels(ylabels, fontsize=font_label_size) + # plt.gca().yaxis.grid(True) + # plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.yaxis.grid(True) + panel1.grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + if percentage: + panel1.set_ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + else: + panel1.set_ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + + [i.set_color("black") for i in panel1.get_yticklabels()] + + + yp2 = 28 + labels = [] + y2max = 0 + tsbColors = [[1/256,70/256,102/256], [228/256,41/256,38/256], 'green'] + for mut in mutations_TSB[sample]: + labels.append(mut) + i = 0 + for tsb in mutations_TSB[sample][mut]: + if tsb == "T": + label = "Genic-transcribed" + elif tsb == "U": + label = "Genic-untranscribed" + else: + label = "Intergenic" + if percentage: + if total_count > 0: + panel2.barh(yp2, mutations_TSB[sample][mut][tsb]/total_count*100,color=tsbColors[i], label=label) + if mutations_TSB[sample][mut][tsb]/total_count*100 > y2max: + y2max = mutations_TSB[sample][mut][tsb]/total_count*100 + else: + if mutations_TSB[sample][mut][tsb] > y2max: + y2max = mutations_TSB[sample][mut][tsb] + + panel2.barh(yp2, mutations_TSB[sample][mut][tsb], color=tsbColors[i], label=label) + yp2 -= 1 + i += 1 + yp2 -=1 + y = int(y2max*1.1) + if y <= 4: + y += 4 + while y%4 != 0: + y += 1 + ytick_offest = int(y/4) + + if percentage: + xlabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] + xlabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + else: + xlabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] + xlabels= [0, ytick_offest, ytick_offest*2, + ytick_offest*3, ytick_offest*4] + + + if not percentage: + xlabels = getxlabels(xlabels) + + panel2.spines['right'].set_visible(False) + panel2.spines['top'].set_visible(False) + labels.reverse() + panel2.set_yticks([3, 7, 11, 15, 19, 23, 27]) + panel2.set_yticklabels(labels, fontsize=30,fontname="Arial", weight = 'bold') + panel2.set_xticklabels(xlabels, fontsize=30) + panel2.set_xticks(xlabs) + handles, labels = panel2.get_legend_handles_labels() + panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) + pp.savefig(plot1) + plt.close() + sample_count += 1 + + pp.close() + except: + print("There may be an issue with the formatting of your matrix file.") + os.remove(output_path + 'SBS_288_plots_' + project + '.pdf') + def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): @@ -650,8 +1129,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%",str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, @@ -3005,128 +3483,52 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust elif plot_type == '288': - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - if first_line[0][6] == ">" or first_line[0][3] == ">": - pcawg = True - if first_line[0][7] != "]" and first_line[0][6] != ">" and first_line[0][3] != ">": - sys.exit("The matrix does not match the correct SBS288 format. Please check you formatting and rerun this plotting function.") - - pp = PdfPages(output_path + 'SBS_288_plots_' + project + '.pdf') - - mutations = OrderedDict() - mutations_TSB = OrderedDict() - total_count = [] try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[2:] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] + plot_custom_text = False + sig_probs = False + pcawg = False - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['C>A'] = OrderedDict() - mutations[sample]['C>G'] = OrderedDict() - mutations[sample]['C>T'] = OrderedDict() - mutations[sample]['T>A'] = OrderedDict() - mutations[sample]['T>C'] = OrderedDict() - mutations[sample]['T>G'] = OrderedDict() - - mutations_TSB[sample] = OrderedDict() - mutations_TSB[sample]['All'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>A'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>G'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>T'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>A'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>C'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>G'] = OrderedDict({'T':0, 'U':0,'N':0}) - - for lines in f: - if pcawg: - line = lines.strip().split(",") - mut_type = line[0] - nuc = line[1][0] + "[" + mut_type + "]" + line[1][2] - sample_index = 2 - else: - line = lines.strip().split() - nuc = line[0] - mut_type = line[0][4:7] - sample_index = 1 - tsb = nuc[0] - - - for sample in samples: - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') - if nuc[2:] not in mutations[sample][mut_type]: - mutations[sample][mut_type][nuc[2:]] = mutCount - else: - mutations[sample][mut_type][nuc[2:]] += mutCount - mutations_TSB[sample][mut_type][tsb] += mutCount - mutations_TSB[sample]['All'][tsb] += mutCount - sample_index += 1 + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + sample_count = 0 - for sample in mutations.keys(): - total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='lightgray') - panel1 = plt.axes([0.04, 0.09, 0.7, 0.77]) - panel2 = plt.axes([0.77, 0.09, 0.21, 0.77]) - xlabels = [] + data,tsb_mats = reindex_sbs288(data) + buf= io.BytesIO() + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS288.pkl','rb')) + pickle.dump(fig_orig, buf) + figs = {} + buff_list = {} + ctx = data.index + colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] + colorsall= [[colors[j] for i in range(int(len(ctx)/6))] for j in range(6)] + colors_flat_list = [item for sublist in colorsall for item in sublist] - x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] - i = 0 - for key in mutations[sample]: - for seq in mutations[sample][key]: - xlabels.append(seq[0]+seq[2]+seq[6]) - if percentage: - if total_count > 0: - panel1.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq]/total_count*100 > ymax: - ymax = mutations[sample][key][seq]/total_count*100 - else: - panel1.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq] > ymax: - ymax = mutations[sample][key][seq] - x += 1 - i += 1 + for sample in data.columns: - x = .043 - y3 = .87 - y = int(ymax*1.25) - y2 = y+2 - for i in range(0, 6, 1): - panel1.add_patch(plt.Rectangle((x,y3), .11, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .117 + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + panel2= figs[sample].axes[1] - yText = y3 + .06 + total_count = np.sum(data[sample].values) + muts = data[sample].values + x=0.4 + if percentage: + if total_count > 0: + panel1.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + panel1.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) - plt.text(.082, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.1975, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.315, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.43, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.55, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.665, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + y = int(ymax*1.25) if y <= 4: y += 4 @@ -3134,19 +3536,16 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust y += 1 y = ymax/1.025 ytick_offest = float(y/3) - # ytick_offest = int(y/4) - if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - # ylabels= [str(0), str(round(ytick_offest)) + "%", str(round(ytick_offest*2)) + "%", - # str(round(ytick_offest*3)) + "%", str(round(ytick_offest*4)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] font_label_size = 30 if not percentage: @@ -3160,54 +3559,14 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust labs = np.arange(0.375,96.375,1) if not percentage: - ylabels= getylabels(ylabels) - #ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if max(ylabels)< 10**5: - # ylabels = ['{:,.2f}'.format(x/1000)+'k' for x in ylabels] - # elif max(ylabels)>= 10**5: - # ylabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in ylabels] - - # if max(ylabels) >=10**9: - # ylabels = ["{:.2e}".format(x) for x in ylabels] - # else: - # if max(ylabels)< 10**5: - # ylabels = ['{:,.2f}'.format(x/1000)+'k' for x in ylabels] - # elif max(ylabels)>= 10**5: - # ylabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in ylabels] - - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp + ylabels= spplt.getylabels(ylabels) panel1.set_xlim([0, 96]) panel1.set_ylim([0, y]) - panel1.set_xticks(labs) + panel1.set_yticks(ylabs) - count = 0 - m = 0 - for i in range (0, 96, 1): - plt.text(i/137 + .04, .02, xlabels[i][0], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - plt.text(i/137 + .04, .044, xlabels[i][1], fontsize=25, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) - plt.text(i/137 + .04, .071, xlabels[i][2], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - count += 1 - if count == 16: - count = 0 - m += 1 + + if sig_probs: plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) @@ -3279,43 +3638,27 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) + bottom=False, labelbottom=False,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) [i.set_color("black") for i in panel1.get_yticklabels()] - yp2 = 28 labels = [] y2max = 0 tsbColors = [[1/256,70/256,102/256], [228/256,41/256,38/256], 'green'] - for mut in mutations_TSB[sample]: - labels.append(mut) - i = 0 - for tsb in mutations_TSB[sample][mut]: - if tsb == "T": - label = "Genic-transcribed" - elif tsb == "U": - label = "Genic-untranscribed" - else: - label = "Intergenic" - if percentage: - if total_count > 0: - panel2.barh(yp2, mutations_TSB[sample][mut][tsb]/total_count*100,color=tsbColors[i], label=label) - if mutations_TSB[sample][mut][tsb]/total_count*100 > y2max: - y2max = mutations_TSB[sample][mut][tsb]/total_count*100 - else: - if mutations_TSB[sample][mut][tsb] > y2max: - y2max = mutations_TSB[sample][mut][tsb] - panel2.barh(yp2, mutations_TSB[sample][mut][tsb], color=tsbColors[i], label=label) - yp2 -= 1 - i += 1 - yp2 -=1 + y2max= np.max([tsb_mats['T'][sample]['All'],tsb_mats['U'][sample]['All'],tsb_mats['N'][sample]['All']]) + + panel2.barh(range(28,1,-4),tsb_mats['T'][sample].values , color=tsbColors[0], label="Genic-transcribed") + panel2.barh(range(27,1,-4),tsb_mats['U'][sample].values , color=tsbColors[1], label="Genic-untranscribed") + panel2.barh(range(26,1,-4),tsb_mats['N'][sample].values , color=tsbColors[2], label="Intergenic") + labels=list(tsb_mats['T'][sample].index) + y = int(y2max*1.1) if y <= 4: y += 4 @@ -3326,48 +3669,16 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if percentage: xlabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] xlabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: xlabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] xlabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] if not percentage: - xlabels = getxlabels(xlabels) + xlabels = spplt.getxlabels(xlabels) - # if max(xlabels) >=10**10: - # xlabels = ["{:.2e}".format(x) for x in xlabels] - # else: - # if max(xlabels)< 10**5: - # xlabels = ['{:,.2f}'.format(x/1000)+'k' for x in xlabels] - # elif max(xlabels)>= 10**5: - # xlabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in xlabels] - - # import pdb - # pdb.set_trace() - # from decimal import Decimal - # xlabels = [str('%.2E') % Decimal(x) for x in xlabels] - #'%.2E' % Decimal('40800000000.00000000000000') - # xlabels = ['{:,}'.format(int(x)) for x in xlabels] - # if len(xlabels[-1]) > 3: - # xlabels_temp = [] - # if len(xlabels[-1]) > 7: - # for label in xlabels: - # if len(label) > 7: - # xlabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # xlabels_temp.append(label[0:-4] + "k") - # else: - # xlabels_temp.append(label) - - # else: - # for label in xlabels: - # if len(label) > 3: - # xlabels_temp.append(label[0:-4] + "k") - # else: - # xlabels_temp.append(label) - # xlabels = xlabels_temp panel2.spines['right'].set_visible(False) panel2.spines['top'].set_visible(False) labels.reverse() @@ -3377,11 +3688,29 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust panel2.set_xticks(xlabs) handles, labels = panel2.get_legend_handles_labels() panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) - pp.savefig(plot1) - plt.close() + # temp_plotsave(output_path,project,figs[sample]) + # pp.savefig(plot1) + # plt.close() sample_count += 1 + + if savefig_format == "pdf": + pp = PdfPages(output_path + 'SBS_288_plots_' + project + '.pdf') + + if savefig_format == "pdf": + for fig in figs: + figs[fig].savefig(pp, format='pdf') + pp.close() + + if savefig_format == "png": + for fig in figs: + figs[fig].savefig(output_path + 'SBS_288_plots_'+fig+'.png',dpi=100) + if savefig_format == "buffer_stream": + for fig in figs: + buffer2=io.BytesIO() + figs[fig].savefig(buffer2,format='png') + buff_list[fig]=buffer2 + return buff_list - pp.close() except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'SBS_288_plots_' + project + '.pdf') diff --git a/setup.py b/setup.py index 173dee1..ccbab2e 100644 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ def run(self): sigPlt.install_plot_templates('SBS288') os.system("echo 'installed figure templates' ") except: - print("Failed to install templates") + os.system("echo 'Failed to install templates' ") @@ -80,7 +80,7 @@ def run(self): license='UCSD', packages=['sigProfilerPlotting'], install_requires =[ - "matplotlib>=3.3.0,<=3.4.3", "pandas", "seaborn"], + "python>3.9","matplotlib>=3.3.0,<=3.4.3", "pandas", "seaborn"], package_data={'':['fonts/*.ttf']}, include_package_data=True, #Specify the custom install class From 764ae385e527e59b09d33759bc406c42fb6d67e8 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:46:30 -0700 Subject: [PATCH 12/21] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cba3405..d8b6f33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - '3.9' + - "3.10" install: - pip install -q matplotlib From 454a2b6ab27682e164e47d02a89b8ed14c6bb155 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:51:52 -0700 Subject: [PATCH 13/21] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d8b6f33..b300eaa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python -python: +python_version: - "3.10" install: From a0ab6cdf889097ee9ac42a76632c3d5c11a063d3 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 16:54:19 -0700 Subject: [PATCH 14/21] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b300eaa..d8b6f33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python -python_version: +python: - "3.10" install: From 7faaae52fef2d1d9f000087ceb58eec9fcc6f414 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 17:01:31 -0700 Subject: [PATCH 15/21] SBS 96 288 modifications --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ccbab2e..cde6fb6 100644 --- a/setup.py +++ b/setup.py @@ -80,7 +80,7 @@ def run(self): license='UCSD', packages=['sigProfilerPlotting'], install_requires =[ - "python>3.9","matplotlib>=3.3.0,<=3.4.3", "pandas", "seaborn"], + "matplotlib>=3.3.0,<=3.4.3", "pandas", "seaborn"], package_data={'':['fonts/*.ttf']}, include_package_data=True, #Specify the custom install class From 911cfbdec352529cc38ec22ed108995ff3fbd99b Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 17:05:48 -0700 Subject: [PATCH 16/21] SBS 96 288 modifications --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d8b6f33..bdd77ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - "3.10" + - "3.9" install: - pip install -q matplotlib From c63d5241d1f2e910a9ffb9e1803ef7ddb5628d3e Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 6 Sep 2022 17:08:53 -0700 Subject: [PATCH 17/21] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bdd77ab..ed441f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - "3.9" + - "3.9.13" install: - pip install -q matplotlib From bc8ab8df562452b07af970b7d61aea2835d20c6b Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Mon, 19 Sep 2022 12:13:05 -0700 Subject: [PATCH 18/21] remove unused functions --- sigProfilerPlotting/sigProfilerPlotting.py | 333 --------------------- 1 file changed, 333 deletions(-) diff --git a/sigProfilerPlotting/sigProfilerPlotting.py b/sigProfilerPlotting/sigProfilerPlotting.py index 545d4c1..1229673 100644 --- a/sigProfilerPlotting/sigProfilerPlotting.py +++ b/sigProfilerPlotting/sigProfilerPlotting.py @@ -732,339 +732,6 @@ def plot(counts, labels, sample, project, percentage, aggregate=False, write_to_ return buff_list pp.close() -def plotSBSmod288(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): - plot_custom_text = False - sig_probs = False - pcawg = False - import pdb;pdb.set_trace() - - if not isinstance(matrix_path, pd.DataFrame): - data=pd.read_csv(matrix_path,sep='\t',index_col=0) - data=data.dropna(axis=1, how='all') - - if data.isnull().values.any(): - raise ValueError("Input data contains Nans.") - - import pdb;pdb.set_trace() - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - if first_line[0][6] == ">" or first_line[0][3] == ">": - pcawg = True - if first_line[0][7] != "]" and first_line[0][6] != ">" and first_line[0][3] != ">": - sys.exit("The matrix does not match the correct SBS288 format. Please check you formatting and rerun this plotting function.") - - pp = PdfPages(output_path + 'SBS_288_plots_' + project + '.pdf') - - mutations = OrderedDict() - mutations_TSB = OrderedDict() - total_count = [] - try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[2:] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] - - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['C>A'] = OrderedDict() - mutations[sample]['C>G'] = OrderedDict() - mutations[sample]['C>T'] = OrderedDict() - mutations[sample]['T>A'] = OrderedDict() - mutations[sample]['T>C'] = OrderedDict() - mutations[sample]['T>G'] = OrderedDict() - - mutations_TSB[sample] = OrderedDict() - mutations_TSB[sample]['All'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>A'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>G'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>T'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>A'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>C'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>G'] = OrderedDict({'T':0, 'U':0,'N':0}) - - for lines in f: - if pcawg: - line = lines.strip().split(",") - mut_type = line[0] - nuc = line[1][0] + "[" + mut_type + "]" + line[1][2] - sample_index = 2 - else: - line = lines.strip().split() - nuc = line[0] - mut_type = line[0][4:7] - sample_index = 1 - tsb = nuc[0] - - - for sample in samples: - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') - if nuc[2:] not in mutations[sample][mut_type]: - mutations[sample][mut_type][nuc[2:]] = mutCount - else: - mutations[sample][mut_type][nuc[2:]] += mutCount - mutations_TSB[sample][mut_type][tsb] += mutCount - mutations_TSB[sample]['All'][tsb] += mutCount - sample_index += 1 - - sample_count = 0 - pdb.set_trace() - data,tsb_mats = reindex_sbs288(data) - pdb.set_trace() - for sample in mutations.keys(): - total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='lightgray') - panel1 = plt.axes([0.04, 0.09, 0.7, 0.77]) - panel2 = plt.axes([0.77, 0.09, 0.21, 0.77]) - xlabels = [] - - x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] - i = 0 - for key in mutations[sample]: - for seq in mutations[sample][key]: - xlabels.append(seq[0]+seq[2]+seq[6]) - if percentage: - if total_count > 0: - panel1.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq]/total_count*100 > ymax: - ymax = mutations[sample][key][seq]/total_count*100 - else: - panel1.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq] > ymax: - ymax = mutations[sample][key][seq] - x += 1 - i += 1 - - x = .043 - y3 = .87 - y = int(ymax*1.25) - y2 = y+2 - for i in range(0, 6, 1): - panel1.add_patch(plt.Rectangle((x,y3), .11, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .117 - - yText = y3 + .06 - - - plt.text(.082, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.1975, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.315, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.43, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.55, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.665, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - - if y <= 4: - y += 4 - - while y%4 != 0: - y += 1 - y = ymax/1.025 - ytick_offest = float(y/3) - # ytick_offest = int(y/4) - - - if percentage: - ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - # ylabels= [str(0), str(round(ytick_offest)) + "%", str(round(ytick_offest*2)) + "%", - # str(round(ytick_offest*3)) + "%", str(round(ytick_offest*4)) + "%"] - else: - ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] - ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] - - font_label_size = 30 - if not percentage: - if int(ylabels[3]) >= 1000: - font_label_size = 20 - - if percentage: - if len(ylabels) > 2: - font_label_size = 20 - - labs = np.arange(0.375,96.375,1) - - if not percentage: - ylabels= getylabels(ylabels) - - panel1.set_xlim([0, 96]) - panel1.set_ylim([0, y]) - panel1.set_xticks(labs) - panel1.set_yticks(ylabs) - count = 0 - m = 0 - for i in range (0, 96, 1): - plt.text(i/137 + .04, .02, xlabels[i][0], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - plt.text(i/137 + .04, .044, xlabels[i][1], fontsize=25, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) - plt.text(i/137 + .04, .071, xlabels[i][2], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - count += 1 - if count == 16: - count = 0 - m += 1 - - if sig_probs: - plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - else: - plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - - - - custom_text_upper_plot = '' - try: - custom_text_upper[sample_count] - except: - custom_text_upper = False - try: - custom_text_middle[sample_count] - except: - custom_text_middle = False - try: - custom_text_bottom[sample_count] - except: - custom_text_bottom = False - - if custom_text_upper: - plot_custom_text = True - if len(custom_text_upper[sample_count]) > 40: - print("To add a custom text, please limit the string to <40 characters including spaces.") - plot_custom_text = False - if custom_text_middle: - if len(custom_text_middle[sample_count]) > 40: - print("To add a custom text, please limit the string to <40 characters including spaces.") - plot_custom_text = False - - if plot_custom_text: - x_pos_custom = 0.73 - if custom_text_upper and custom_text_middle: - custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] - if custom_text_bottom: - custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] - - if custom_text_upper and not custom_text_middle: - custom_text_upper_plot = custom_text_upper[sample_count] - panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right',zorder=1) - - elif custom_text_upper and custom_text_middle: - if not custom_text_bottom: - panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - else: - panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - elif not custom_text_upper and custom_text_middle: - custom_text_upper_plot = custom_text_middle[sample_count] - panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - - - panel1.set_yticklabels(ylabels, fontsize=font_label_size) - # plt.gca().yaxis.grid(True) - # plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.yaxis.grid(True) - panel1.grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.set_xlabel('') - panel1.set_ylabel('') - - if percentage: - panel1.set_ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - else: - panel1.set_ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - - - - panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) - - - [i.set_color("black") for i in panel1.get_yticklabels()] - - - yp2 = 28 - labels = [] - y2max = 0 - tsbColors = [[1/256,70/256,102/256], [228/256,41/256,38/256], 'green'] - for mut in mutations_TSB[sample]: - labels.append(mut) - i = 0 - for tsb in mutations_TSB[sample][mut]: - if tsb == "T": - label = "Genic-transcribed" - elif tsb == "U": - label = "Genic-untranscribed" - else: - label = "Intergenic" - if percentage: - if total_count > 0: - panel2.barh(yp2, mutations_TSB[sample][mut][tsb]/total_count*100,color=tsbColors[i], label=label) - if mutations_TSB[sample][mut][tsb]/total_count*100 > y2max: - y2max = mutations_TSB[sample][mut][tsb]/total_count*100 - else: - if mutations_TSB[sample][mut][tsb] > y2max: - y2max = mutations_TSB[sample][mut][tsb] - - panel2.barh(yp2, mutations_TSB[sample][mut][tsb], color=tsbColors[i], label=label) - yp2 -= 1 - i += 1 - yp2 -=1 - y = int(y2max*1.1) - if y <= 4: - y += 4 - while y%4 != 0: - y += 1 - ytick_offest = int(y/4) - - if percentage: - xlabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - xlabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - else: - xlabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] - xlabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] - - - if not percentage: - xlabels = getxlabels(xlabels) - - panel2.spines['right'].set_visible(False) - panel2.spines['top'].set_visible(False) - labels.reverse() - panel2.set_yticks([3, 7, 11, 15, 19, 23, 27]) - panel2.set_yticklabels(labels, fontsize=30,fontname="Arial", weight = 'bold') - panel2.set_xticklabels(xlabels, fontsize=30) - panel2.set_xticks(xlabs) - handles, labels = panel2.get_legend_handles_labels() - panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) - pp.savefig(plot1) - plt.close() - sample_count += 1 - - pp.close() - except: - print("There may be an issue with the formatting of your matrix file.") - os.remove(output_path + 'SBS_288_plots_' + project + '.pdf') - def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): From f3f899b01a5f57c6ef578363a5d5ac46809a6269 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 4 Oct 2022 10:41:33 -0700 Subject: [PATCH 19/21] dbsplots modifications --- build/lib/sigProfilerPlotting/dbsplotsmod.py | 321 ++++ .../sigProfilerPlotting.py | 758 ++------ input/examples/samples/test1536.all | 1537 ----------------- setup.py | 3 +- sigProfilerPlotting/sigProfilerPlotting.py | 425 ++--- 5 files changed, 665 insertions(+), 2379 deletions(-) create mode 100644 build/lib/sigProfilerPlotting/dbsplotsmod.py delete mode 100755 input/examples/samples/test1536.all diff --git a/build/lib/sigProfilerPlotting/dbsplotsmod.py b/build/lib/sigProfilerPlotting/dbsplotsmod.py new file mode 100644 index 0000000..95ce50c --- /dev/null +++ b/build/lib/sigProfilerPlotting/dbsplotsmod.py @@ -0,0 +1,321 @@ +from bdb import set_trace +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt +import matplotlib.font_manager +from matplotlib.backends.backend_pdf import PdfPages +import matplotlib.patches as mplpatches +import matplotlib.ticker as ticker +from matplotlib.ticker import LinearLocator +import matplotlib.lines as lines +import matplotlib.transforms as transforms +import re +import os +import sys +import argparse +from collections import OrderedDict +import pandas as pd +import numpy as np +import io +import string +import warnings +import pickle +import sigProfilerPlotting as spplt +import pdb +import itertools,time +from sklearn.preprocessing import LabelEncoder + +warnings.filterwarnings("ignore") +def getdbstemp(context='DBS78',path='DBS78.pkl'): + # pp = PdfPages(output_path + 'DBS_78_plots_template' + '.pdf') + plot_custom_text = False + pcawg = False + sig_probs = False + plt.rcParams['axes.linewidth'] = 4 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='grey') + panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [3/256,102/256,204/256],[162/256,207/256,99/256], + [1/256,102/256,1/256], [255/256,153/256,153/256], [228/256,41/256,38/256], + [255/256,178/256,102/256], [255/256,128/256,1/256], [204/256,153/256,255/256], + [76/256,1/256,153/256]] + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + i = 0 + panel1.add_patch(plt.Rectangle((.043,y3), .101, .05, facecolor=colors[0], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.151,y3), .067, .05, facecolor=colors[1], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.225,y3), .102, .05, facecolor=colors[2], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.334,y3), .067, .05, facecolor=colors[3], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.408,y3), .102, .05, facecolor=colors[4], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.517,y3), .067, .05, facecolor=colors[5], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.591,y3), .067, .05, facecolor=colors[6], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.665,y3), .102, .05, facecolor=colors[7], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.774,y3), .102, .05, facecolor=colors[8], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.883,y3), .102, .05, facecolor=colors[9], clip_on=False, transform=plt.gcf().transFigure)) + + yText = y3 + .06 + plt.text(.07, yText, 'AC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.163, yText, 'AT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.255, yText, 'CC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.345, yText, 'CG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.435, yText, 'CT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.527, yText, 'GC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.6, yText, 'TA>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.69, yText, 'TC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.8, yText, 'TG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.915, yText, 'TT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + ytick_offest = int(y/4) + + labs = np.arange(0.44,78.44,1) + panel1.set_xlim([0, 78]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + # panel1.set_yticks(ylabs) + panel1.set_xticklabels(xlabels, rotation='vertical', fontsize=30, color='grey', fontname='Courier New', verticalalignment='top', fontweight='bold') + + # panel1.set_yticklabels(ylabels, fontsize=25) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + # if percentage: + # plt.ylabel("Percentage of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + # else: + # plt.ylabel("Number of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=True,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + [i.set_color("grey") for i in plt.gca().get_xticklabels()] + pickle.dump(plot1, open(path, 'wb')) + + # pp.savefig(plot1) + # plt.close() + # pp.close() + +def plotDBSmod(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None): + + # context ='DBS78' + # package_path = spplt.__path__[0] + # install_path =os.path.join(package_path,'templates/') + # if not os.path.exists(install_path): + # os.mkdir(install_path) + + # filename= os.path.join(install_path,context+'.pkl') + # getdbstemp(context,path=filename) + plot_custom_text = False + pcawg = False + sig_probs = False + if plot_type == '78' or plot_type == '78DBS' or plot_type == 'DBS78': + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + # import pdb; + # pdb.set_trace() + # with open(matrix_path) as f: + # next(f) + # first_line = f.readline() + # first_line = first_line.strip().split() + # mutation_type = first_line[0] + # if first_line[0][2] != ">": + # pcawg = True + # if len(mutation_type) != 5 and first_line[0][2] == ">": + # sys.exit("The matrix does not match the correct DBS96 format. Please check you formatting and rerun this plotting function.") + # pp = PdfPages(output_path + 'DBS_78_plots_' + project + '.pdf') + + dinucs = ['TT>GG','TT>CG','TT>AG','TT>GC','TT>CC','TT>AC','TT>GA','TT>CA','TT>AA','AC>CA','AC>CG','AC>CT','AC>GA', + 'AC>GG','AC>GT','AC>TA','AC>TG','AC>TT','CT>AA','CT>AC','CT>AG','CT>GA','CT>GC','CT>GG','CT>TG','CT>TC', + 'CT>TA','AT>CA','AT>CC','AT>CG','AT>GA','AT>GC','AT>TA','TG>GT','TG>CT','TG>AT','TG>GC','TG>CC','TG>AC', + 'TG>GA','TG>CA','TG>AA','CC>AA','CC>AG','CC>AT','CC>GA','CC>GG','CC>GT','CC>TA','CC>TG','CC>TT','CG>AT', + 'CG>GC','CG>GT','CG>TC','CG>TA','CG>TT','TC>GT','TC>CT','TC>AT','TC>GG','TC>CG','TC>AG','TC>GA','TC>CA', + 'TC>AA','GC>AA','GC>AG','GC>AT','GC>CA','GC>CG','GC>TA','TA>GT','TA>CT','TA>AT','TA>GG','TA>CG','TA>GC'] + + revcompl = lambda x: ''.join([{'A':'T','C':'G','G':'C','T':'A'}[B] for B in x][::-1]) + mutations = OrderedDict() + + + try: + vals=set(list(data.index))-set(dinucs) + vals=sorted(list(vals)) + for ech in vals: + ech_mod = ech.split('>')[0]+'>'+revcompl(ech.split('>')[1]) + data.rename(index={ech:ech_mod}, inplace=True) + + data = data.sort_index() + ctx = data.index + xlabels=[dn.split('>')[1] for dn in ctx] + colors = [[3/256,189/256,239/256], [3/256,102/256,204/256],[162/256,207/256,99/256], + [1/256,102/256,1/256], [255/256,153/256,153/256], [228/256,41/256,38/256], + [255/256,178/256,102/256], [255/256,128/256,1/256], [204/256,153/256,255/256], + [76/256,1/256,153/256]] + mainlist=[dn.split('>')[0] for dn in ctx] + le = LabelEncoder() + colors_idxs = le.fit_transform(mainlist) + colors_flat_list = [colors[i] for i in colors_idxs] + sample_count = 0 + + + buf= io.BytesIO() + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/DBS78.pkl','rb')) + pickle.dump(fig_orig, buf) + figs={} + + + for sample in data.columns: + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + total_count = np.sum(data[sample].values)#sum(sum(nuc.values()) for nuc in mutations[sample].values()) + + x = 0.4 + muts = data[sample].values + if percentage: + if total_count > 0: + plt.bar(np.asarray(range(len(ctx)))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + + plt.bar(np.asarray(range(len(ctx)))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) + # for i in range(len(xlabels)): + # print(xlabels[i],muts[i]) + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + i = 0 + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + ytick_offest = int(y/4) + + + if percentage: + ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] + ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + else: + ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] + ylabels= [0, ytick_offest, ytick_offest*2, + ytick_offest*3, ytick_offest*4] + + + if sig_probs: + plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + else: + plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " double subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + + custom_text_upper_plot = '' + try: + custom_text_upper[sample_count] + except: + custom_text_upper = False + try: + custom_text_middle[sample_count] + except: + custom_text_middle = False + try: + custom_text_bottom[sample_count] + except: + custom_text_bottom = False + + if custom_text_upper: + plot_custom_text = True + if len(custom_text_upper[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + if custom_text_bottom: + if len(custom_text_bottom[sample_count]) > 40: + print("To add a custom text, please limit the string to <40 characters including spaces.") + plot_custom_text = False + + if plot_custom_text: + x_pos_custom = 0.98 + if custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] + if custom_text_bottom: + custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] + + if custom_text_upper and not custom_text_middle: + custom_text_upper_plot = custom_text_upper[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + elif custom_text_upper and custom_text_middle: + if not custom_text_bottom: + panel1.text(x_pos_custom, 0.75, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + else: + panel1.text(x_pos_custom, 0.7, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + elif not custom_text_upper and custom_text_middle: + custom_text_upper_plot = custom_text_middle[sample_count] + panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + + if not percentage: + ylabels =spplt.getylabels(ylabels) + + labs = np.arange(0.44,78.44,1) + panel1.set_xlim([0, 78]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + panel1.set_yticks(ylabs) + panel1.set_xticklabels(xlabels, rotation='vertical', fontsize=30, color='grey', fontname='Courier New', verticalalignment='top', fontweight='bold') + + panel1.set_yticklabels(ylabels, fontsize=25) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + if percentage: + plt.ylabel("Percentage of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + else: + plt.ylabel("Number of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=True,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + [i.set_color("grey") for i in plt.gca().get_xticklabels()] + + # pp.savefig(plot1) + # plt.close() + # sample_count += 1 + pp = PdfPages(output_path + 'DBS_78_plots_' + project + '.pdf') + for fig in figs: + figs[fig].savefig(pp, format='pdf') + pp.close() + + except: + print("There may be an issue with the formatting of your matrix file.") + os.remove(output_path + 'DBS_78_plots_' + project + '.pdf') \ No newline at end of file diff --git a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py index 545d4c1..9cc62a0 100644 --- a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py +++ b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py @@ -29,6 +29,8 @@ import sigProfilerPlotting as spplt import pdb import itertools,time +import sklearn +from sklearn.preprocessing import LabelEncoder warnings.filterwarnings("ignore") @@ -262,8 +264,88 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): handles, labels = panel2.get_legend_handles_labels() panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) pickle.dump(plot1, open(path, 'wb')) - + + elif context =='DBS78': + + plot_custom_text = False + pcawg = False + sig_probs = False + plt.rcParams['axes.linewidth'] = 4 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='grey') + panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [3/256,102/256,204/256],[162/256,207/256,99/256], + [1/256,102/256,1/256], [255/256,153/256,153/256], [228/256,41/256,38/256], + [255/256,178/256,102/256], [255/256,128/256,1/256], [204/256,153/256,255/256], + [76/256,1/256,153/256]] + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + i = 0 + panel1.add_patch(plt.Rectangle((.043,y3), .101, .05, facecolor=colors[0], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.151,y3), .067, .05, facecolor=colors[1], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.225,y3), .102, .05, facecolor=colors[2], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.334,y3), .067, .05, facecolor=colors[3], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.408,y3), .102, .05, facecolor=colors[4], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.517,y3), .067, .05, facecolor=colors[5], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.591,y3), .067, .05, facecolor=colors[6], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.665,y3), .102, .05, facecolor=colors[7], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.774,y3), .102, .05, facecolor=colors[8], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.883,y3), .102, .05, facecolor=colors[9], clip_on=False, transform=plt.gcf().transFigure)) + + yText = y3 + .06 + plt.text(.07, yText, 'AC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.163, yText, 'AT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.255, yText, 'CC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.345, yText, 'CG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.435, yText, 'CT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.527, yText, 'GC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.6, yText, 'TA>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.69, yText, 'TC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.8, yText, 'TG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.915, yText, 'TT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + ytick_offest = int(y/4) + + labs = np.arange(0.44,78.44,1) + panel1.set_xlim([0, 78]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + # panel1.set_yticks(ylabs) + panel1.set_xticklabels(xlabels, rotation='vertical', fontsize=30, color='grey', fontname='Courier New', verticalalignment='top', fontweight='bold') + + # panel1.set_yticklabels(ylabels, fontsize=25) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + # if percentage: + # plt.ylabel("Percentage of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + # else: + # plt.ylabel("Number of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=True,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + [i.set_color("black") for i in plt.gca().get_yticklabels()] + [i.set_color("grey") for i in plt.gca().get_xticklabels()] + pickle.dump(plot1, open(path, 'wb')) @@ -732,339 +814,6 @@ def plot(counts, labels, sample, project, percentage, aggregate=False, write_to_ return buff_list pp.close() -def plotSBSmod288(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): - plot_custom_text = False - sig_probs = False - pcawg = False - import pdb;pdb.set_trace() - - if not isinstance(matrix_path, pd.DataFrame): - data=pd.read_csv(matrix_path,sep='\t',index_col=0) - data=data.dropna(axis=1, how='all') - - if data.isnull().values.any(): - raise ValueError("Input data contains Nans.") - - import pdb;pdb.set_trace() - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - if first_line[0][6] == ">" or first_line[0][3] == ">": - pcawg = True - if first_line[0][7] != "]" and first_line[0][6] != ">" and first_line[0][3] != ">": - sys.exit("The matrix does not match the correct SBS288 format. Please check you formatting and rerun this plotting function.") - - pp = PdfPages(output_path + 'SBS_288_plots_' + project + '.pdf') - - mutations = OrderedDict() - mutations_TSB = OrderedDict() - total_count = [] - try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[2:] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] - - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['C>A'] = OrderedDict() - mutations[sample]['C>G'] = OrderedDict() - mutations[sample]['C>T'] = OrderedDict() - mutations[sample]['T>A'] = OrderedDict() - mutations[sample]['T>C'] = OrderedDict() - mutations[sample]['T>G'] = OrderedDict() - - mutations_TSB[sample] = OrderedDict() - mutations_TSB[sample]['All'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>A'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>G'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['C>T'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>A'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>C'] = OrderedDict({'T':0, 'U':0,'N':0}) - mutations_TSB[sample]['T>G'] = OrderedDict({'T':0, 'U':0,'N':0}) - - for lines in f: - if pcawg: - line = lines.strip().split(",") - mut_type = line[0] - nuc = line[1][0] + "[" + mut_type + "]" + line[1][2] - sample_index = 2 - else: - line = lines.strip().split() - nuc = line[0] - mut_type = line[0][4:7] - sample_index = 1 - tsb = nuc[0] - - - for sample in samples: - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') - if nuc[2:] not in mutations[sample][mut_type]: - mutations[sample][mut_type][nuc[2:]] = mutCount - else: - mutations[sample][mut_type][nuc[2:]] += mutCount - mutations_TSB[sample][mut_type][tsb] += mutCount - mutations_TSB[sample]['All'][tsb] += mutCount - sample_index += 1 - - sample_count = 0 - pdb.set_trace() - data,tsb_mats = reindex_sbs288(data) - pdb.set_trace() - for sample in mutations.keys(): - total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='lightgray') - panel1 = plt.axes([0.04, 0.09, 0.7, 0.77]) - panel2 = plt.axes([0.77, 0.09, 0.21, 0.77]) - xlabels = [] - - x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [1/256,1/256,1/256],[228/256,41/256,38/256], [203/256,202/256,202/256], [162/256,207/256,99/256], [236/256,199/256,197/256]] - i = 0 - for key in mutations[sample]: - for seq in mutations[sample][key]: - xlabels.append(seq[0]+seq[2]+seq[6]) - if percentage: - if total_count > 0: - panel1.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq]/total_count*100 > ymax: - ymax = mutations[sample][key][seq]/total_count*100 - else: - panel1.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq] > ymax: - ymax = mutations[sample][key][seq] - x += 1 - i += 1 - - x = .043 - y3 = .87 - y = int(ymax*1.25) - y2 = y+2 - for i in range(0, 6, 1): - panel1.add_patch(plt.Rectangle((x,y3), .11, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .117 - - yText = y3 + .06 - - - plt.text(.082, yText, 'C>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.1975, yText, 'C>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.315, yText, 'C>T', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.43, yText, 'T>A', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.55, yText, 'T>C', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.665, yText, 'T>G', fontsize=55, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - - if y <= 4: - y += 4 - - while y%4 != 0: - y += 1 - y = ymax/1.025 - ytick_offest = float(y/3) - # ytick_offest = int(y/4) - - - if percentage: - ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - # ylabels= [str(0), str(round(ytick_offest)) + "%", str(round(ytick_offest*2)) + "%", - # str(round(ytick_offest*3)) + "%", str(round(ytick_offest*4)) + "%"] - else: - ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] - ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] - - font_label_size = 30 - if not percentage: - if int(ylabels[3]) >= 1000: - font_label_size = 20 - - if percentage: - if len(ylabels) > 2: - font_label_size = 20 - - labs = np.arange(0.375,96.375,1) - - if not percentage: - ylabels= getylabels(ylabels) - - panel1.set_xlim([0, 96]) - panel1.set_ylim([0, y]) - panel1.set_xticks(labs) - panel1.set_yticks(ylabs) - count = 0 - m = 0 - for i in range (0, 96, 1): - plt.text(i/137 + .04, .02, xlabels[i][0], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - plt.text(i/137 + .04, .044, xlabels[i][1], fontsize=25, color=colors[m], rotation='vertical', verticalalignment='center', fontname='Courier New', fontweight='bold',transform=plt.gcf().transFigure) - plt.text(i/137 + .04, .071, xlabels[i][2], fontsize=25, color='gray', rotation='vertical', verticalalignment='center', fontname='Courier New', transform=plt.gcf().transFigure) - count += 1 - if count == 16: - count = 0 - m += 1 - - if sig_probs: - plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - else: - plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - - - - custom_text_upper_plot = '' - try: - custom_text_upper[sample_count] - except: - custom_text_upper = False - try: - custom_text_middle[sample_count] - except: - custom_text_middle = False - try: - custom_text_bottom[sample_count] - except: - custom_text_bottom = False - - if custom_text_upper: - plot_custom_text = True - if len(custom_text_upper[sample_count]) > 40: - print("To add a custom text, please limit the string to <40 characters including spaces.") - plot_custom_text = False - if custom_text_middle: - if len(custom_text_middle[sample_count]) > 40: - print("To add a custom text, please limit the string to <40 characters including spaces.") - plot_custom_text = False - - if plot_custom_text: - x_pos_custom = 0.73 - if custom_text_upper and custom_text_middle: - custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] - if custom_text_bottom: - custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] - - if custom_text_upper and not custom_text_middle: - custom_text_upper_plot = custom_text_upper[sample_count] - panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right',zorder=1) - - elif custom_text_upper and custom_text_middle: - if not custom_text_bottom: - panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - else: - panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - elif not custom_text_upper and custom_text_middle: - custom_text_upper_plot = custom_text_middle[sample_count] - panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=40, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - - - panel1.set_yticklabels(ylabels, fontsize=font_label_size) - # plt.gca().yaxis.grid(True) - # plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.yaxis.grid(True) - panel1.grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) - panel1.set_xlabel('') - panel1.set_ylabel('') - - if percentage: - panel1.set_ylabel("Percentage of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - else: - panel1.set_ylabel("Number of Single Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') - - - - panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) - - - [i.set_color("black") for i in panel1.get_yticklabels()] - - - yp2 = 28 - labels = [] - y2max = 0 - tsbColors = [[1/256,70/256,102/256], [228/256,41/256,38/256], 'green'] - for mut in mutations_TSB[sample]: - labels.append(mut) - i = 0 - for tsb in mutations_TSB[sample][mut]: - if tsb == "T": - label = "Genic-transcribed" - elif tsb == "U": - label = "Genic-untranscribed" - else: - label = "Intergenic" - if percentage: - if total_count > 0: - panel2.barh(yp2, mutations_TSB[sample][mut][tsb]/total_count*100,color=tsbColors[i], label=label) - if mutations_TSB[sample][mut][tsb]/total_count*100 > y2max: - y2max = mutations_TSB[sample][mut][tsb]/total_count*100 - else: - if mutations_TSB[sample][mut][tsb] > y2max: - y2max = mutations_TSB[sample][mut][tsb] - - panel2.barh(yp2, mutations_TSB[sample][mut][tsb], color=tsbColors[i], label=label) - yp2 -= 1 - i += 1 - yp2 -=1 - y = int(y2max*1.1) - if y <= 4: - y += 4 - while y%4 != 0: - y += 1 - ytick_offest = int(y/4) - - if percentage: - xlabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - xlabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - else: - xlabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] - xlabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] - - - if not percentage: - xlabels = getxlabels(xlabels) - - panel2.spines['right'].set_visible(False) - panel2.spines['top'].set_visible(False) - labels.reverse() - panel2.set_yticks([3, 7, 11, 15, 19, 23, 27]) - panel2.set_yticklabels(labels, fontsize=30,fontname="Arial", weight = 'bold') - panel2.set_xticklabels(xlabels, fontsize=30) - panel2.set_xticks(xlabs) - handles, labels = panel2.get_legend_handles_labels() - panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) - pp.savefig(plot1) - plt.close() - sample_count += 1 - - pp.close() - except: - print("There may be an issue with the formatting of your matrix file.") - os.remove(output_path + 'SBS_288_plots_' + project + '.pdf') - def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format="pdf"): @@ -3872,25 +3621,6 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if not percentage: ylabels = getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 96]) panel1.set_ylim([0, y]) @@ -4275,25 +4005,6 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo if not percentage: ylabels=getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 83]) panel1.set_ylim([0, y]) @@ -5138,25 +4849,6 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo if not percentage: ylabels = getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 83]) panel1.set_ylim([0, y]) @@ -5253,154 +4945,101 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo print("The provided plot_type: ", plot_type, " is not supported by this plotting function") def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None): - # if 'roman' in matplotlib.font_manager.weight_dict: - # del matplotlib.font_manager.weight_dict['roman'] - # matplotlib.font_manager._rebuild() + + + # context ='DBS78' + # package_path = spplt.__path__[0] + # install_path =os.path.join(package_path,'templates/') + # if not os.path.exists(install_path): + # os.mkdir(install_path) + + # filename= os.path.join(install_path,context+'.pkl') + # getdbstemp(context,path=filename) plot_custom_text = False pcawg = False sig_probs = False if plot_type == '78' or plot_type == '78DBS' or plot_type == 'DBS78': - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - mutation_type = first_line[0] - if first_line[0][2] != ">": - pcawg = True - if len(mutation_type) != 5 and first_line[0][2] == ">": - sys.exit("The matrix does not match the correct DBS96 format. Please check you formatting and rerun this plotting function.") - pp = PdfPages(output_path + 'DBS_78_plots_' + project + '.pdf') + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + # import pdb; + # pdb.set_trace() + # with open(matrix_path) as f: + # next(f) + # first_line = f.readline() + # first_line = first_line.strip().split() + # mutation_type = first_line[0] + # if first_line[0][2] != ">": + # pcawg = True + # if len(mutation_type) != 5 and first_line[0][2] == ">": + # sys.exit("The matrix does not match the correct DBS96 format. Please check you formatting and rerun this plotting function.") + # pp = PdfPages(output_path + 'DBS_78_plots_' + project + '.pdf') dinucs = ['TT>GG','TT>CG','TT>AG','TT>GC','TT>CC','TT>AC','TT>GA','TT>CA','TT>AA','AC>CA','AC>CG','AC>CT','AC>GA', - 'AC>GG','AC>GT','AC>TA','AC>TG','AC>TT','CT>AA','CT>AC','CT>AG','CT>GA','CT>GC','CT>GG','CT>TG','CT>TC', - 'CT>TA','AT>CA','AT>CC','AT>CG','AT>GA','AT>GC','AT>TA','TG>GT','TG>CT','TG>AT','TG>GC','TG>CC','TG>AC', - 'TG>GA','TG>CA','TG>AA','CC>AA','CC>AG','CC>AT','CC>GA','CC>GG','CC>GT','CC>TA','CC>TG','CC>TT','CG>AT', - 'CG>GC','CG>GT','CG>TC','CG>TA','CG>TT','TC>GT','TC>CT','TC>AT','TC>GG','TC>CG','TC>AG','TC>GA','TC>CA', - 'TC>AA','GC>AA','GC>AG','GC>AT','GC>CA','GC>CG','GC>TA','TA>GT','TA>CT','TA>AT','TA>GG','TA>CG','TA>GC'] + 'AC>GG','AC>GT','AC>TA','AC>TG','AC>TT','CT>AA','CT>AC','CT>AG','CT>GA','CT>GC','CT>GG','CT>TG','CT>TC', + 'CT>TA','AT>CA','AT>CC','AT>CG','AT>GA','AT>GC','AT>TA','TG>GT','TG>CT','TG>AT','TG>GC','TG>CC','TG>AC', + 'TG>GA','TG>CA','TG>AA','CC>AA','CC>AG','CC>AT','CC>GA','CC>GG','CC>GT','CC>TA','CC>TG','CC>TT','CG>AT', + 'CG>GC','CG>GT','CG>TC','CG>TA','CG>TT','TC>GT','TC>CT','TC>AT','TC>GG','TC>CG','TC>AG','TC>GA','TC>CA', + 'TC>AA','GC>AA','GC>AG','GC>AT','GC>CA','GC>CG','GC>TA','TA>GT','TA>CT','TA>AT','TA>GG','TA>CG','TA>GC'] revcompl = lambda x: ''.join([{'A':'T','C':'G','G':'C','T':'A'}[B] for B in x][::-1]) mutations = OrderedDict() + try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[2:] - samples = [x.replace('"','') for x in samples] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['AC'] = OrderedDict() - mutations[sample]['AT'] = OrderedDict() - mutations[sample]['CC'] = OrderedDict() - mutations[sample]['CG'] = OrderedDict() - mutations[sample]['CT'] = OrderedDict() - mutations[sample]['GC'] = OrderedDict() - mutations[sample]['TA'] = OrderedDict() - mutations[sample]['TC'] = OrderedDict() - mutations[sample]['TG'] = OrderedDict() - mutations[sample]['TT'] = OrderedDict() - + vals=set(list(data.index))-set(dinucs) + vals=sorted(list(vals)) + for ech in vals: + ech_mod = ech.split('>')[0]+'>'+revcompl(ech.split('>')[1]) + data.rename(index={ech:ech_mod}, inplace=True) + + data = data.sort_index() + ctx = data.index + xlabels=[dn.split('>')[1] for dn in ctx] + colors = [[3/256,189/256,239/256], [3/256,102/256,204/256],[162/256,207/256,99/256], + [1/256,102/256,1/256], [255/256,153/256,153/256], [228/256,41/256,38/256], + [255/256,178/256,102/256], [255/256,128/256,1/256], [204/256,153/256,255/256], + [76/256,1/256,153/256]] + mainlist=[dn.split('>')[0] for dn in ctx] + le = LabelEncoder() + colors_idxs = le.fit_transform(mainlist) + colors_flat_list = [colors[i] for i in colors_idxs] + sample_count = 0 - for lines in f: - if pcawg: - line = lines.strip().split(",") - line = [x.replace('"','') for x in line] - mut = line[0] + ">" + line[1] - nuc = line[1] - mut_type = line[0] - if mut not in dinucs: - nuc = revcompl(nuc) - mut_type = revcompl(mut_type) - sample_index = 2 - else: - line = lines.strip().split() - mut = line[0] - nuc = line[0][3:] - mut_type = line[0][0:2] - if mut not in dinucs: - nuc = revcompl(nuc) - mut_type = revcompl(mut_type) - sample_index = 1 - for sample in samples: - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') + buf= io.BytesIO() + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/DBS78.pkl','rb')) + pickle.dump(fig_orig, buf) + figs={} - # mutCount = int(line[sample_index]) - mutations[sample][mut_type][nuc] = mutCount - sample_index += 1 - sample_count = 0 - for sample in mutations.keys(): - total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 4 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='grey') - panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) - xlabels = [] + for sample in data.columns: + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + total_count = np.sum(data[sample].values)#sum(sum(nuc.values()) for nuc in mutations[sample].values()) x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [3/256,102/256,204/256],[162/256,207/256,99/256], - [1/256,102/256,1/256], [255/256,153/256,153/256], [228/256,41/256,38/256], - [255/256,178/256,102/256], [255/256,128/256,1/256], [204/256,153/256,255/256], - [76/256,1/256,153/256]] - i = 0 - for key in mutations[sample]: - muts = mutations[sample][key].keys() - muts = sorted(muts) - for seq in muts: - xlabels.append(seq) - if percentage: - if total_count > 0: - plt.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq]/total_count*100 > ymax: - ymax = mutations[sample][key][seq]/total_count*100 - else: - plt.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq] > ymax: - ymax = mutations[sample][key][seq] - x += 1 - i += 1 + muts = data[sample].values + if percentage: + if total_count > 0: + plt.bar(np.asarray(range(len(ctx)))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + + plt.bar(np.asarray(range(len(ctx)))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) + # for i in range(len(xlabels)): + # print(xlabels[i],muts[i]) x = .043 y3 = .87 y = int(ymax*1.25) y2 = y+2 i = 0 - panel1.add_patch(plt.Rectangle((.043,y3), .101, .05, facecolor=colors[0], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.151,y3), .067, .05, facecolor=colors[1], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.225,y3), .102, .05, facecolor=colors[2], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.334,y3), .067, .05, facecolor=colors[3], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.408,y3), .102, .05, facecolor=colors[4], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.517,y3), .067, .05, facecolor=colors[5], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.591,y3), .067, .05, facecolor=colors[6], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.665,y3), .102, .05, facecolor=colors[7], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.774,y3), .102, .05, facecolor=colors[8], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.883,y3), .102, .05, facecolor=colors[9], clip_on=False, transform=plt.gcf().transFigure)) - - yText = y3 + .06 - plt.text(.07, yText, 'AC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.163, yText, 'AT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.255, yText, 'CC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.345, yText, 'CG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.435, yText, 'CT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.527, yText, 'GC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.6, yText, 'TA>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.69, yText, 'TC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.8, yText, 'TG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.915, yText, 'TT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) if y <= 4: y += 4 @@ -5413,11 +5052,11 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] if sig_probs: @@ -5471,33 +5110,8 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - - - - if not percentage: - ylabels =getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp - + ylabels =spplt.getylabels(ylabels) labs = np.arange(0.44,78.44,1) panel1.set_xlim([0, 78]) @@ -5518,19 +5132,23 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust plt.ylabel("Number of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=True,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) + bottom=False, labelbottom=True,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) [i.set_color("black") for i in plt.gca().get_yticklabels()] [i.set_color("grey") for i in plt.gca().get_xticklabels()] - pp.savefig(plot1) - plt.close() - sample_count += 1 + # pp.savefig(plot1) + # plt.close() + # sample_count += 1 + pp = PdfPages(output_path + 'DBS_78_plots_' + project + '.pdf') + for fig in figs: + figs[fig].savefig(pp, format='pdf') pp.close() + except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'DBS_78_plots_' + project + '.pdf') @@ -5699,26 +5317,6 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust if not percentage: ylabels= getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp - labs = np.arange(0.55,36.44,1) panel1.set_xlim([0, 36]) @@ -5759,18 +5357,4 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust os.remove(output_path + 'DBS_186_plots_' + project + '.pdf') else: - print("The provided plot_type: ", plot_type, " is not supported by this plotting function") - - -# def main(): -# # # #plotSBS("/Users/ebergstr/Desktop/AID/output/SBS/AID.SBS384.all", "/Users/ebergstr/Desktop/", "AID", '384', False, custom_text_upper=['Similarity to PCAWG: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7'], custom_text_bottom=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9']) -# plotID("/Users/ebergstr/Desktop/BRCA/output/INDEL/BRCA.INDEL83.all", "/Users/ebergstr/Desktop/", "BRCA", '83', True, custom_text_upper=['Similarity to PCAWG: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7'], custom_text_middle=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9'], custom_text_bottom=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9']) -# # # plotDBS("/Users/ebergstr/Desktop/Mel/output/DINUC/Mel.DBS186.all", "/Users/ebergstr/Desktop/", "Mel", '186', False, custom_text_upper=['Similarity to PCAWG: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7'], custom_text_middle=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9'], custom_text_bottom=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9']) - -# # # # #plotSBS("/Users/ebergstr/Desktop/BRCA/output/SBS/BRCA.SBS1536.all", "/Users/ebergstr/Desktop/", "BRCA", '1536', False, custom_text_upper=['Similarity to PCAWG: 0.98'], custom_text_middle= ['Similarity to PCAWG: 0.98'], custom_text_bottom=['Stability: 0.98']) -# # # #plotSBS("/Users/ebergstr/Desktop/BRCA/output/SBS/BRCA.SBS1536.all", "/Users/ebergstr/Desktop/", "BRCA", '1536', False, custom_text_upper=['Similarity to PCAWG: 0.98'], custom_text_middle= ['Similarity to PCAWG: 0.98']) - -# # # # plotDBS("/Users/ebergstr/Downloads/Biliary-AdenoCA.dinucs.csv", "/Users/ebergstr/Desktop/", "test", '78', False) - -# if __name__ == '__main__': -# main() + print("The provided plot_type: ", plot_type, " is not supported by this plotting function") \ No newline at end of file diff --git a/input/examples/samples/test1536.all b/input/examples/samples/test1536.all deleted file mode 100755 index a1a8965..0000000 --- a/input/examples/samples/test1536.all +++ /dev/null @@ -1,1537 +0,0 @@ -MutationType Sample 1 Sample 2 Sample 3 Sample 4 Sample 5 Sample 6 Sample 7 Sample 8 Sample 9 Sample 10 Sample 11 Sample 12 Sample 13 Sample 14 Sample 15 -AA[C>A]AA 43 13 46 35 18 6 15 14 14 14 3 10 25 14 14 -AA[C>A]AC 13 6 23 11 5 1 3 8 7 5 1 2 7 10 5 -AA[C>A]AG 18 5 14 7 4 4 2 4 6 5 2 1 6 5 5 -AA[C>A]AT 16 7 21 19 6 1 10 8 12 16 4 5 15 7 7 -AA[C>A]CA 19 6 19 8 7 1 6 8 7 8 2 3 4 12 4 -AA[C>A]CC 9 0 4 6 8 2 2 7 6 1 1 2 10 4 2 -AA[C>A]CG 3 0 0 0 0 0 0 0 0 0 0 0 1 0 0 -AA[C>A]CT 12 7 8 13 10 1 8 11 5 6 0 3 8 10 4 -AA[C>A]GA 5 1 2 4 2 0 1 2 1 1 0 1 1 0 0 -AA[C>A]GC 1 0 0 0 0 0 0 2 1 0 0 1 2 1 2 -AA[C>A]GG 2 0 1 2 0 1 3 0 0 0 0 1 0 1 1 -AA[C>A]GT 2 1 1 3 1 1 2 1 0 2 2 0 2 0 2 -AA[C>A]TA 15 5 14 4 4 5 4 7 1 2 2 1 1 5 3 -AA[C>A]TC 8 4 5 7 3 0 4 3 6 7 0 3 8 7 2 -AA[C>A]TG 11 6 11 5 6 0 1 6 6 4 1 1 7 4 5 -AA[C>A]TT 10 6 14 7 5 2 3 10 7 8 0 6 7 8 6 -AA[C>G]AA 11 4 8 10 8 2 7 10 7 9 0 2 8 8 7 -AA[C>G]AC 1 1 2 2 1 0 1 3 0 4 0 1 2 0 3 -AA[C>G]AG 4 9 8 4 7 3 5 8 4 7 2 3 12 11 5 -AA[C>G]AT 8 2 1 1 2 0 4 5 2 4 0 1 2 1 0 -AA[C>G]CA 6 5 7 6 5 0 2 11 3 3 0 1 5 2 4 -AA[C>G]CC 2 0 2 1 2 0 3 1 1 3 1 1 0 1 1 -AA[C>G]CG 1 1 1 1 0 0 1 1 1 0 0 0 1 0 0 -AA[C>G]CT 10 1 4 2 4 0 1 6 3 4 0 1 1 4 2 -AA[C>G]GA 1 1 1 0 0 1 1 0 1 3 1 0 1 1 0 -AA[C>G]GC 0 0 0 0 1 0 1 0 0 1 1 0 2 0 0 -AA[C>G]GG 2 0 1 0 2 0 1 0 1 1 0 0 0 1 0 -AA[C>G]GT 0 1 1 1 1 0 1 1 2 3 0 1 0 1 0 -AA[C>G]TA 10 6 5 2 7 0 3 11 4 13 1 1 2 5 2 -AA[C>G]TC 2 1 8 3 1 0 3 2 9 1 1 2 1 1 1 -AA[C>G]TG 5 2 4 2 8 1 4 7 5 8 3 0 4 2 1 -AA[C>G]TT 6 2 13 5 5 1 5 8 7 6 0 1 4 6 2 -AA[C>T]AA 16 12 8 14 6 4 6 8 7 11 1 5 12 8 6 -AA[C>T]AC 10 0 5 3 5 2 0 9 3 4 1 1 5 4 6 -AA[C>T]AG 13 6 10 9 5 4 1 9 3 3 2 0 5 5 7 -AA[C>T]AT 23 9 19 17 11 3 11 12 14 13 4 3 10 14 10 -AA[C>T]CA 12 8 7 4 9 0 5 7 2 6 3 2 1 4 5 -AA[C>T]CC 4 6 6 2 4 0 3 10 4 4 0 2 1 4 0 -AA[C>T]CG 1 0 1 0 0 0 0 3 1 1 0 0 0 0 0 -AA[C>T]CT 11 9 5 5 3 3 10 4 5 10 1 7 10 0 7 -AA[C>T]GA 22 8 10 14 13 4 8 5 4 21 1 4 8 2 7 -AA[C>T]GC 16 10 3 6 3 1 7 5 5 13 0 0 6 5 4 -AA[C>T]GG 20 6 8 10 10 4 5 9 6 7 1 0 10 3 4 -AA[C>T]GT 22 11 6 13 5 1 4 3 4 11 0 2 9 7 2 -AA[C>T]TA 8 5 11 4 5 3 2 4 4 5 4 3 5 1 4 -AA[C>T]TC 7 5 4 6 4 0 6 5 7 9 0 0 6 7 2 -AA[C>T]TG 8 9 9 3 2 1 3 6 7 3 1 2 2 4 2 -AA[C>T]TT 6 4 7 11 6 3 5 9 7 4 3 1 5 3 3 -AA[T>A]AA 28 4 11 6 9 4 5 10 9 9 2 3 7 7 6 -AA[T>A]AC 17 3 3 4 6 5 5 7 3 3 1 2 4 3 1 -AA[T>A]AG 14 3 5 4 3 4 1 4 3 2 1 1 2 3 2 -AA[T>A]AT 51 5 6 1 4 5 3 5 5 13 0 6 5 2 4 -AA[T>A]CA 7 7 3 2 1 1 6 3 3 3 1 2 3 1 3 -AA[T>A]CC 3 3 3 6 4 1 1 5 1 3 2 0 3 0 0 -AA[T>A]CG 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -AA[T>A]CT 9 1 5 4 2 1 0 5 3 1 1 3 0 2 3 -AA[T>A]GA 11 5 8 2 3 6 5 5 2 3 2 2 3 4 10 -AA[T>A]GC 5 1 0 1 3 1 5 4 4 4 2 2 4 2 1 -AA[T>A]GG 6 2 6 2 3 1 5 3 2 5 1 3 2 4 1 -AA[T>A]GT 21 10 5 6 8 1 12 9 9 6 2 4 2 7 3 -AA[T>A]TA 33 1 7 9 4 3 3 9 9 6 4 2 1 4 4 -AA[T>A]TC 12 2 8 1 6 4 3 5 2 3 1 2 0 2 3 -AA[T>A]TG 9 2 2 0 1 4 1 4 6 4 0 0 1 1 6 -AA[T>A]TT 28 11 13 15 13 10 6 21 21 17 2 2 6 4 5 -AA[T>C]AA 38 19 48 29 17 5 16 17 11 18 7 4 17 30 5 -AA[T>C]AC 35 32 47 22 20 3 12 16 19 15 4 8 12 14 5 -AA[T>C]AG 32 20 20 19 9 3 7 17 6 22 4 4 10 15 10 -AA[T>C]AT 59 24 56 30 9 6 10 15 15 25 4 6 21 34 6 -AA[T>C]CA 29 11 28 12 11 1 7 12 10 10 1 0 11 26 3 -AA[T>C]CC 24 4 34 6 12 2 5 9 2 9 2 1 4 11 3 -AA[T>C]CG 1 0 0 0 1 0 0 2 0 3 0 1 0 0 0 -AA[T>C]CT 17 6 19 6 12 0 7 4 11 6 5 2 8 13 0 -AA[T>C]GA 25 7 25 21 9 2 12 16 14 16 3 4 11 15 7 -AA[T>C]GC 21 15 34 10 16 3 5 13 6 8 4 3 8 8 1 -AA[T>C]GG 15 11 25 14 13 1 7 7 5 11 3 3 6 9 6 -AA[T>C]GT 25 14 35 25 20 5 9 11 11 14 4 4 14 14 4 -AA[T>C]TA 20 3 15 21 14 1 12 14 11 8 2 7 5 15 5 -AA[T>C]TC 24 11 13 6 10 1 5 6 8 15 1 4 8 8 1 -AA[T>C]TG 15 14 20 16 12 4 9 8 9 10 3 1 15 21 10 -AA[T>C]TT 18 9 25 12 8 4 12 13 9 20 2 2 14 9 8 -AA[T>G]AA 13 2 3 4 9 2 4 11 2 7 1 0 3 2 5 -AA[T>G]AC 2 0 4 1 1 0 3 4 1 3 0 0 2 0 0 -AA[T>G]AG 6 2 4 2 3 3 2 0 2 2 0 1 1 5 0 -AA[T>G]AT 8 3 3 2 6 0 3 5 5 3 0 1 2 2 2 -AA[T>G]CA 5 4 1 4 4 0 3 4 3 7 0 0 1 3 2 -AA[T>G]CC 3 0 6 1 0 0 2 1 1 5 1 1 2 1 1 -AA[T>G]CG 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 -AA[T>G]CT 6 0 7 1 6 0 0 7 6 6 0 1 2 2 0 -AA[T>G]GA 8 1 4 2 5 1 4 20 5 6 0 1 2 7 0 -AA[T>G]GC 2 0 1 4 3 0 2 3 2 7 0 0 0 3 0 -AA[T>G]GG 1 0 2 0 2 0 2 4 2 1 0 0 2 2 0 -AA[T>G]GT 5 0 2 1 4 0 2 7 1 1 1 1 2 2 3 -AA[T>G]TA 10 1 14 6 6 1 12 12 8 16 4 3 5 1 4 -AA[T>G]TC 10 5 6 5 1 0 2 5 4 9 1 2 2 3 4 -AA[T>G]TG 5 3 5 2 4 0 3 8 4 4 0 1 2 1 0 -AA[T>G]TT 15 4 5 3 11 0 6 9 7 24 1 6 6 8 8 -AC[C>A]AA 24 10 20 20 5 4 11 4 7 12 1 2 15 9 6 -AC[C>A]AC 12 6 14 14 1 2 5 10 4 6 2 3 8 4 11 -AC[C>A]AG 13 6 6 7 7 4 2 5 5 6 1 0 11 7 4 -AC[C>A]AT 38 15 17 24 12 1 11 4 8 14 0 3 13 13 6 -AC[C>A]CA 22 7 17 7 8 0 4 8 5 2 2 4 8 9 4 -AC[C>A]CC 12 3 13 6 3 0 4 6 4 5 2 2 2 5 3 -AC[C>A]CG 3 1 0 3 1 0 1 2 2 1 0 0 0 1 1 -AC[C>A]CT 13 9 9 8 9 2 4 7 6 8 1 2 8 12 1 -AC[C>A]GA 3 1 1 0 2 0 0 0 1 1 0 1 0 0 0 -AC[C>A]GC 1 1 2 3 0 1 0 0 2 0 0 0 0 0 1 -AC[C>A]GG 0 0 2 1 0 0 0 0 0 1 0 0 0 0 2 -AC[C>A]GT 1 0 2 1 0 0 0 2 2 0 0 0 0 1 2 -AC[C>A]TA 13 3 6 4 3 0 4 4 6 4 3 1 5 5 4 -AC[C>A]TC 7 2 12 5 4 1 8 10 5 8 1 0 5 6 3 -AC[C>A]TG 9 4 9 8 7 1 8 8 5 12 1 1 9 3 5 -AC[C>A]TT 12 4 12 10 4 3 9 3 2 10 2 1 11 7 7 -AC[C>G]AA 11 3 11 7 5 3 1 5 8 6 0 1 3 0 2 -AC[C>G]AC 3 1 1 5 2 0 1 1 1 1 0 1 3 4 1 -AC[C>G]AG 3 2 5 1 4 2 4 5 1 2 1 1 1 3 1 -AC[C>G]AT 5 2 6 1 5 0 2 6 4 0 2 1 0 0 4 -AC[C>G]CA 8 1 7 4 4 1 3 5 3 6 1 0 3 5 1 -AC[C>G]CC 5 3 0 1 2 0 2 4 1 2 0 1 1 2 0 -AC[C>G]CG 0 0 0 1 0 0 1 2 0 1 0 0 0 0 0 -AC[C>G]CT 7 4 5 2 4 1 3 3 7 9 2 0 5 4 3 -AC[C>G]GA 1 0 2 2 0 0 0 0 0 0 0 0 0 0 1 -AC[C>G]GC 1 0 0 2 1 0 2 0 0 1 0 0 1 0 0 -AC[C>G]GG 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 -AC[C>G]GT 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 -AC[C>G]TA 5 5 2 6 5 0 6 8 2 3 0 0 1 1 2 -AC[C>G]TC 1 3 3 3 8 2 3 4 6 4 2 2 2 2 0 -AC[C>G]TG 5 3 4 5 3 2 1 3 3 2 3 2 1 2 1 -AC[C>G]TT 7 2 6 5 6 2 6 7 7 5 1 0 3 5 2 -AC[C>T]AA 9 8 12 8 8 3 5 7 3 5 0 3 5 10 3 -AC[C>T]AC 6 3 9 8 6 5 2 2 2 5 0 2 5 4 1 -AC[C>T]AG 8 2 8 11 8 2 6 7 6 5 1 0 2 6 0 -AC[C>T]AT 15 6 11 11 10 4 4 5 7 6 2 2 5 5 5 -AC[C>T]CA 9 4 12 6 3 2 2 11 6 8 0 2 6 5 5 -AC[C>T]CC 10 3 7 5 5 3 4 6 4 2 1 2 6 3 4 -AC[C>T]CG 1 3 2 0 1 0 0 1 1 0 1 0 1 1 1 -AC[C>T]CT 10 4 6 13 5 3 7 6 4 8 2 3 3 9 7 -AC[C>T]GA 5 3 4 4 0 0 6 2 4 0 1 2 3 0 1 -AC[C>T]GC 10 5 8 6 6 1 2 2 3 4 0 0 4 1 2 -AC[C>T]GG 2 5 1 5 1 0 2 1 2 2 0 0 2 2 0 -AC[C>T]GT 5 2 3 5 3 1 2 3 3 7 1 1 5 2 0 -AC[C>T]TA 3 5 7 9 4 4 3 7 5 8 0 0 3 5 3 -AC[C>T]TC 10 11 3 8 11 3 4 8 5 4 0 2 4 11 1 -AC[C>T]TG 8 6 10 9 6 3 6 6 7 8 4 0 5 5 3 -AC[C>T]TT 16 13 11 13 5 3 12 11 6 4 6 3 6 3 5 -AC[T>A]AA 17 3 6 4 3 0 4 6 3 1 1 0 6 3 1 -AC[T>A]AC 7 0 0 0 3 1 4 2 4 6 3 0 2 0 2 -AC[T>A]AG 15 1 2 2 2 1 2 4 1 0 0 1 1 4 2 -AC[T>A]AT 44 1 7 3 7 2 1 3 0 1 1 2 1 0 7 -AC[T>A]CA 17 8 2 5 2 3 0 3 3 9 0 1 1 4 4 -AC[T>A]CC 11 2 4 2 1 1 1 5 2 1 0 0 3 5 2 -AC[T>A]CG 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0 -AC[T>A]CT 14 1 9 6 6 1 2 7 6 3 2 3 4 8 2 -AC[T>A]GA 17 2 4 3 11 0 2 6 5 2 1 1 4 2 0 -AC[T>A]GC 16 1 9 5 4 0 2 2 4 2 1 4 3 3 1 -AC[T>A]GG 11 1 6 2 4 3 3 4 0 4 1 2 2 3 5 -AC[T>A]GT 46 1 2 2 2 2 5 6 4 4 2 0 2 5 0 -AC[T>A]TA 11 5 3 4 5 1 2 7 0 6 1 1 2 2 6 -AC[T>A]TC 8 4 3 3 2 1 3 3 5 2 1 2 1 1 1 -AC[T>A]TG 15 2 7 2 5 0 2 3 2 1 1 0 4 1 0 -AC[T>A]TT 14 4 5 7 5 0 5 7 6 8 2 3 1 10 5 -AC[T>C]AA 10 5 16 9 4 4 6 8 5 8 3 5 1 9 6 -AC[T>C]AC 7 3 8 8 8 0 4 7 3 5 2 0 3 2 3 -AC[T>C]AG 3 3 2 0 9 1 2 3 4 6 2 2 2 5 4 -AC[T>C]AT 10 2 12 10 5 2 3 7 7 5 1 0 4 8 5 -AC[T>C]CA 11 9 16 9 2 4 7 2 4 3 1 1 1 5 3 -AC[T>C]CC 6 3 11 3 6 1 6 3 3 5 1 1 5 7 2 -AC[T>C]CG 0 1 0 2 0 0 0 0 0 0 0 0 0 1 0 -AC[T>C]CT 13 9 16 13 4 3 3 9 3 6 0 5 7 8 1 -AC[T>C]GA 5 3 8 7 2 1 3 4 7 2 1 1 4 6 1 -AC[T>C]GC 8 3 8 4 6 3 2 7 3 2 1 2 9 10 1 -AC[T>C]GG 6 2 2 5 4 1 3 8 5 4 3 3 3 7 1 -AC[T>C]GT 9 2 8 6 3 1 3 6 5 0 1 2 2 8 2 -AC[T>C]TA 8 7 7 4 4 2 0 5 3 6 3 2 4 11 0 -AC[T>C]TC 12 5 27 7 5 0 12 10 7 7 0 0 11 11 1 -AC[T>C]TG 8 4 10 10 6 0 4 9 5 5 2 1 7 7 3 -AC[T>C]TT 22 9 31 19 9 2 12 9 7 12 3 3 8 15 3 -AC[T>G]AA 5 2 1 0 2 1 1 7 2 2 0 0 0 0 0 -AC[T>G]AC 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 -AC[T>G]AG 2 0 1 0 0 0 0 0 1 0 0 1 1 0 1 -AC[T>G]AT 4 1 0 0 0 0 1 2 1 0 0 1 0 0 0 -AC[T>G]CA 3 1 3 3 0 1 2 1 1 3 0 2 0 0 4 -AC[T>G]CC 1 0 2 1 0 2 2 2 1 1 0 1 0 0 1 -AC[T>G]CG 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 -AC[T>G]CT 3 1 1 0 2 0 0 0 2 1 0 0 2 1 0 -AC[T>G]GA 3 2 5 2 4 0 3 3 2 4 1 1 2 1 0 -AC[T>G]GC 2 1 3 2 1 0 1 1 2 1 1 1 3 3 1 -AC[T>G]GG 3 1 4 2 1 0 1 1 4 1 0 0 0 1 0 -AC[T>G]GT 5 2 1 1 1 1 1 3 0 0 0 1 1 0 2 -AC[T>G]TA 6 2 3 3 9 3 4 5 6 4 0 1 0 2 0 -AC[T>G]TC 4 3 5 4 2 0 1 2 2 2 1 1 0 1 0 -AC[T>G]TG 1 1 2 2 1 1 3 2 0 1 1 0 4 1 0 -AC[T>G]TT 7 2 2 3 4 1 5 8 2 3 0 0 8 4 4 -AG[C>A]AA 24 6 14 17 7 2 3 14 2 6 2 3 8 6 6 -AG[C>A]AC 10 3 10 5 1 2 4 8 7 2 3 3 0 7 4 -AG[C>A]AG 15 2 10 5 4 3 4 8 4 2 2 1 2 9 6 -AG[C>A]AT 20 9 12 15 8 3 3 3 12 4 2 2 5 1 3 -AG[C>A]CA 18 5 13 11 3 0 3 10 9 6 1 3 3 9 7 -AG[C>A]CC 11 3 8 4 5 0 2 3 3 2 0 0 2 3 5 -AG[C>A]CG 1 0 2 0 1 0 1 2 2 1 1 0 1 0 1 -AG[C>A]CT 13 2 11 7 6 0 4 6 6 4 3 3 1 5 1 -AG[C>A]GA 5 1 2 3 3 1 0 0 0 1 0 1 2 0 1 -AG[C>A]GC 1 1 0 1 1 0 0 2 1 1 0 0 1 0 0 -AG[C>A]GG 2 1 2 2 1 0 0 0 1 1 0 0 1 1 1 -AG[C>A]GT 0 1 0 0 1 0 2 0 0 0 0 0 1 0 1 -AG[C>A]TA 11 4 11 4 0 0 3 4 4 3 2 1 3 7 4 -AG[C>A]TC 5 3 4 3 2 0 0 4 0 4 0 1 1 2 2 -AG[C>A]TG 17 5 3 5 5 3 5 6 5 5 1 1 5 5 2 -AG[C>A]TT 13 7 8 1 4 0 6 8 6 5 0 0 6 7 5 -AG[C>G]AA 10 3 6 3 2 1 1 6 1 2 2 0 2 5 4 -AG[C>G]AC 2 1 1 0 0 0 1 1 3 2 0 1 0 1 1 -AG[C>G]AG 5 3 2 4 3 0 2 8 1 3 2 0 2 1 2 -AG[C>G]AT 1 2 10 3 4 2 1 0 0 2 1 0 2 2 1 -AG[C>G]CA 9 7 5 2 7 1 1 6 1 6 2 1 1 3 1 -AG[C>G]CC 6 3 0 3 3 0 1 2 1 3 0 1 2 1 0 -AG[C>G]CG 1 0 0 0 0 0 1 0 2 0 0 0 0 0 2 -AG[C>G]CT 9 3 3 3 5 1 2 7 5 2 1 1 2 3 2 -AG[C>G]GA 1 0 1 0 0 0 1 1 1 0 0 1 2 1 0 -AG[C>G]GC 0 1 0 0 0 0 2 0 0 0 0 0 1 0 1 -AG[C>G]GG 0 0 0 2 0 0 0 2 0 0 0 0 0 0 0 -AG[C>G]GT 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 -AG[C>G]TA 7 2 4 2 0 1 2 5 5 4 1 0 4 3 3 -AG[C>G]TC 3 1 5 1 2 1 2 3 2 3 0 1 0 2 0 -AG[C>G]TG 4 1 4 4 2 2 1 3 1 1 0 0 1 0 1 -AG[C>G]TT 6 2 1 5 0 2 2 3 1 5 1 1 1 5 2 -AG[C>T]AA 10 6 9 10 7 0 4 12 4 3 1 1 4 6 3 -AG[C>T]AC 5 3 8 5 3 0 5 6 1 7 0 2 8 5 2 -AG[C>T]AG 9 2 10 7 8 1 12 10 7 12 2 2 3 1 5 -AG[C>T]AT 19 4 14 7 10 1 5 7 6 7 3 3 6 9 3 -AG[C>T]CA 14 7 12 10 8 4 8 6 3 8 3 1 6 8 6 -AG[C>T]CC 5 3 5 6 5 2 4 11 7 6 0 0 3 3 2 -AG[C>T]CG 3 0 1 0 1 0 0 1 0 1 0 0 1 2 1 -AG[C>T]CT 16 5 11 3 9 2 5 9 5 8 5 1 2 5 4 -AG[C>T]GA 11 3 5 5 9 0 7 6 6 6 1 0 3 3 2 -AG[C>T]GC 14 5 5 3 3 0 2 3 0 4 0 1 5 2 3 -AG[C>T]GG 8 3 3 6 4 1 4 5 6 10 0 0 1 4 4 -AG[C>T]GT 9 6 3 4 3 0 0 2 4 6 1 3 0 2 1 -AG[C>T]TA 7 4 10 3 10 1 7 7 3 6 2 1 6 4 4 -AG[C>T]TC 3 5 5 6 6 2 3 4 2 2 0 0 3 4 6 -AG[C>T]TG 15 10 10 6 5 3 4 4 6 9 1 2 5 3 11 -AG[C>T]TT 6 4 11 8 4 5 6 4 3 8 2 1 5 7 8 -AG[T>A]AA 9 3 0 1 1 2 6 1 2 3 1 3 2 4 1 -AG[T>A]AC 1 2 6 2 5 0 2 5 0 0 1 1 2 0 2 -AG[T>A]AG 16 1 1 3 2 1 2 2 1 1 1 1 1 1 1 -AG[T>A]AT 7 0 2 0 4 1 2 3 6 3 1 1 2 1 0 -AG[T>A]CA 11 3 9 7 3 1 2 4 0 4 0 1 2 7 1 -AG[T>A]CC 8 1 4 1 3 0 0 2 2 1 0 0 2 1 1 -AG[T>A]CG 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 -AG[T>A]CT 3 2 3 1 0 0 2 2 3 2 0 2 0 1 3 -AG[T>A]GA 8 0 4 4 5 1 2 5 0 2 1 2 1 0 1 -AG[T>A]GC 7 0 5 3 0 1 2 0 2 1 2 2 0 0 0 -AG[T>A]GG 9 0 1 2 3 0 4 2 4 0 0 0 1 7 0 -AG[T>A]GT 5 1 6 2 1 1 3 2 4 1 0 0 2 3 1 -AG[T>A]TA 8 4 2 0 2 1 1 2 2 4 0 1 4 3 2 -AG[T>A]TC 4 1 3 0 1 0 0 1 1 0 1 1 3 0 1 -AG[T>A]TG 4 1 4 3 2 1 0 3 1 1 0 0 1 4 2 -AG[T>A]TT 7 3 9 5 5 2 3 3 3 4 3 1 1 5 6 -AG[T>C]AA 24 14 29 13 11 1 7 9 12 16 1 3 12 20 2 -AG[T>C]AC 11 16 21 15 14 0 9 6 4 9 1 2 4 11 3 -AG[T>C]AG 19 9 23 15 9 2 8 5 6 10 2 5 6 10 3 -AG[T>C]AT 27 14 38 17 12 0 16 9 9 8 1 2 14 19 3 -AG[T>C]CA 24 10 36 9 6 1 12 11 8 12 1 2 8 12 0 -AG[T>C]CC 20 12 10 8 9 1 8 3 8 6 1 2 6 7 1 -AG[T>C]CG 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 -AG[T>C]CT 14 9 16 14 14 2 10 8 4 9 1 3 6 7 1 -AG[T>C]GA 9 9 23 11 11 1 7 12 4 6 2 4 8 10 3 -AG[T>C]GC 11 7 28 5 15 1 10 11 4 6 1 5 8 11 0 -AG[T>C]GG 10 5 13 4 10 0 7 3 3 6 2 1 6 7 0 -AG[T>C]GT 16 8 24 7 6 1 8 6 7 10 3 3 2 16 4 -AG[T>C]TA 11 4 8 3 4 1 3 4 2 7 1 4 3 7 1 -AG[T>C]TC 17 10 30 17 9 0 10 8 5 14 1 5 4 13 2 -AG[T>C]TG 9 4 19 9 5 3 6 5 6 6 1 2 4 7 1 -AG[T>C]TT 11 4 13 3 3 0 8 10 7 9 0 5 8 8 6 -AG[T>G]AA 0 0 2 3 2 0 3 3 0 4 0 0 4 1 1 -AG[T>G]AC 2 1 2 0 1 2 0 0 0 1 0 1 1 0 0 -AG[T>G]AG 1 1 2 0 0 1 1 3 1 1 0 0 0 0 1 -AG[T>G]AT 2 1 0 0 2 0 1 1 2 2 0 1 1 1 0 -AG[T>G]CA 0 3 2 5 1 0 3 1 1 3 0 0 0 2 1 -AG[T>G]CC 2 0 1 0 0 0 1 1 1 0 0 0 1 0 0 -AG[T>G]CG 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 -AG[T>G]CT 0 0 2 0 1 0 0 5 1 2 0 0 0 0 1 -AG[T>G]GA 2 2 2 2 3 0 4 2 0 3 2 1 2 2 0 -AG[T>G]GC 0 0 3 0 0 0 5 1 2 2 0 1 3 1 3 -AG[T>G]GG 3 2 2 0 2 0 1 2 1 2 1 1 0 3 1 -AG[T>G]GT 1 1 2 0 1 0 1 2 3 2 0 1 0 0 0 -AG[T>G]TA 1 4 2 1 2 0 3 3 3 6 1 2 1 1 1 -AG[T>G]TC 1 4 0 0 1 0 4 5 0 0 0 1 1 1 1 -AG[T>G]TG 0 0 0 1 2 0 1 4 5 1 0 0 2 0 2 -AG[T>G]TT 4 2 2 2 5 1 3 3 2 3 1 1 1 1 1 -AT[C>A]AA 18 7 13 10 9 2 11 9 8 8 0 3 8 11 3 -AT[C>A]AC 8 7 7 10 5 0 5 8 8 8 2 3 6 3 4 -AT[C>A]AG 14 3 13 3 7 1 2 3 10 10 2 1 4 6 2 -AT[C>A]AT 20 9 20 10 13 1 2 12 14 9 2 3 5 8 5 -AT[C>A]CA 17 3 21 15 8 0 8 14 9 9 1 4 9 7 4 -AT[C>A]CC 11 6 9 7 4 2 3 10 7 5 4 0 5 7 6 -AT[C>A]CG 0 1 1 3 0 1 0 2 0 2 0 0 1 0 0 -AT[C>A]CT 27 3 12 15 8 0 4 11 8 12 4 1 4 12 7 -AT[C>A]GA 2 1 2 1 2 0 4 0 2 0 0 1 1 1 3 -AT[C>A]GC 3 1 2 2 1 0 0 4 2 3 0 0 1 2 0 -AT[C>A]GG 2 1 0 1 3 0 1 2 1 2 1 1 0 0 0 -AT[C>A]GT 4 0 1 1 0 0 0 0 0 1 0 0 0 0 1 -AT[C>A]TA 21 6 8 7 5 1 9 8 13 11 0 1 5 7 1 -AT[C>A]TC 14 5 5 19 5 2 3 6 10 8 5 7 2 4 4 -AT[C>A]TG 16 5 11 5 13 0 7 6 11 8 4 5 6 5 6 -AT[C>A]TT 28 4 13 13 17 1 8 14 22 4 3 5 10 12 6 -AT[C>G]AA 19 2 17 6 13 0 3 15 7 1 4 3 2 4 3 -AT[C>G]AC 3 2 4 3 3 1 0 6 4 2 1 0 0 0 0 -AT[C>G]AG 5 1 4 4 4 4 5 8 8 2 0 1 1 4 2 -AT[C>G]AT 10 0 6 5 2 0 2 4 1 3 0 3 2 1 2 -AT[C>G]CA 14 1 6 7 7 2 3 7 9 7 1 3 3 1 1 -AT[C>G]CC 4 2 3 2 5 0 2 7 4 3 0 1 2 3 3 -AT[C>G]CG 1 0 3 1 0 0 0 1 0 0 0 0 1 0 0 -AT[C>G]CT 7 3 8 4 5 3 3 8 9 4 3 2 2 5 1 -AT[C>G]GA 1 0 3 2 0 0 2 1 0 1 0 1 0 0 0 -AT[C>G]GC 0 0 0 0 0 0 1 1 2 0 1 0 0 1 0 -AT[C>G]GG 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 -AT[C>G]GT 0 0 0 1 1 1 0 2 3 1 0 2 2 0 0 -AT[C>G]TA 7 5 12 1 13 2 5 11 6 10 0 3 3 3 7 -AT[C>G]TC 17 3 9 8 5 1 2 11 6 4 3 0 4 5 6 -AT[C>G]TG 15 2 9 5 3 0 2 6 4 5 1 1 0 4 0 -AT[C>G]TT 14 5 7 10 10 3 13 16 5 9 2 1 3 5 2 -AT[C>T]AA 14 3 11 9 7 1 3 12 6 10 1 0 5 7 6 -AT[C>T]AC 12 3 9 8 12 2 5 7 5 7 2 1 7 3 2 -AT[C>T]AG 8 6 9 5 6 0 4 13 4 6 0 5 4 9 1 -AT[C>T]AT 17 6 16 13 18 1 10 14 10 10 3 2 7 6 7 -AT[C>T]CA 13 7 7 8 8 1 2 5 9 7 1 1 4 4 5 -AT[C>T]CC 21 5 11 3 8 1 5 6 4 7 1 2 5 5 1 -AT[C>T]CG 0 3 1 0 1 0 0 1 1 1 0 0 2 0 0 -AT[C>T]CT 11 10 9 10 7 4 4 11 5 13 2 2 11 7 9 -AT[C>T]GA 3 1 3 3 0 1 2 5 1 5 1 0 5 2 3 -AT[C>T]GC 12 1 3 3 3 1 1 1 4 3 0 0 5 1 2 -AT[C>T]GG 10 2 2 1 1 0 2 0 1 4 0 0 1 1 0 -AT[C>T]GT 5 3 1 5 2 1 2 2 1 4 0 1 1 4 2 -AT[C>T]TA 5 4 7 6 5 1 1 11 4 8 0 0 3 2 2 -AT[C>T]TC 12 4 10 5 6 0 6 15 6 6 1 0 3 3 7 -AT[C>T]TG 10 2 7 5 6 0 4 8 2 5 2 2 4 3 7 -AT[C>T]TT 16 6 15 8 9 2 5 8 4 10 1 3 6 2 5 -AT[T>A]AA 41 3 8 5 3 1 6 10 4 6 3 1 1 2 2 -AT[T>A]AC 13 2 3 0 7 1 3 6 3 3 0 2 1 4 1 -AT[T>A]AG 33 1 2 2 3 0 1 3 2 0 0 1 4 0 0 -AT[T>A]AT 49 3 8 1 6 2 2 7 7 6 0 2 0 6 0 -AT[T>A]CA 18 5 13 3 11 2 2 2 4 5 0 1 4 8 3 -AT[T>A]CC 13 0 6 6 3 0 5 7 3 6 3 1 1 8 1 -AT[T>A]CG 1 0 0 0 0 0 0 1 0 2 0 0 0 0 0 -AT[T>A]CT 12 4 10 12 6 0 4 9 9 4 5 3 4 8 1 -AT[T>A]GA 13 1 6 5 5 1 3 6 7 2 0 1 2 2 3 -AT[T>A]GC 4 2 3 2 3 3 1 2 2 2 1 3 2 3 0 -AT[T>A]GG 14 0 4 3 1 0 2 4 1 1 0 0 0 0 1 -AT[T>A]GT 24 2 8 3 2 3 1 3 0 8 0 2 3 0 2 -AT[T>A]TA 34 3 12 4 7 4 12 11 15 14 2 6 6 6 5 -AT[T>A]TC 11 2 6 7 12 5 5 10 14 10 0 4 2 8 3 -AT[T>A]TG 33 4 13 6 7 0 7 7 4 15 3 6 4 3 4 -AT[T>A]TT 42 9 20 15 16 7 15 18 18 19 4 11 8 6 13 -AT[T>C]AA 22 19 31 23 7 1 11 13 11 9 2 1 6 15 2 -AT[T>C]AC 17 5 26 14 8 0 9 13 2 8 1 1 7 11 2 -AT[T>C]AG 17 10 23 13 8 3 6 4 11 10 3 2 9 12 0 -AT[T>C]AT 43 26 62 26 25 1 17 15 7 26 1 8 27 24 3 -AT[T>C]CA 8 9 26 15 12 0 5 6 2 10 0 5 5 12 2 -AT[T>C]CC 8 4 8 4 7 0 1 2 2 4 1 1 3 6 1 -AT[T>C]CG 0 0 1 0 0 0 0 1 1 0 0 0 0 2 0 -AT[T>C]CT 17 4 20 10 6 0 6 5 5 4 0 2 6 10 1 -AT[T>C]GA 15 2 13 9 6 0 4 4 4 3 2 2 3 7 0 -AT[T>C]GC 2 7 11 9 2 0 4 7 4 3 1 3 5 12 1 -AT[T>C]GG 4 6 6 2 3 1 1 1 2 7 3 1 0 3 0 -AT[T>C]GT 15 7 11 13 3 0 6 3 5 4 0 0 8 10 1 -AT[T>C]TA 25 5 22 10 6 2 3 6 9 7 0 2 7 14 1 -AT[T>C]TC 23 8 36 19 11 0 9 11 6 11 0 4 9 20 1 -AT[T>C]TG 16 6 15 8 4 0 7 4 2 6 2 2 9 5 2 -AT[T>C]TT 27 18 40 21 8 1 9 6 7 12 0 2 10 14 2 -AT[T>G]AA 13 1 5 0 6 1 1 7 9 5 0 4 6 6 1 -AT[T>G]AC 2 0 2 2 0 0 3 1 3 2 0 0 1 0 0 -AT[T>G]AG 4 0 0 1 0 0 2 3 1 4 1 0 1 2 1 -AT[T>G]AT 4 0 4 3 0 1 8 6 1 5 0 1 3 1 2 -AT[T>G]CA 5 2 7 2 7 0 5 5 6 6 0 3 4 3 0 -AT[T>G]CC 3 2 2 3 3 1 3 4 2 5 0 1 1 1 1 -AT[T>G]CG 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 -AT[T>G]CT 5 6 5 8 9 0 2 3 3 7 1 2 2 1 4 -AT[T>G]GA 2 2 4 2 5 0 2 6 1 1 0 2 1 2 0 -AT[T>G]GC 1 0 2 1 3 0 0 3 4 1 1 2 1 0 1 -AT[T>G]GG 0 0 1 0 1 0 2 7 4 3 1 1 1 1 1 -AT[T>G]GT 9 1 5 1 4 0 1 6 1 2 0 0 1 1 1 -AT[T>G]TA 15 8 10 7 13 4 4 8 4 10 3 3 4 6 8 -AT[T>G]TC 5 2 10 3 3 0 5 7 2 12 1 1 3 3 0 -AT[T>G]TG 6 3 3 2 5 0 3 7 1 6 1 0 4 5 2 -AT[T>G]TT 14 6 16 13 9 0 7 20 4 18 3 0 12 9 4 -CA[C>A]AA 18 9 15 16 9 3 11 6 9 12 3 3 9 11 6 -CA[C>A]AC 15 6 12 7 3 2 5 4 4 3 1 2 6 6 5 -CA[C>A]AG 18 9 9 7 4 0 3 10 6 5 0 1 4 3 6 -CA[C>A]AT 17 3 17 6 3 2 2 12 8 8 1 0 2 5 5 -CA[C>A]CA 24 9 14 6 6 1 3 9 11 5 2 0 4 8 3 -CA[C>A]CC 14 2 4 6 4 0 2 2 1 3 1 1 4 5 0 -CA[C>A]CG 3 0 3 0 1 0 0 1 1 1 0 0 2 0 1 -CA[C>A]CT 12 1 10 4 1 0 1 10 6 11 2 1 3 2 3 -CA[C>A]GA 2 0 1 0 0 0 0 4 1 0 0 0 3 1 2 -CA[C>A]GC 5 0 1 1 1 0 1 1 0 1 0 1 1 1 0 -CA[C>A]GG 3 0 1 0 3 1 3 2 0 1 1 1 1 0 0 -CA[C>A]GT 6 0 1 2 0 0 2 0 0 1 2 1 0 1 0 -CA[C>A]TA 9 1 5 1 4 1 0 2 1 3 0 1 2 2 3 -CA[C>A]TC 4 2 2 1 4 1 2 3 6 2 0 1 3 3 0 -CA[C>A]TG 15 3 8 9 7 1 7 8 2 4 2 0 9 9 1 -CA[C>A]TT 11 5 5 8 6 2 3 5 6 1 2 0 6 4 3 -CA[C>G]AA 4 0 4 5 2 2 4 8 5 4 3 1 2 2 0 -CA[C>G]AC 2 1 3 2 0 1 3 3 1 1 1 0 1 3 1 -CA[C>G]AG 6 9 8 5 6 4 5 4 5 8 1 3 8 8 2 -CA[C>G]AT 6 4 3 2 2 1 3 6 1 6 1 0 1 3 0 -CA[C>G]CA 8 2 12 4 7 0 2 8 6 7 1 0 3 3 1 -CA[C>G]CC 1 0 3 1 2 0 5 7 3 4 1 1 2 2 3 -CA[C>G]CG 0 1 1 2 1 0 0 1 2 0 0 0 2 0 1 -CA[C>G]CT 3 0 3 7 5 0 3 2 5 5 0 0 0 3 1 -CA[C>G]GA 1 1 1 1 0 0 2 4 1 2 0 0 0 1 1 -CA[C>G]GC 0 2 1 0 2 1 0 1 1 2 0 2 0 0 1 -CA[C>G]GG 0 1 1 0 0 0 0 1 3 1 0 1 0 0 0 -CA[C>G]GT 2 0 0 1 2 0 1 0 3 0 0 0 0 1 1 -CA[C>G]TA 6 0 3 3 5 0 2 5 7 3 1 0 2 1 2 -CA[C>G]TC 5 2 1 2 2 1 3 4 4 4 0 1 3 1 2 -CA[C>G]TG 6 3 4 4 5 3 11 6 6 3 2 1 3 3 4 -CA[C>G]TT 6 7 6 5 7 0 3 7 3 6 2 0 4 6 2 -CA[C>T]AA 10 6 9 5 6 2 9 6 4 7 0 2 3 6 5 -CA[C>T]AC 12 7 4 8 4 3 5 3 6 3 0 0 5 2 5 -CA[C>T]AG 10 5 5 6 4 2 2 6 4 7 1 1 5 2 5 -CA[C>T]AT 14 8 13 10 5 2 7 10 6 5 0 2 11 6 10 -CA[C>T]CA 9 8 9 11 4 3 4 6 5 10 2 3 9 10 8 -CA[C>T]CC 7 2 10 4 12 1 4 10 2 7 1 3 5 5 2 -CA[C>T]CG 0 1 2 0 0 0 1 1 0 2 3 0 2 0 1 -CA[C>T]CT 11 1 5 5 10 1 7 5 8 9 3 2 3 7 7 -CA[C>T]GA 22 8 3 13 8 1 4 8 7 16 0 2 7 3 2 -CA[C>T]GC 28 20 15 17 7 5 10 9 13 14 2 3 15 6 7 -CA[C>T]GG 19 6 6 14 10 2 8 7 4 13 2 0 10 3 10 -CA[C>T]GT 17 8 8 5 8 2 7 10 7 8 1 3 11 5 8 -CA[C>T]TA 4 2 2 6 3 1 2 3 3 7 2 2 5 1 2 -CA[C>T]TC 9 4 7 7 2 1 3 10 2 3 1 1 5 0 3 -CA[C>T]TG 18 7 14 11 6 3 11 10 5 6 1 2 9 5 4 -CA[C>T]TT 12 8 11 7 8 5 3 6 6 3 1 3 3 6 6 -CA[T>A]AA 12 3 8 3 3 0 2 4 3 6 1 1 2 4 3 -CA[T>A]AC 14 0 0 2 4 1 0 2 2 3 0 1 4 0 0 -CA[T>A]AG 17 1 5 0 3 1 0 1 3 2 1 0 3 2 2 -CA[T>A]AT 42 2 4 2 1 0 7 5 3 4 0 0 2 2 0 -CA[T>A]CA 5 1 5 2 2 2 3 1 2 2 0 0 4 2 3 -CA[T>A]CC 4 1 4 2 1 1 3 0 2 1 0 1 1 2 2 -CA[T>A]CG 0 0 1 0 1 0 0 1 0 0 1 0 0 0 2 -CA[T>A]CT 7 4 7 0 1 0 2 4 2 3 1 1 6 6 3 -CA[T>A]GA 4 2 5 2 2 0 4 3 2 5 0 1 1 3 1 -CA[T>A]GC 3 3 5 3 2 2 1 3 0 2 2 0 1 2 0 -CA[T>A]GG 13 1 3 1 1 2 1 3 2 1 2 1 3 1 2 -CA[T>A]GT 23 2 2 4 6 1 8 1 1 4 1 0 2 2 2 -CA[T>A]TA 9 1 10 2 0 2 0 0 3 5 2 1 1 2 2 -CA[T>A]TC 6 2 4 0 3 1 0 1 2 1 0 1 0 0 3 -CA[T>A]TG 6 1 4 4 4 0 3 4 3 1 1 1 2 4 1 -CA[T>A]TT 20 4 6 3 7 0 0 7 4 6 1 1 2 0 8 -CA[T>C]AA 6 6 6 4 7 3 3 4 7 8 1 3 3 7 2 -CA[T>C]AC 12 7 11 9 11 1 1 9 5 8 1 1 6 10 2 -CA[T>C]AG 13 12 18 6 6 1 9 11 4 7 3 4 5 7 4 -CA[T>C]AT 19 4 13 5 3 2 7 6 12 11 1 4 3 8 2 -CA[T>C]CA 7 8 12 11 6 2 7 3 4 6 0 4 5 9 2 -CA[T>C]CC 15 4 14 10 4 2 4 6 6 5 3 2 3 7 1 -CA[T>C]CG 2 0 0 0 0 0 0 2 0 0 0 0 1 0 0 -CA[T>C]CT 21 8 23 14 9 1 10 8 7 11 2 3 8 11 1 -CA[T>C]GA 8 6 9 8 2 1 3 5 8 12 0 0 3 7 4 -CA[T>C]GC 16 6 12 7 2 0 4 3 7 12 3 6 4 9 1 -CA[T>C]GG 15 7 11 5 7 1 8 2 6 7 2 2 7 9 3 -CA[T>C]GT 18 6 17 9 3 3 6 6 5 8 0 5 8 7 5 -CA[T>C]TA 9 5 5 5 4 0 3 5 8 10 1 1 1 6 3 -CA[T>C]TC 17 4 17 12 5 0 3 2 7 3 1 1 5 8 2 -CA[T>C]TG 8 7 13 10 8 2 7 9 6 11 4 0 14 11 4 -CA[T>C]TT 14 6 17 12 12 0 11 11 8 10 3 6 12 11 5 -CA[T>G]AA 3 2 4 1 1 0 0 7 1 3 0 1 3 1 1 -CA[T>G]AC 2 0 1 3 0 0 1 0 2 0 1 0 1 0 1 -CA[T>G]AG 3 0 2 2 4 0 1 4 2 0 0 0 0 0 2 -CA[T>G]AT 5 0 0 2 1 0 0 3 1 0 1 0 2 0 0 -CA[T>G]CA 2 1 3 1 2 1 0 0 2 4 0 1 2 0 1 -CA[T>G]CC 2 0 2 2 1 0 3 4 0 2 0 0 0 0 3 -CA[T>G]CG 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 -CA[T>G]CT 1 1 3 1 4 2 2 3 1 5 0 0 1 3 3 -CA[T>G]GA 6 0 0 0 0 1 3 3 3 2 1 5 2 1 1 -CA[T>G]GC 8 0 0 3 4 1 3 2 0 1 2 0 1 1 1 -CA[T>G]GG 2 0 0 5 0 1 1 2 1 2 0 0 1 3 0 -CA[T>G]GT 7 0 2 2 1 1 4 2 1 2 2 1 2 1 4 -CA[T>G]TA 3 2 0 1 2 5 4 1 2 3 1 1 0 2 0 -CA[T>G]TC 4 1 3 2 4 0 3 4 1 2 0 1 0 1 1 -CA[T>G]TG 2 0 5 2 0 0 2 1 1 4 0 0 0 1 1 -CA[T>G]TT 5 0 6 4 5 2 5 5 3 4 1 2 0 2 2 -CC[C>A]AA 23 8 14 11 4 1 1 8 9 7 1 3 7 12 5 -CC[C>A]AC 24 6 23 11 12 1 4 5 5 2 1 2 1 9 8 -CC[C>A]AG 40 5 14 7 11 4 8 10 8 11 2 2 4 13 0 -CC[C>A]AT 25 12 31 12 7 1 3 11 2 6 3 1 14 23 3 -CC[C>A]CA 28 9 21 14 13 1 6 7 8 5 1 1 4 16 6 -CC[C>A]CC 17 3 9 6 3 1 2 3 6 3 0 1 5 4 0 -CC[C>A]CG 9 0 3 2 1 0 1 1 0 1 1 2 0 0 1 -CC[C>A]CT 22 3 13 10 2 3 5 11 6 5 1 1 6 8 8 -CC[C>A]GA 2 1 2 0 1 0 0 3 1 1 0 1 0 0 1 -CC[C>A]GC 3 0 1 1 0 0 3 3 0 4 0 2 1 0 3 -CC[C>A]GG 5 1 5 2 1 0 1 3 1 2 0 0 1 2 0 -CC[C>A]GT 5 0 1 4 0 1 1 1 3 1 0 0 2 1 1 -CC[C>A]TA 15 2 9 5 2 0 1 7 3 6 1 0 1 3 2 -CC[C>A]TC 13 1 8 0 1 0 5 5 2 4 4 4 5 4 4 -CC[C>A]TG 17 5 7 4 3 0 2 1 6 8 1 1 3 6 8 -CC[C>A]TT 19 5 7 10 2 2 6 9 6 4 1 4 2 8 2 -CC[C>G]AA 5 2 11 4 7 3 3 6 7 5 1 1 2 5 2 -CC[C>G]AC 2 5 2 4 1 1 1 2 1 0 0 2 1 2 2 -CC[C>G]AG 8 2 3 2 2 0 2 8 2 7 0 1 4 2 4 -CC[C>G]AT 3 0 1 2 0 0 5 4 3 0 0 0 1 1 0 -CC[C>G]CA 8 3 5 3 6 1 2 2 7 1 0 0 3 4 4 -CC[C>G]CC 3 3 2 1 3 1 0 2 1 3 1 2 0 3 0 -CC[C>G]CG 1 1 0 0 0 1 2 1 1 0 0 1 1 0 0 -CC[C>G]CT 15 2 6 4 4 2 2 4 4 3 1 2 4 4 1 -CC[C>G]GA 1 0 3 0 1 0 0 3 0 2 0 0 1 0 0 -CC[C>G]GC 2 1 2 0 1 1 2 2 0 0 1 0 0 1 0 -CC[C>G]GG 1 0 0 1 3 0 0 3 0 1 0 1 0 0 3 -CC[C>G]GT 1 0 0 1 0 1 2 1 3 3 0 0 0 1 0 -CC[C>G]TA 4 1 4 5 9 0 1 7 4 1 1 1 5 2 1 -CC[C>G]TC 2 1 5 4 5 1 6 11 1 4 0 1 3 3 2 -CC[C>G]TG 3 0 1 5 4 1 5 4 11 2 2 1 2 4 2 -CC[C>G]TT 5 5 5 5 7 1 8 5 3 5 2 4 4 5 1 -CC[C>T]AA 6 8 11 6 3 2 5 2 4 6 1 2 3 6 4 -CC[C>T]AC 5 2 5 9 5 2 5 8 0 7 5 1 6 2 1 -CC[C>T]AG 19 4 17 17 7 2 2 8 8 13 4 3 12 5 4 -CC[C>T]AT 7 5 9 10 5 0 5 11 5 5 2 2 4 5 2 -CC[C>T]CA 12 5 12 14 10 1 9 5 5 8 0 1 4 7 7 -CC[C>T]CC 6 4 9 8 3 2 2 7 4 7 4 0 2 5 2 -CC[C>T]CG 2 3 0 2 1 0 1 3 2 3 0 1 3 0 0 -CC[C>T]CT 15 1 5 8 4 0 10 10 6 12 0 1 1 4 2 -CC[C>T]GA 8 6 6 9 2 0 5 4 2 7 0 1 2 3 3 -CC[C>T]GC 17 3 10 8 5 2 5 13 4 11 1 1 3 9 6 -CC[C>T]GG 21 7 6 11 3 1 10 7 7 13 1 1 7 2 5 -CC[C>T]GT 14 4 5 3 6 2 3 3 5 4 0 2 3 3 4 -CC[C>T]TA 7 3 8 1 5 0 4 10 0 3 0 0 1 5 3 -CC[C>T]TC 12 4 5 6 1 1 4 6 3 9 1 2 6 3 4 -CC[C>T]TG 6 2 12 15 9 3 3 7 6 3 2 1 4 3 6 -CC[C>T]TT 19 8 13 7 6 1 5 7 9 2 4 1 4 7 3 -CC[T>A]AA 26 2 3 1 5 4 2 2 2 1 3 3 2 3 2 -CC[T>A]AC 15 2 0 2 4 1 1 1 1 3 0 1 0 2 0 -CC[T>A]AG 18 1 1 1 0 2 0 3 1 0 0 0 2 0 1 -CC[T>A]AT 50 0 1 1 4 0 2 3 3 0 0 2 0 0 1 -CC[T>A]CA 24 1 9 5 2 0 2 4 3 4 0 2 3 7 4 -CC[T>A]CC 12 1 6 8 5 3 2 6 6 6 3 1 1 1 3 -CC[T>A]CG 3 0 2 0 0 0 1 1 0 0 1 0 1 0 1 -CC[T>A]CT 15 4 7 2 6 1 0 3 4 5 1 0 3 4 2 -CC[T>A]GA 15 2 4 6 3 0 5 4 2 2 1 0 3 0 3 -CC[T>A]GC 22 5 2 6 6 2 2 5 2 6 0 1 4 5 5 -CC[T>A]GG 22 2 10 7 7 0 3 6 5 10 1 2 5 4 2 -CC[T>A]GT 58 3 3 4 2 0 5 3 8 5 3 0 0 0 2 -CC[T>A]TA 10 4 3 2 2 0 2 2 2 3 0 0 1 1 1 -CC[T>A]TC 3 1 5 1 2 2 1 4 3 3 1 3 0 0 1 -CC[T>A]TG 21 3 3 2 6 1 2 1 4 6 1 0 0 2 6 -CC[T>A]TT 19 6 7 6 7 1 3 10 6 6 0 3 3 3 3 -CC[T>C]AA 6 3 3 1 5 1 2 3 2 5 0 4 0 2 1 -CC[T>C]AC 4 2 7 0 3 1 5 3 1 7 1 1 2 0 1 -CC[T>C]AG 3 1 4 2 4 2 3 5 3 3 1 1 2 0 6 -CC[T>C]AT 5 3 2 1 6 2 0 5 3 6 1 2 1 1 3 -CC[T>C]CA 3 1 5 3 3 2 1 6 4 5 0 2 2 7 0 -CC[T>C]CC 5 2 2 1 3 1 5 2 1 5 0 1 3 3 2 -CC[T>C]CG 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 -CC[T>C]CT 12 2 9 7 6 0 2 4 3 4 1 3 4 4 2 -CC[T>C]GA 7 1 6 2 6 0 3 3 9 4 2 3 2 3 5 -CC[T>C]GC 5 3 3 3 9 3 3 2 6 2 3 0 1 2 6 -CC[T>C]GG 6 2 9 3 5 2 4 4 3 4 1 0 2 4 0 -CC[T>C]GT 4 7 3 3 9 2 1 5 2 2 2 1 2 3 2 -CC[T>C]TA 2 0 1 1 1 2 1 1 3 2 1 0 1 0 2 -CC[T>C]TC 3 0 1 1 5 1 1 1 3 1 1 1 3 4 2 -CC[T>C]TG 6 1 2 3 3 1 2 4 2 4 1 1 1 3 0 -CC[T>C]TT 8 2 5 6 5 1 1 2 4 5 1 3 1 1 3 -CC[T>G]AA 2 1 2 3 3 0 1 2 5 1 0 0 2 1 1 -CC[T>G]AC 1 3 1 0 2 0 1 1 1 0 0 0 1 1 1 -CC[T>G]AG 3 2 1 0 0 0 0 2 1 3 0 2 0 0 0 -CC[T>G]AT 7 0 0 0 0 1 0 2 1 0 0 0 0 0 2 -CC[T>G]CA 3 0 8 2 0 0 1 4 2 5 2 0 1 1 2 -CC[T>G]CC 4 1 1 3 1 0 5 1 1 5 3 1 1 3 0 -CC[T>G]CG 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CC[T>G]CT 4 0 2 2 3 0 1 2 1 3 0 2 1 4 2 -CC[T>G]GA 3 0 1 2 3 0 2 2 3 5 0 0 1 3 3 -CC[T>G]GC 1 0 3 1 0 0 2 1 2 1 0 0 0 0 0 -CC[T>G]GG 0 0 2 0 0 0 0 2 1 0 1 1 1 1 2 -CC[T>G]GT 7 0 3 1 0 0 1 3 1 1 0 1 0 1 1 -CC[T>G]TA 2 1 2 4 0 0 1 1 6 3 1 0 1 1 0 -CC[T>G]TC 0 0 3 1 5 0 1 3 4 2 3 0 1 0 2 -CC[T>G]TG 2 1 1 2 1 0 2 3 1 2 1 0 0 1 1 -CC[T>G]TT 3 1 3 4 4 1 4 3 2 1 1 1 3 4 2 -CG[C>A]AA 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 -CG[C>A]AC 1 0 1 1 0 0 0 0 1 0 0 0 0 1 0 -CG[C>A]AG 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 -CG[C>A]AT 2 0 2 2 1 0 0 0 0 0 0 2 0 0 1 -CG[C>A]CA 0 1 1 0 2 0 1 1 0 3 0 0 0 0 0 -CG[C>A]CC 1 0 1 2 1 0 0 0 3 0 0 0 1 0 1 -CG[C>A]CG 1 0 1 0 1 1 0 1 1 0 0 0 0 0 0 -CG[C>A]CT 2 0 1 1 1 0 1 0 2 0 1 1 0 0 2 -CG[C>A]GA 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[C>A]GC 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 -CG[C>A]GG 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 -CG[C>A]GT 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 -CG[C>A]TA 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 -CG[C>A]TC 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 -CG[C>A]TG 1 0 1 1 1 0 1 0 0 0 1 0 1 0 1 -CG[C>A]TT 2 0 1 2 1 0 1 0 0 1 0 0 0 0 0 -CG[C>G]AA 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 -CG[C>G]AC 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 -CG[C>G]AG 0 0 1 0 0 0 0 0 0 1 0 0 0 2 0 -CG[C>G]AT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[C>G]CA 1 0 0 0 0 0 0 0 0 0 0 0 1 0 2 -CG[C>G]CC 0 0 0 0 1 0 0 2 1 2 0 0 0 0 0 -CG[C>G]CG 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -CG[C>G]CT 2 0 1 0 0 0 0 0 1 0 0 0 1 0 0 -CG[C>G]GA 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[C>G]GC 0 0 0 0 0 0 1 1 2 0 0 0 1 1 0 -CG[C>G]GG 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 -CG[C>G]GT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[C>G]TA 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 -CG[C>G]TC 0 0 1 0 0 0 0 0 0 0 0 0 2 1 0 -CG[C>G]TG 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 -CG[C>G]TT 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 -CG[C>T]AA 0 0 2 1 0 0 0 1 0 0 0 0 1 0 0 -CG[C>T]AC 3 0 1 2 0 1 2 0 0 0 1 0 1 1 0 -CG[C>T]AG 2 0 1 1 1 0 0 0 2 0 0 0 1 1 1 -CG[C>T]AT 4 2 0 1 1 0 1 1 2 1 0 0 1 1 1 -CG[C>T]CA 3 0 0 0 2 0 0 1 0 0 0 0 1 2 0 -CG[C>T]CC 2 2 0 0 5 1 0 1 0 2 1 0 0 3 2 -CG[C>T]CG 0 0 2 2 0 1 0 0 0 0 0 0 1 0 0 -CG[C>T]CT 6 0 0 5 3 0 1 1 0 1 2 0 1 2 1 -CG[C>T]GA 2 2 5 3 2 1 0 1 2 3 1 0 1 2 2 -CG[C>T]GC 9 3 4 3 3 2 1 5 4 3 0 1 5 2 2 -CG[C>T]GG 9 2 5 3 2 2 3 2 3 6 2 0 3 2 2 -CG[C>T]GT 0 3 0 0 4 1 0 1 1 0 0 1 0 1 1 -CG[C>T]TA 1 0 0 2 1 0 0 0 0 1 0 0 0 1 0 -CG[C>T]TC 0 1 1 1 1 0 0 0 0 1 0 1 2 2 0 -CG[C>T]TG 0 3 1 1 1 1 1 2 0 0 1 2 0 2 1 -CG[C>T]TT 1 4 1 3 0 0 0 2 0 1 0 1 2 0 0 -CG[T>A]AA 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 -CG[T>A]AC 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 -CG[T>A]AG 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>A]AT 3 1 1 0 1 0 0 1 0 1 0 0 1 0 0 -CG[T>A]CA 1 0 1 0 2 0 0 0 0 0 0 0 0 0 0 -CG[T>A]CC 0 0 0 2 0 0 0 0 0 0 0 0 0 0 1 -CG[T>A]CG 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 -CG[T>A]CT 1 0 0 0 0 1 2 1 1 0 0 0 0 0 0 -CG[T>A]GA 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 -CG[T>A]GC 2 0 0 0 0 0 0 1 1 1 0 0 1 0 1 -CG[T>A]GG 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 -CG[T>A]GT 0 0 0 0 1 0 0 3 1 0 0 0 0 0 0 -CG[T>A]TA 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>A]TC 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>A]TG 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>A]TT 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>C]AA 4 0 0 2 1 1 0 0 0 0 0 0 0 0 0 -CG[T>C]AC 3 0 0 1 0 0 2 1 0 0 0 0 0 0 1 -CG[T>C]AG 1 0 0 2 0 0 0 0 0 0 0 0 0 0 1 -CG[T>C]AT 1 1 2 0 2 0 1 2 0 0 0 0 1 1 0 -CG[T>C]CA 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 -CG[T>C]CC 1 0 1 0 0 0 0 0 1 2 0 0 0 0 0 -CG[T>C]CG 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>C]CT 2 3 1 2 2 0 3 1 1 0 0 0 3 2 0 -CG[T>C]GA 1 0 2 3 1 0 0 0 1 1 0 0 0 2 0 -CG[T>C]GC 0 0 1 1 0 0 1 0 0 0 0 1 0 2 1 -CG[T>C]GG 2 0 1 0 2 0 2 3 0 1 0 0 0 0 0 -CG[T>C]GT 2 0 0 0 0 1 0 0 1 1 0 0 1 0 0 -CG[T>C]TA 1 0 1 0 0 0 0 0 2 0 0 0 0 1 0 -CG[T>C]TC 0 1 2 0 0 0 1 0 0 0 0 0 1 1 0 -CG[T>C]TG 3 2 1 0 1 0 0 0 2 0 0 2 0 1 0 -CG[T>C]TT 2 0 0 0 1 0 0 1 0 0 0 0 0 2 0 -CG[T>G]AA 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]AC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]AG 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]AT 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 -CG[T>G]CA 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]CC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]CG 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]CT 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 -CG[T>G]GA 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 -CG[T>G]GC 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]GG 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]GT 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 -CG[T>G]TA 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]TC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -CG[T>G]TG 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -CG[T>G]TT 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 -CT[C>A]AA 21 6 15 9 9 0 2 8 8 6 4 1 2 7 5 -CT[C>A]AC 13 6 8 9 4 0 2 11 10 8 3 0 2 6 4 -CT[C>A]AG 18 5 11 10 9 2 3 10 3 9 3 3 2 3 5 -CT[C>A]AT 19 7 17 7 5 2 0 14 10 8 0 4 5 7 6 -CT[C>A]CA 20 7 9 5 7 4 7 9 7 7 2 3 6 9 6 -CT[C>A]CC 16 7 13 7 6 0 3 12 3 9 3 3 7 5 4 -CT[C>A]CG 1 1 2 1 1 0 0 2 0 2 1 0 0 1 0 -CT[C>A]CT 24 8 14 5 16 2 12 14 9 9 1 3 3 7 7 -CT[C>A]GA 1 1 0 1 2 0 0 0 0 2 0 1 2 2 0 -CT[C>A]GC 1 0 1 0 2 1 0 0 0 0 0 0 1 1 0 -CT[C>A]GG 4 1 5 0 1 0 1 3 2 2 1 0 0 0 0 -CT[C>A]GT 2 3 1 0 0 0 1 1 1 2 1 1 0 0 2 -CT[C>A]TA 7 3 8 4 6 0 3 10 9 4 2 2 5 4 3 -CT[C>A]TC 12 1 7 3 7 1 3 5 8 6 0 0 4 3 3 -CT[C>A]TG 15 3 7 7 12 0 1 7 6 6 0 1 3 2 6 -CT[C>A]TT 18 3 13 4 6 1 5 6 7 5 5 2 5 4 3 -CT[C>G]AA 11 4 10 1 8 1 3 18 11 5 1 1 6 2 3 -CT[C>G]AC 4 1 2 3 2 0 0 4 1 3 3 0 0 2 3 -CT[C>G]AG 7 3 5 6 6 0 3 3 4 2 1 1 4 2 0 -CT[C>G]AT 10 1 3 1 6 1 3 6 0 6 1 1 1 1 1 -CT[C>G]CA 12 5 8 3 9 2 3 13 6 8 3 1 2 7 3 -CT[C>G]CC 8 4 3 4 8 1 3 10 4 0 0 3 4 3 3 -CT[C>G]CG 1 0 1 2 0 0 0 1 0 2 0 0 0 1 0 -CT[C>G]CT 13 3 12 2 14 3 2 9 9 5 3 3 4 5 2 -CT[C>G]GA 2 0 0 1 0 0 0 0 1 0 0 0 0 0 1 -CT[C>G]GC 0 0 1 0 0 0 0 3 0 0 0 0 0 1 0 -CT[C>G]GG 1 1 0 1 0 0 0 2 0 0 0 0 0 1 0 -CT[C>G]GT 1 0 1 1 1 0 0 2 0 0 0 0 1 0 0 -CT[C>G]TA 13 3 7 1 5 1 5 16 11 11 2 3 3 4 1 -CT[C>G]TC 6 5 7 4 9 2 4 9 5 11 1 3 6 6 3 -CT[C>G]TG 7 4 8 5 10 0 9 11 5 7 1 2 4 3 3 -CT[C>G]TT 8 4 12 4 15 4 3 22 10 7 3 6 5 6 5 -CT[C>T]AA 14 5 13 7 7 1 7 6 3 8 6 0 4 7 3 -CT[C>T]AC 17 3 13 3 6 1 1 11 4 6 0 0 4 8 2 -CT[C>T]AG 18 4 12 10 7 3 6 16 7 7 2 2 5 7 7 -CT[C>T]AT 15 3 8 8 12 4 1 15 3 7 2 0 6 4 9 -CT[C>T]CA 11 2 10 9 3 2 2 7 3 9 3 3 5 6 3 -CT[C>T]CC 13 11 9 14 9 1 3 12 9 10 2 1 5 11 3 -CT[C>T]CG 1 3 0 0 0 0 0 1 3 1 0 0 0 1 2 -CT[C>T]CT 20 9 18 15 15 1 5 16 11 10 5 2 14 19 9 -CT[C>T]GA 10 1 3 4 1 2 2 2 2 2 0 2 3 0 3 -CT[C>T]GC 5 2 1 2 1 0 1 2 2 6 1 1 1 4 3 -CT[C>T]GG 12 8 7 4 5 2 9 2 7 6 1 2 5 4 3 -CT[C>T]GT 4 2 6 7 4 1 3 6 1 3 0 2 4 0 0 -CT[C>T]TA 11 3 5 8 8 0 2 3 3 7 2 1 1 5 2 -CT[C>T]TC 13 5 6 3 1 1 4 7 4 11 2 1 9 1 3 -CT[C>T]TG 13 5 6 7 7 1 5 6 4 4 2 2 3 4 6 -CT[C>T]TT 9 3 8 6 7 3 4 7 4 7 0 0 4 2 6 -CT[T>A]AA 28 2 1 3 1 1 4 1 2 6 0 0 2 1 2 -CT[T>A]AC 12 2 5 0 2 1 0 4 2 1 1 2 1 2 3 -CT[T>A]AG 29 0 3 0 3 0 0 1 0 3 1 0 0 1 1 -CT[T>A]AT 54 1 5 3 1 2 2 3 2 3 0 0 2 1 3 -CT[T>A]CA 9 3 7 5 1 2 3 5 4 2 0 2 2 7 2 -CT[T>A]CC 6 2 7 6 4 0 5 5 4 4 1 0 2 1 1 -CT[T>A]CG 0 0 0 0 0 0 0 1 2 0 0 0 1 0 0 -CT[T>A]CT 17 3 9 6 6 1 8 4 2 1 3 1 1 2 6 -CT[T>A]GA 10 2 5 0 3 1 0 3 1 4 1 0 0 2 0 -CT[T>A]GC 8 1 3 0 0 2 0 2 3 3 0 2 0 0 0 -CT[T>A]GG 14 0 4 1 3 1 0 3 2 2 0 1 1 2 1 -CT[T>A]GT 22 0 2 4 3 1 1 0 2 0 0 1 1 2 1 -CT[T>A]TA 8 1 5 2 1 6 2 1 4 5 2 0 3 1 0 -CT[T>A]TC 7 1 10 1 2 0 4 2 0 3 2 4 0 1 1 -CT[T>A]TG 24 2 2 1 8 0 0 3 3 1 0 1 2 2 2 -CT[T>A]TT 20 2 5 3 3 1 0 3 6 5 2 1 2 2 0 -CT[T>C]AA 6 3 7 1 4 0 2 2 6 3 2 3 1 2 0 -CT[T>C]AC 5 2 4 2 1 1 6 4 1 4 1 3 2 0 1 -CT[T>C]AG 3 0 4 3 4 0 3 1 3 2 1 2 1 2 0 -CT[T>C]AT 12 2 8 6 5 0 4 5 3 2 0 0 6 6 3 -CT[T>C]CA 6 2 2 4 4 1 1 2 3 1 0 1 3 2 0 -CT[T>C]CC 5 3 6 3 7 1 4 6 0 5 0 3 2 8 0 -CT[T>C]CG 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -CT[T>C]CT 8 3 11 5 5 0 7 5 2 5 2 1 1 7 3 -CT[T>C]GA 1 1 3 1 3 0 4 4 2 2 0 0 0 1 0 -CT[T>C]GC 3 1 4 2 2 0 5 2 4 1 2 0 0 4 0 -CT[T>C]GG 2 1 4 1 4 0 0 2 3 2 1 0 0 3 0 -CT[T>C]GT 4 0 1 1 0 0 1 5 0 4 0 0 1 1 2 -CT[T>C]TA 5 2 2 2 3 1 1 3 1 6 4 0 1 0 1 -CT[T>C]TC 9 3 7 5 9 1 1 5 2 2 0 1 1 6 3 -CT[T>C]TG 5 3 5 5 2 0 7 8 8 7 3 2 1 3 3 -CT[T>C]TT 9 3 6 6 4 2 5 11 0 13 0 1 7 3 3 -CT[T>G]AA 6 1 6 2 2 0 3 8 3 3 2 0 3 4 1 -CT[T>G]AC 2 2 1 1 3 1 0 1 1 0 0 0 3 1 2 -CT[T>G]AG 4 1 0 1 0 0 0 4 3 1 0 0 2 0 0 -CT[T>G]AT 1 0 1 0 3 0 1 1 1 0 0 0 0 0 0 -CT[T>G]CA 3 0 3 2 3 0 4 1 5 3 2 1 0 3 1 -CT[T>G]CC 0 0 3 0 6 0 4 9 4 3 0 1 2 2 1 -CT[T>G]CG 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 -CT[T>G]CT 3 3 5 2 4 1 4 2 3 3 1 4 4 1 3 -CT[T>G]GA 5 1 4 0 3 0 3 2 1 4 0 0 0 2 1 -CT[T>G]GC 1 2 0 0 1 1 2 7 0 3 2 3 1 0 1 -CT[T>G]GG 3 0 3 1 2 0 2 3 6 4 1 0 0 1 2 -CT[T>G]GT 5 0 1 2 3 1 3 4 0 0 1 1 1 3 1 -CT[T>G]TA 5 0 5 1 5 1 3 7 5 8 0 1 4 2 5 -CT[T>G]TC 5 5 7 3 2 1 5 4 2 0 4 0 3 1 3 -CT[T>G]TG 3 1 3 1 3 3 5 4 4 5 2 3 1 0 0 -CT[T>G]TT 8 4 6 3 10 4 13 15 2 12 3 1 5 5 2 -GA[C>A]AA 26 10 15 10 9 0 3 13 7 8 3 2 4 7 5 -GA[C>A]AC 9 6 9 7 6 0 3 5 1 3 1 1 2 9 2 -GA[C>A]AG 13 3 5 1 8 0 2 7 4 2 1 3 2 4 2 -GA[C>A]AT 12 5 23 6 4 1 3 3 6 5 0 2 6 19 5 -GA[C>A]CA 10 4 3 7 5 0 6 1 5 5 0 1 1 8 2 -GA[C>A]CC 1 1 5 3 3 0 1 4 3 1 1 0 4 3 1 -GA[C>A]CG 3 0 0 1 0 0 1 0 0 0 0 0 0 0 0 -GA[C>A]CT 9 4 8 7 4 1 2 1 2 4 1 1 3 4 0 -GA[C>A]GA 0 0 0 3 0 0 0 0 0 0 0 0 1 0 0 -GA[C>A]GC 1 2 1 1 1 0 0 0 1 2 1 0 2 0 0 -GA[C>A]GG 2 0 5 0 1 0 1 3 1 0 0 2 0 0 2 -GA[C>A]GT 3 1 0 0 1 0 0 0 1 0 0 0 0 0 0 -GA[C>A]TA 8 2 4 2 3 0 1 0 2 4 0 0 2 2 7 -GA[C>A]TC 5 1 5 3 0 0 1 5 1 4 0 0 1 0 1 -GA[C>A]TG 6 2 2 5 2 3 3 5 6 2 1 2 2 3 4 -GA[C>A]TT 8 5 6 6 4 1 3 7 5 3 1 2 2 3 1 -GA[C>G]AA 3 4 4 3 3 1 3 4 2 5 0 0 3 3 0 -GA[C>G]AC 5 1 4 1 1 1 1 2 2 1 0 0 1 1 1 -GA[C>G]AG 5 4 6 6 4 1 2 5 4 8 4 0 6 7 7 -GA[C>G]AT 1 0 2 1 0 0 1 1 0 3 1 0 3 1 1 -GA[C>G]CA 7 2 3 1 2 0 5 3 1 4 1 1 2 2 4 -GA[C>G]CC 1 0 3 2 2 0 3 3 0 2 1 1 1 0 1 -GA[C>G]CG 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 -GA[C>G]CT 5 2 6 4 0 1 2 6 1 5 0 2 1 1 2 -GA[C>G]GA 0 0 0 1 1 0 1 2 0 0 0 1 1 0 2 -GA[C>G]GC 1 2 2 0 1 0 1 0 0 0 1 0 0 0 0 -GA[C>G]GG 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 -GA[C>G]GT 0 0 1 0 2 0 0 0 0 1 1 0 0 0 0 -GA[C>G]TA 1 0 4 1 1 2 2 5 5 3 0 0 0 0 1 -GA[C>G]TC 0 0 3 1 2 0 0 5 3 1 0 0 0 0 1 -GA[C>G]TG 6 2 1 1 3 1 2 1 1 2 3 2 2 0 1 -GA[C>G]TT 2 1 1 3 3 0 4 2 3 6 2 1 0 7 1 -GA[C>T]AA 6 4 3 5 5 1 6 7 2 6 0 3 4 5 6 -GA[C>T]AC 3 3 5 2 7 2 2 2 3 3 1 1 0 0 1 -GA[C>T]AG 10 6 5 5 5 2 1 7 1 2 2 0 5 3 2 -GA[C>T]AT 8 6 10 10 6 5 8 11 4 3 2 1 13 4 3 -GA[C>T]CA 10 4 5 5 2 0 1 6 5 4 1 0 2 1 1 -GA[C>T]CC 7 2 2 0 1 0 2 3 0 3 0 2 0 3 2 -GA[C>T]CG 4 1 0 0 1 0 1 1 0 0 0 0 0 0 1 -GA[C>T]CT 8 6 3 3 4 0 4 3 2 5 1 2 2 6 4 -GA[C>T]GA 18 5 5 8 7 1 6 8 3 9 1 2 10 7 0 -GA[C>T]GC 18 8 10 1 4 2 6 3 6 15 0 0 6 7 4 -GA[C>T]GG 25 7 7 14 10 8 17 8 9 9 1 2 7 5 2 -GA[C>T]GT 18 9 10 8 3 2 4 3 4 12 0 2 11 1 3 -GA[C>T]TA 8 2 5 6 1 1 2 3 0 1 0 0 2 6 2 -GA[C>T]TC 0 2 3 2 5 1 3 3 2 2 0 0 3 1 2 -GA[C>T]TG 14 2 6 2 1 2 1 5 1 1 1 0 1 2 3 -GA[C>T]TT 6 5 1 5 8 1 6 3 1 4 0 1 3 4 5 -GA[T>A]AA 16 4 4 3 5 2 1 3 3 3 1 3 4 3 2 -GA[T>A]AC 3 1 2 1 2 0 0 4 3 4 1 1 0 1 0 -GA[T>A]AG 23 2 3 4 3 2 1 3 1 5 0 2 1 2 0 -GA[T>A]AT 16 0 2 1 1 2 3 2 4 2 0 0 1 1 1 -GA[T>A]CA 7 2 8 3 3 0 2 2 3 2 0 1 2 1 1 -GA[T>A]CC 2 1 2 3 1 0 0 2 0 2 0 0 2 0 0 -GA[T>A]CG 1 0 1 0 0 0 1 0 2 1 0 0 0 1 0 -GA[T>A]CT 10 0 5 3 3 0 1 4 0 5 0 0 4 1 1 -GA[T>A]GA 5 3 3 2 6 1 3 3 3 4 1 2 3 3 4 -GA[T>A]GC 2 0 5 0 2 0 2 0 1 2 1 0 1 1 1 -GA[T>A]GG 9 0 4 3 1 3 0 4 0 2 1 1 3 0 1 -GA[T>A]GT 12 2 2 1 2 1 0 2 3 1 1 1 1 2 1 -GA[T>A]TA 5 3 5 5 1 0 1 4 1 3 0 0 1 4 2 -GA[T>A]TC 3 0 1 2 5 0 1 5 4 2 2 2 2 1 2 -GA[T>A]TG 5 1 5 1 2 0 3 0 3 3 2 2 1 1 1 -GA[T>A]TT 3 1 3 1 2 0 3 0 4 4 1 1 4 3 3 -GA[T>C]AA 12 2 10 5 9 2 9 4 7 5 2 3 6 11 2 -GA[T>C]AC 16 4 7 8 5 1 2 7 7 5 1 1 5 3 7 -GA[T>C]AG 14 4 10 6 5 1 4 9 11 5 0 2 3 7 4 -GA[T>C]AT 18 3 9 4 5 0 8 6 2 6 1 2 7 12 2 -GA[T>C]CA 12 6 23 8 6 1 6 3 2 2 0 2 7 8 1 -GA[T>C]CC 2 4 6 3 6 0 3 3 2 6 2 1 1 5 2 -GA[T>C]CG 0 0 1 0 1 0 0 0 0 1 0 0 0 1 0 -GA[T>C]CT 9 4 9 8 1 1 5 3 4 2 2 1 4 11 2 -GA[T>C]GA 13 3 11 4 5 2 5 5 6 6 1 0 1 6 3 -GA[T>C]GC 8 3 8 4 4 3 4 2 1 4 0 0 4 3 0 -GA[T>C]GG 11 6 18 7 3 1 5 6 2 5 5 1 9 7 4 -GA[T>C]GT 4 9 6 5 6 2 2 4 2 5 0 1 3 7 2 -GA[T>C]TA 4 3 9 2 1 0 2 1 4 3 0 0 1 5 0 -GA[T>C]TC 10 2 6 2 1 1 1 1 0 3 0 1 0 4 1 -GA[T>C]TG 7 11 10 5 7 2 4 7 5 8 0 1 10 11 3 -GA[T>C]TT 10 6 10 9 3 1 6 8 6 8 1 2 2 6 4 -GA[T>G]AA 1 2 2 0 0 0 0 4 0 2 1 1 3 1 0 -GA[T>G]AC 3 0 1 0 0 0 0 1 0 2 0 0 0 1 0 -GA[T>G]AG 4 0 1 2 2 0 4 1 1 1 1 0 1 2 0 -GA[T>G]AT 2 0 0 0 1 0 1 1 0 1 0 1 1 1 0 -GA[T>G]CA 1 0 0 1 0 1 2 1 1 3 1 0 1 2 0 -GA[T>G]CC 1 0 1 0 2 0 1 1 1 1 0 0 0 0 2 -GA[T>G]CG 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 -GA[T>G]CT 0 1 0 0 4 1 3 1 1 3 0 0 3 2 1 -GA[T>G]GA 2 0 3 2 0 0 5 4 3 0 1 1 1 1 1 -GA[T>G]GC 3 0 2 0 1 2 0 1 0 0 0 2 0 1 1 -GA[T>G]GG 2 0 3 2 3 1 1 2 0 0 0 0 1 1 0 -GA[T>G]GT 3 0 3 3 0 0 1 1 3 0 0 0 0 0 1 -GA[T>G]TA 2 0 2 2 3 1 0 0 2 0 2 1 0 2 0 -GA[T>G]TC 2 0 1 2 1 0 1 1 1 0 0 0 0 0 1 -GA[T>G]TG 2 0 2 2 3 1 0 3 0 1 1 1 1 1 0 -GA[T>G]TT 4 0 1 1 4 0 2 7 4 6 1 0 1 0 1 -GC[C>A]AA 16 4 8 6 2 0 6 6 4 8 2 1 2 8 5 -GC[C>A]AC 11 5 10 4 1 0 2 6 4 7 0 1 5 8 2 -GC[C>A]AG 7 1 11 8 2 0 1 2 4 2 4 2 5 5 1 -GC[C>A]AT 19 6 22 6 3 1 7 9 8 4 1 2 7 8 3 -GC[C>A]CA 14 5 15 2 2 3 2 9 4 3 1 0 1 10 1 -GC[C>A]CC 9 4 4 8 3 0 5 5 4 6 2 2 3 5 2 -GC[C>A]CG 2 1 3 2 1 0 0 3 1 1 1 0 0 1 0 -GC[C>A]CT 11 5 13 5 11 2 7 3 5 5 2 2 5 6 3 -GC[C>A]GA 4 0 2 2 0 1 3 0 2 0 0 0 1 0 0 -GC[C>A]GC 0 0 1 2 1 0 0 1 0 1 0 1 1 0 1 -GC[C>A]GG 4 0 0 1 1 0 0 0 2 1 1 0 1 1 2 -GC[C>A]GT 1 0 0 1 0 0 0 1 1 0 0 0 0 1 1 -GC[C>A]TA 3 0 4 4 0 0 2 3 3 3 1 0 0 1 0 -GC[C>A]TC 10 0 6 4 9 1 3 10 5 3 3 2 6 2 2 -GC[C>A]TG 12 5 4 6 5 0 6 4 6 5 3 3 5 8 6 -GC[C>A]TT 12 2 6 7 2 1 5 2 4 4 0 3 4 5 2 -GC[C>G]AA 5 2 3 0 1 0 2 3 0 3 0 0 0 3 1 -GC[C>G]AC 2 0 0 0 0 1 0 1 2 1 0 0 0 0 0 -GC[C>G]AG 8 1 4 2 2 0 3 2 3 1 1 2 1 4 1 -GC[C>G]AT 2 3 1 3 1 1 0 2 5 2 0 1 0 2 1 -GC[C>G]CA 3 3 4 4 2 1 3 4 1 2 0 0 1 0 2 -GC[C>G]CC 2 0 1 4 1 0 0 4 1 3 0 0 2 0 4 -GC[C>G]CG 0 0 1 0 3 1 1 2 1 0 0 0 0 0 1 -GC[C>G]CT 3 2 5 2 7 2 4 5 1 5 1 1 2 2 0 -GC[C>G]GA 1 0 0 0 0 2 0 1 0 2 0 1 0 0 1 -GC[C>G]GC 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 -GC[C>G]GG 1 0 1 0 0 1 1 0 1 0 0 0 1 0 1 -GC[C>G]GT 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 -GC[C>G]TA 1 2 2 3 3 0 3 4 3 4 1 0 0 1 0 -GC[C>G]TC 4 3 5 0 4 0 3 6 1 5 2 1 1 2 4 -GC[C>G]TG 1 3 1 1 3 1 3 4 1 4 1 1 2 2 2 -GC[C>G]TT 4 5 0 2 2 1 5 4 1 7 3 0 1 4 1 -GC[C>T]AA 9 10 10 5 5 1 1 2 3 2 0 1 5 6 0 -GC[C>T]AC 5 0 7 5 2 0 4 5 3 4 4 0 5 3 4 -GC[C>T]AG 5 6 6 7 2 3 0 3 3 5 0 2 6 4 2 -GC[C>T]AT 11 5 5 5 8 0 7 3 6 3 0 1 3 4 4 -GC[C>T]CA 7 4 7 7 7 1 4 11 5 9 3 2 8 6 6 -GC[C>T]CC 3 7 3 11 8 1 5 9 3 3 1 1 4 4 2 -GC[C>T]CG 1 1 2 3 1 1 0 1 1 1 0 0 1 1 1 -GC[C>T]CT 10 8 4 5 12 3 7 7 5 7 1 2 6 11 1 -GC[C>T]GA 11 5 3 6 5 2 2 3 4 8 3 0 1 3 3 -GC[C>T]GC 4 2 6 3 4 3 2 1 3 8 2 0 1 0 2 -GC[C>T]GG 16 6 6 2 9 1 7 6 9 9 0 1 4 3 1 -GC[C>T]GT 11 3 3 3 2 3 2 4 4 1 0 0 0 1 0 -GC[C>T]TA 4 2 6 4 4 0 2 6 2 5 0 2 2 7 3 -GC[C>T]TC 11 6 5 8 6 2 6 4 7 8 0 1 6 9 4 -GC[C>T]TG 11 2 6 6 3 2 4 10 6 8 3 2 5 7 4 -GC[C>T]TT 14 2 8 7 3 1 1 1 3 9 1 3 1 2 6 -GC[T>A]AA 34 2 5 2 4 0 3 5 4 3 1 1 1 1 0 -GC[T>A]AC 10 2 2 0 3 0 4 1 2 2 0 1 2 2 2 -GC[T>A]AG 29 1 2 1 3 0 2 0 0 3 2 0 1 0 0 -GC[T>A]AT 37 2 2 6 1 2 1 1 2 2 0 3 1 1 1 -GC[T>A]CA 6 2 3 1 4 1 1 3 2 5 1 1 0 3 2 -GC[T>A]CC 8 2 0 1 1 1 1 2 1 4 0 0 1 1 1 -GC[T>A]CG 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 -GC[T>A]CT 14 1 8 6 3 2 4 5 5 4 1 3 2 0 2 -GC[T>A]GA 21 2 4 1 5 3 4 2 1 3 1 0 2 0 1 -GC[T>A]GC 8 0 3 3 1 2 1 3 0 0 1 0 1 1 3 -GC[T>A]GG 15 3 5 3 3 0 3 4 1 2 2 1 3 0 1 -GC[T>A]GT 30 1 4 4 5 4 2 5 3 4 1 2 2 0 1 -GC[T>A]TA 7 1 6 1 4 2 0 3 3 3 1 0 0 0 3 -GC[T>A]TC 2 2 5 2 3 0 0 0 0 2 0 1 2 1 1 -GC[T>A]TG 10 1 1 3 3 0 0 1 2 1 0 0 3 2 1 -GC[T>A]TT 2 1 4 6 3 0 3 6 2 5 2 0 2 3 1 -GC[T>C]AA 3 1 0 5 2 2 4 5 3 1 3 1 1 5 1 -GC[T>C]AC 3 3 2 4 3 0 5 2 2 1 2 1 3 1 3 -GC[T>C]AG 8 0 5 1 1 0 3 5 2 2 0 2 3 0 0 -GC[T>C]AT 4 3 5 2 3 3 1 8 4 3 1 2 1 3 2 -GC[T>C]CA 4 1 4 4 3 0 2 3 1 3 2 0 0 2 1 -GC[T>C]CC 5 1 2 3 3 1 1 4 2 2 0 0 1 5 1 -GC[T>C]CG 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 -GC[T>C]CT 2 2 6 3 1 0 4 3 0 0 1 0 2 5 5 -GC[T>C]GA 5 2 6 2 3 2 4 3 4 3 2 2 2 2 1 -GC[T>C]GC 4 3 2 7 2 1 2 3 2 1 0 0 0 2 2 -GC[T>C]GG 2 4 6 3 4 0 2 1 6 5 1 1 1 3 1 -GC[T>C]GT 4 1 1 7 2 3 3 2 3 3 1 1 1 4 2 -GC[T>C]TA 4 1 2 6 1 0 2 2 2 6 0 0 5 1 0 -GC[T>C]TC 6 2 4 3 1 2 4 4 5 4 0 2 3 1 2 -GC[T>C]TG 3 0 1 4 4 1 1 3 4 2 1 0 3 3 2 -GC[T>C]TT 4 5 1 5 4 2 6 5 4 4 1 1 3 4 2 -GC[T>G]AA 1 2 3 2 0 0 0 2 2 0 0 0 0 0 1 -GC[T>G]AC 1 0 2 0 0 0 2 0 0 0 0 0 0 0 0 -GC[T>G]AG 3 1 1 0 0 0 2 1 0 1 0 0 2 0 0 -GC[T>G]AT 2 1 1 0 1 1 1 1 0 2 0 0 0 0 0 -GC[T>G]CA 2 1 3 0 0 0 2 1 1 0 0 0 1 0 1 -GC[T>G]CC 2 1 2 2 1 0 2 1 0 1 0 0 2 1 0 -GC[T>G]CG 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 -GC[T>G]CT 4 1 2 0 0 1 0 0 1 1 0 0 1 0 0 -GC[T>G]GA 2 2 2 1 0 0 1 3 0 2 1 2 0 1 1 -GC[T>G]GC 2 0 0 1 0 0 0 1 0 0 0 0 0 0 0 -GC[T>G]GG 3 1 1 1 3 0 2 5 3 3 0 0 1 0 0 -GC[T>G]GT 1 1 2 1 2 1 2 2 1 0 0 0 1 0 1 -GC[T>G]TA 1 0 1 0 1 0 3 3 0 2 0 0 0 2 1 -GC[T>G]TC 2 3 1 1 3 0 0 6 3 1 1 1 1 1 0 -GC[T>G]TG 4 1 2 1 2 0 0 1 2 1 1 0 0 0 0 -GC[T>G]TT 2 1 3 0 4 1 1 6 2 1 0 0 0 1 1 -GG[C>A]AA 15 4 9 8 6 5 5 2 8 6 0 1 8 7 0 -GG[C>A]AC 9 2 9 4 2 0 1 0 3 2 1 0 3 4 2 -GG[C>A]AG 12 4 3 4 3 1 3 8 9 3 2 4 8 5 7 -GG[C>A]AT 12 8 18 5 12 0 8 4 6 3 2 2 5 9 2 -GG[C>A]CA 11 2 10 5 4 1 8 6 3 7 1 2 4 6 3 -GG[C>A]CC 6 1 2 7 1 1 4 3 5 3 1 2 3 2 3 -GG[C>A]CG 4 0 1 0 0 0 0 0 1 0 0 0 2 1 1 -GG[C>A]CT 9 1 8 7 8 0 6 1 3 4 2 2 2 11 4 -GG[C>A]GA 1 2 2 2 0 0 2 0 0 0 0 0 0 1 0 -GG[C>A]GC 3 1 1 4 0 1 1 0 2 3 0 0 0 1 2 -GG[C>A]GG 8 2 4 0 2 0 2 1 3 0 0 0 0 2 1 -GG[C>A]GT 2 1 2 1 3 1 0 0 0 1 0 0 3 0 0 -GG[C>A]TA 12 1 4 4 4 0 1 3 0 0 0 3 2 3 0 -GG[C>A]TC 8 2 5 4 3 0 3 3 3 2 0 2 0 1 2 -GG[C>A]TG 15 3 6 7 3 0 0 5 3 4 1 1 2 7 2 -GG[C>A]TT 15 3 5 4 4 2 5 1 5 4 0 1 5 4 1 -GG[C>G]AA 5 3 3 1 2 0 2 1 1 4 0 0 0 1 1 -GG[C>G]AC 2 0 0 1 2 0 2 0 1 2 0 2 0 1 0 -GG[C>G]AG 1 0 7 0 4 1 3 2 1 1 1 1 1 2 3 -GG[C>G]AT 0 0 2 0 1 0 0 0 1 2 1 0 0 1 0 -GG[C>G]CA 7 1 5 2 1 1 0 4 3 4 0 1 1 0 0 -GG[C>G]CC 4 1 0 0 0 0 0 4 1 0 1 4 1 2 0 -GG[C>G]CG 0 0 0 1 1 0 2 0 0 0 0 0 0 0 2 -GG[C>G]CT 4 0 5 0 1 0 3 2 1 1 1 0 2 0 0 -GG[C>G]GA 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -GG[C>G]GC 0 0 2 0 0 0 1 0 0 0 2 0 0 1 0 -GG[C>G]GG 0 0 1 0 2 0 2 0 0 0 1 0 0 0 0 -GG[C>G]GT 1 0 1 0 0 0 1 0 1 0 0 0 0 0 1 -GG[C>G]TA 2 1 2 2 3 0 1 2 4 3 0 0 1 1 0 -GG[C>G]TC 1 0 3 0 1 1 2 3 0 3 0 0 1 0 1 -GG[C>G]TG 2 0 1 2 6 1 0 3 1 0 0 0 1 1 2 -GG[C>G]TT 1 3 2 1 5 1 2 2 1 0 1 0 0 2 0 -GG[C>T]AA 10 9 9 11 7 2 6 9 5 6 4 1 5 6 4 -GG[C>T]AC 9 6 6 4 2 0 2 8 11 13 1 1 3 0 4 -GG[C>T]AG 15 8 6 11 4 6 3 12 7 8 2 2 8 8 6 -GG[C>T]AT 12 5 10 10 9 1 5 11 3 9 1 0 4 9 2 -GG[C>T]CA 15 9 5 10 6 2 8 7 7 7 2 1 7 7 1 -GG[C>T]CC 6 4 5 3 5 6 1 3 1 7 2 3 5 2 4 -GG[C>T]CG 0 0 2 5 1 0 4 0 0 1 1 1 1 1 1 -GG[C>T]CT 8 5 9 13 5 4 8 10 4 5 2 0 9 9 10 -GG[C>T]GA 20 5 4 4 10 0 4 2 6 7 2 0 7 5 4 -GG[C>T]GC 20 7 6 8 7 3 9 8 4 11 2 1 9 7 5 -GG[C>T]GG 38 6 15 16 11 2 12 11 10 14 2 4 9 7 5 -GG[C>T]GT 14 7 8 9 6 2 6 7 4 7 1 0 9 2 5 -GG[C>T]TA 11 5 3 6 3 2 4 3 1 4 2 1 2 4 1 -GG[C>T]TC 7 2 3 7 6 1 1 8 5 7 0 0 4 5 7 -GG[C>T]TG 10 7 8 13 5 2 8 11 9 8 3 3 6 5 6 -GG[C>T]TT 14 2 6 3 3 1 6 5 3 3 0 3 3 5 3 -GG[T>A]AA 5 1 1 1 0 0 1 2 2 3 0 0 0 0 3 -GG[T>A]AC 2 1 1 1 1 0 1 1 0 1 0 1 1 0 0 -GG[T>A]AG 7 0 0 0 2 2 0 2 3 0 0 0 1 0 1 -GG[T>A]AT 5 1 1 3 1 0 2 1 3 4 0 0 0 1 1 -GG[T>A]CA 8 1 7 3 3 0 0 3 0 1 0 0 2 3 0 -GG[T>A]CC 4 1 0 2 0 0 0 2 2 0 0 2 1 0 0 -GG[T>A]CG 0 1 1 0 0 0 0 0 0 1 0 0 0 1 0 -GG[T>A]CT 6 1 1 1 1 1 2 1 1 1 0 1 2 7 0 -GG[T>A]GA 5 2 2 1 2 1 1 5 1 0 0 0 0 0 0 -GG[T>A]GC 3 1 3 0 1 0 3 5 0 1 0 1 1 0 2 -GG[T>A]GG 6 2 1 2 4 0 3 4 0 2 0 0 0 0 0 -GG[T>A]GT 4 0 1 0 0 0 0 2 0 1 0 0 0 0 0 -GG[T>A]TA 5 1 0 1 2 0 0 3 2 5 1 1 0 4 1 -GG[T>A]TC 1 0 0 0 2 0 1 1 0 5 0 0 0 0 0 -GG[T>A]TG 5 1 1 0 1 1 1 2 0 1 0 2 1 1 3 -GG[T>A]TT 5 0 1 1 1 1 2 2 6 1 0 0 1 3 2 -GG[T>C]AA 3 2 5 5 1 0 2 5 1 3 0 1 2 7 0 -GG[T>C]AC 3 3 1 6 1 0 0 4 5 1 0 1 1 2 0 -GG[T>C]AG 2 4 4 3 3 2 4 4 3 3 0 2 1 5 2 -GG[T>C]AT 3 4 3 5 3 1 1 4 3 1 1 0 6 2 0 -GG[T>C]CA 4 4 2 7 4 1 2 1 2 3 2 2 0 2 1 -GG[T>C]CC 4 4 6 1 1 0 1 5 1 2 0 0 1 0 0 -GG[T>C]CG 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 -GG[T>C]CT 1 4 5 4 3 0 6 3 3 3 1 1 6 5 1 -GG[T>C]GA 5 2 10 0 0 1 3 4 2 5 1 1 3 0 0 -GG[T>C]GC 1 1 2 1 2 0 0 1 4 2 0 0 1 3 3 -GG[T>C]GG 1 1 4 4 1 2 3 3 3 6 0 2 2 0 0 -GG[T>C]GT 5 1 3 2 3 1 1 1 4 3 0 0 1 2 1 -GG[T>C]TA 2 0 4 2 2 0 2 1 0 1 2 1 1 0 0 -GG[T>C]TC 4 2 1 3 3 0 4 2 0 4 2 1 2 3 1 -GG[T>C]TG 4 3 2 5 1 1 2 2 4 3 3 3 2 5 4 -GG[T>C]TT 7 3 5 6 2 1 3 2 1 3 0 1 5 4 2 -GG[T>G]AA 0 0 1 0 1 0 0 2 0 2 0 0 0 0 0 -GG[T>G]AC 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 -GG[T>G]AG 2 0 0 0 0 0 0 1 0 0 0 0 0 0 1 -GG[T>G]AT 0 0 0 1 0 0 1 1 0 0 0 0 1 0 0 -GG[T>G]CA 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 -GG[T>G]CC 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 -GG[T>G]CG 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 -GG[T>G]CT 0 2 1 0 0 0 0 1 0 1 0 0 0 1 0 -GG[T>G]GA 0 0 1 0 3 0 0 0 1 1 0 0 1 0 1 -GG[T>G]GC 2 0 0 1 0 2 1 0 0 2 1 0 1 1 0 -GG[T>G]GG 2 0 0 0 0 0 0 0 0 0 0 0 2 1 0 -GG[T>G]GT 0 0 1 0 1 0 0 2 0 1 0 0 0 0 0 -GG[T>G]TA 1 0 1 0 1 0 0 0 0 0 1 1 0 1 0 -GG[T>G]TC 0 1 1 0 3 0 0 0 0 2 0 0 0 1 0 -GG[T>G]TG 2 1 1 0 1 0 0 1 0 0 0 1 0 0 0 -GG[T>G]TT 1 0 2 1 1 1 0 1 2 1 1 0 0 2 0 -GT[C>A]AA 9 3 11 10 3 0 4 10 6 5 2 3 3 6 3 -GT[C>A]AC 7 3 6 4 5 0 2 4 2 5 3 1 2 4 3 -GT[C>A]AG 4 3 6 1 3 2 0 2 3 3 0 0 0 2 3 -GT[C>A]AT 9 2 6 8 5 0 5 10 7 7 1 1 4 2 2 -GT[C>A]CA 11 4 3 6 4 1 5 6 5 6 3 3 5 4 4 -GT[C>A]CC 8 2 8 5 5 0 4 4 1 6 2 2 2 6 3 -GT[C>A]CG 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 -GT[C>A]CT 11 2 8 3 3 2 4 5 2 8 2 2 5 4 4 -GT[C>A]GA 0 0 1 0 0 1 0 0 0 0 0 0 2 0 0 -GT[C>A]GC 0 1 2 0 0 0 0 1 1 0 0 0 1 0 0 -GT[C>A]GG 1 0 0 1 1 0 0 1 1 2 0 0 0 1 0 -GT[C>A]GT 0 0 0 1 0 0 0 0 2 0 0 0 0 0 0 -GT[C>A]TA 8 1 4 5 2 1 3 4 3 4 0 1 1 1 1 -GT[C>A]TC 4 2 6 2 11 0 1 6 4 5 0 1 1 2 3 -GT[C>A]TG 8 4 8 6 2 0 3 5 5 4 2 0 2 5 3 -GT[C>A]TT 11 2 10 8 4 1 3 5 7 7 0 4 3 6 3 -GT[C>G]AA 9 3 7 1 4 0 0 8 2 5 2 0 2 4 0 -GT[C>G]AC 5 0 4 0 1 0 0 3 1 1 0 0 1 2 0 -GT[C>G]AG 3 3 6 6 8 2 4 6 4 4 0 2 5 5 0 -GT[C>G]AT 8 1 3 0 4 1 2 6 0 1 0 0 0 0 0 -GT[C>G]CA 5 2 4 0 4 1 2 1 2 4 1 1 1 1 2 -GT[C>G]CC 3 5 6 3 7 0 5 2 2 4 2 0 0 0 0 -GT[C>G]CG 0 1 3 0 1 0 0 1 0 0 0 0 0 1 0 -GT[C>G]CT 5 3 2 1 5 2 4 3 5 5 1 0 1 3 0 -GT[C>G]GA 0 1 1 0 3 0 1 1 0 0 1 0 1 0 0 -GT[C>G]GC 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 -GT[C>G]GG 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 -GT[C>G]GT 2 1 0 0 0 1 0 0 0 2 0 0 0 1 0 -GT[C>G]TA 2 2 2 4 6 0 3 10 3 4 0 0 4 3 4 -GT[C>G]TC 6 5 5 3 9 1 0 8 7 7 2 2 2 3 4 -GT[C>G]TG 6 1 6 3 4 1 3 6 2 4 1 0 2 1 0 -GT[C>G]TT 0 1 8 6 12 0 5 18 3 9 2 2 2 4 0 -GT[C>T]AA 13 4 14 10 8 1 5 8 4 4 0 3 5 3 2 -GT[C>T]AC 6 2 3 5 4 1 3 6 2 4 1 0 2 2 6 -GT[C>T]AG 10 5 3 7 6 1 5 10 2 4 2 1 1 3 2 -GT[C>T]AT 20 6 15 11 10 1 4 10 3 7 2 3 2 6 8 -GT[C>T]CA 5 6 7 3 8 0 3 9 3 7 3 0 3 2 4 -GT[C>T]CC 4 5 7 4 4 1 4 10 5 5 2 0 6 5 2 -GT[C>T]CG 0 0 0 0 1 0 1 2 1 0 0 0 1 1 0 -GT[C>T]CT 12 2 9 6 9 1 4 11 5 3 2 2 7 4 6 -GT[C>T]GA 7 3 1 1 2 1 0 1 2 3 0 0 1 1 0 -GT[C>T]GC 4 1 2 1 1 0 0 3 2 3 1 1 1 0 2 -GT[C>T]GG 5 1 0 3 2 2 1 1 0 1 0 0 1 1 1 -GT[C>T]GT 6 1 4 3 1 1 1 2 1 1 1 0 1 0 4 -GT[C>T]TA 4 3 4 1 3 2 1 1 5 2 0 0 0 3 0 -GT[C>T]TC 10 6 8 6 7 3 3 5 0 6 2 0 4 2 3 -GT[C>T]TG 8 2 5 8 2 2 1 7 4 3 1 2 0 2 2 -GT[C>T]TT 4 3 14 7 8 2 4 6 7 6 0 1 3 6 1 -GT[T>A]AA 24 2 0 4 3 1 1 3 3 2 0 0 2 2 0 -GT[T>A]AC 4 0 2 2 2 0 1 0 0 1 0 0 1 0 2 -GT[T>A]AG 24 1 0 0 1 0 1 5 0 2 1 1 0 0 0 -GT[T>A]AT 21 0 3 1 2 1 4 2 1 0 1 2 1 2 4 -GT[T>A]CA 14 4 6 1 7 0 2 2 3 4 0 3 1 5 3 -GT[T>A]CC 6 3 5 4 4 0 1 2 3 0 0 1 1 1 0 -GT[T>A]CG 3 0 1 1 0 0 0 1 0 0 0 0 1 0 0 -GT[T>A]CT 6 1 9 2 5 0 8 5 1 0 1 1 2 4 2 -GT[T>A]GA 4 1 2 2 2 1 1 1 2 1 2 0 2 0 0 -GT[T>A]GC 4 1 5 2 2 1 1 0 3 1 0 1 0 4 1 -GT[T>A]GG 7 1 2 2 1 0 4 3 1 2 0 2 1 3 0 -GT[T>A]GT 12 1 5 3 4 1 1 0 2 1 0 0 2 1 1 -GT[T>A]TA 5 1 1 4 2 1 0 2 2 1 1 1 0 2 0 -GT[T>A]TC 6 0 6 2 4 0 3 2 3 4 0 0 1 2 1 -GT[T>A]TG 9 0 3 2 1 0 0 6 1 2 0 0 2 1 0 -GT[T>A]TT 10 7 6 3 3 2 7 3 3 2 2 1 2 1 2 -GT[T>C]AA 4 2 6 3 3 1 3 2 5 0 0 0 1 7 0 -GT[T>C]AC 6 5 8 3 3 0 1 0 3 2 0 1 0 2 0 -GT[T>C]AG 7 1 3 0 9 0 1 2 3 2 0 0 1 1 0 -GT[T>C]AT 6 1 3 1 3 0 2 1 4 3 0 1 3 1 0 -GT[T>C]CA 1 1 4 2 5 0 0 5 1 4 0 0 0 3 0 -GT[T>C]CC 1 0 5 1 1 1 3 2 3 0 1 1 2 0 0 -GT[T>C]CG 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 -GT[T>C]CT 3 2 2 1 5 0 0 2 1 1 0 0 1 3 1 -GT[T>C]GA 0 0 1 0 1 0 0 2 1 0 0 0 1 0 0 -GT[T>C]GC 3 2 3 0 0 0 0 0 1 3 0 1 1 1 2 -GT[T>C]GG 2 2 1 1 1 0 1 0 0 3 0 1 2 1 0 -GT[T>C]GT 1 0 1 1 3 0 3 5 0 0 1 2 1 3 1 -GT[T>C]TA 4 1 6 1 4 0 0 2 0 2 0 0 1 1 1 -GT[T>C]TC 6 3 8 1 3 0 3 0 2 3 0 3 1 5 2 -GT[T>C]TG 5 1 1 3 5 1 0 2 1 1 2 2 0 0 1 -GT[T>C]TT 5 1 4 2 1 0 2 0 1 1 0 4 2 4 4 -GT[T>G]AA 4 0 0 1 3 0 1 1 0 5 0 0 2 1 1 -GT[T>G]AC 1 0 0 0 2 0 2 1 3 1 0 0 0 0 0 -GT[T>G]AG 4 0 1 1 1 2 1 0 0 0 0 0 0 0 0 -GT[T>G]AT 4 0 1 0 1 0 0 0 0 0 0 0 0 1 0 -GT[T>G]CA 3 0 1 2 1 1 1 3 1 2 0 1 3 0 1 -GT[T>G]CC 0 1 2 1 2 0 2 1 2 0 2 0 1 0 0 -GT[T>G]CG 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 -GT[T>G]CT 0 1 1 1 3 0 3 0 1 1 1 0 1 4 2 -GT[T>G]GA 4 2 2 3 2 1 0 2 0 3 0 0 1 0 0 -GT[T>G]GC 1 1 3 2 0 0 0 2 2 3 1 0 0 2 0 -GT[T>G]GG 0 2 0 1 0 0 2 3 0 2 1 0 0 0 0 -GT[T>G]GT 3 1 3 0 1 0 2 2 1 1 0 0 1 1 1 -GT[T>G]TA 4 3 7 2 2 0 1 5 2 6 0 0 2 1 0 -GT[T>G]TC 0 4 4 2 3 1 5 3 0 8 0 1 2 3 2 -GT[T>G]TG 3 0 3 3 2 1 5 2 4 2 1 0 3 0 1 -GT[T>G]TT 8 2 5 5 7 1 3 11 3 5 1 1 4 2 3 -TA[C>A]AA 25 9 29 24 14 3 17 11 11 11 4 5 6 14 9 -TA[C>A]AC 10 0 8 8 6 1 3 7 3 4 3 0 2 4 6 -TA[C>A]AG 18 1 15 9 4 1 2 6 4 6 2 3 3 7 4 -TA[C>A]AT 21 7 32 20 8 0 10 8 8 10 1 4 10 17 5 -TA[C>A]CA 11 1 6 5 4 0 4 1 5 3 0 2 3 3 2 -TA[C>A]CC 0 1 4 4 2 0 0 2 3 5 0 0 3 1 2 -TA[C>A]CG 2 0 0 0 1 0 0 0 1 0 0 0 1 0 1 -TA[C>A]CT 5 1 11 4 4 0 6 5 6 4 2 0 5 2 4 -TA[C>A]GA 1 0 1 1 1 0 0 2 0 1 0 1 1 4 0 -TA[C>A]GC 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 -TA[C>A]GG 2 2 2 0 1 0 0 4 1 1 1 0 0 1 0 -TA[C>A]GT 3 1 1 0 1 0 0 1 1 1 0 0 0 3 1 -TA[C>A]TA 12 2 4 3 2 1 0 3 2 6 0 1 7 1 3 -TA[C>A]TC 5 3 2 0 1 0 1 3 3 1 0 0 0 2 0 -TA[C>A]TG 13 3 4 3 5 2 3 4 3 7 1 1 2 4 5 -TA[C>A]TT 14 4 11 3 9 2 3 4 8 4 3 0 7 5 5 -TA[C>G]AA 8 2 4 3 1 0 2 7 8 6 1 1 0 2 0 -TA[C>G]AC 3 1 2 1 0 1 2 3 0 3 0 0 0 1 0 -TA[C>G]AG 12 5 7 7 5 3 2 5 2 5 2 3 5 3 5 -TA[C>G]AT 8 0 2 2 2 1 1 3 3 3 1 1 5 3 0 -TA[C>G]CA 5 0 2 1 1 2 2 7 6 7 0 0 2 4 1 -TA[C>G]CC 3 0 1 1 1 0 1 3 4 4 0 0 1 4 0 -TA[C>G]CG 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 -TA[C>G]CT 5 1 2 2 0 0 0 3 1 3 1 1 2 1 3 -TA[C>G]GA 3 0 1 1 0 0 0 1 0 0 0 0 0 0 0 -TA[C>G]GC 1 0 0 0 1 0 2 2 0 0 0 0 0 0 1 -TA[C>G]GG 0 0 1 0 1 0 0 2 0 0 0 0 0 0 0 -TA[C>G]GT 2 1 1 0 1 0 1 0 0 0 0 1 1 1 0 -TA[C>G]TA 10 4 10 2 3 1 5 8 3 7 1 3 1 2 0 -TA[C>G]TC 6 1 3 2 2 0 2 8 3 2 1 0 2 3 3 -TA[C>G]TG 5 3 4 1 3 0 3 8 2 3 2 2 3 5 5 -TA[C>G]TT 9 5 5 7 3 1 8 7 5 4 0 3 7 0 3 -TA[C>T]AA 9 6 8 9 5 1 8 6 6 7 0 2 5 6 5 -TA[C>T]AC 6 1 3 5 4 3 0 3 5 2 0 3 7 1 1 -TA[C>T]AG 11 4 13 5 8 6 3 12 4 12 3 3 0 5 3 -TA[C>T]AT 21 11 14 16 13 4 10 17 4 10 3 2 9 10 5 -TA[C>T]CA 9 3 5 5 9 1 5 5 2 12 1 2 4 9 3 -TA[C>T]CC 5 3 5 4 6 0 3 2 2 4 3 0 5 3 1 -TA[C>T]CG 1 0 2 1 0 0 0 0 1 1 0 1 0 1 0 -TA[C>T]CT 6 6 4 1 6 2 4 4 5 5 1 1 4 6 3 -TA[C>T]GA 11 6 3 3 6 1 4 6 9 10 1 0 9 3 2 -TA[C>T]GC 8 5 6 5 3 1 5 5 3 8 0 0 3 7 1 -TA[C>T]GG 16 4 6 5 5 1 7 4 7 4 1 1 5 4 0 -TA[C>T]GT 23 11 6 10 5 7 9 8 4 8 2 4 9 6 2 -TA[C>T]TA 8 4 9 4 9 2 3 5 4 5 2 1 4 5 6 -TA[C>T]TC 4 5 7 4 7 1 5 5 8 6 0 0 3 3 3 -TA[C>T]TG 6 7 4 7 10 4 9 11 5 7 0 2 8 9 3 -TA[C>T]TT 14 12 11 9 10 3 11 8 7 10 4 4 11 8 9 -TA[T>A]AA 43 3 5 6 4 3 5 6 6 7 2 2 6 2 2 -TA[T>A]AC 8 1 2 3 4 1 4 2 1 5 0 0 0 3 1 -TA[T>A]AG 28 0 3 3 4 0 3 1 1 5 1 2 1 0 1 -TA[T>A]AT 81 3 4 1 5 1 6 7 3 5 0 3 4 3 2 -TA[T>A]CA 20 1 3 4 2 0 1 1 3 1 0 1 0 0 1 -TA[T>A]CC 4 0 5 1 0 0 1 1 0 2 1 1 1 2 1 -TA[T>A]CG 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 -TA[T>A]CT 7 2 4 5 3 1 4 4 0 3 1 3 1 1 0 -TA[T>A]GA 10 3 5 3 2 0 2 1 0 6 1 1 6 1 2 -TA[T>A]GC 9 2 4 3 2 2 3 0 1 0 0 1 2 1 1 -TA[T>A]GG 25 0 2 1 3 0 3 4 2 3 1 3 1 0 0 -TA[T>A]GT 30 6 7 5 2 0 1 3 1 5 4 0 2 2 0 -TA[T>A]TA 13 1 4 4 8 1 2 4 1 5 0 1 1 4 1 -TA[T>A]TC 6 0 4 5 5 2 3 1 4 3 0 0 2 2 1 -TA[T>A]TG 23 1 5 1 3 4 4 2 5 2 1 0 1 1 1 -TA[T>A]TT 17 5 9 7 8 3 2 9 2 9 1 5 3 4 5 -TA[T>C]AA 25 7 27 11 11 2 10 14 8 9 5 4 14 11 9 -TA[T>C]AC 32 12 16 15 12 1 7 7 12 10 3 2 14 8 5 -TA[T>C]AG 26 10 16 14 5 0 7 9 7 9 1 3 9 12 5 -TA[T>C]AT 60 21 33 33 25 3 7 22 14 19 4 4 14 25 7 -TA[T>C]CA 13 10 19 9 4 1 7 7 2 9 2 3 5 8 4 -TA[T>C]CC 4 2 11 5 3 2 6 3 4 4 2 0 4 4 3 -TA[T>C]CG 0 0 1 0 0 0 0 1 0 2 0 0 0 0 0 -TA[T>C]CT 10 8 18 11 7 1 8 3 3 5 4 3 8 10 2 -TA[T>C]GA 15 1 19 12 6 4 6 4 4 10 3 4 5 12 4 -TA[T>C]GC 8 6 11 7 6 3 2 5 8 6 1 3 7 6 7 -TA[T>C]GG 10 8 15 5 10 1 2 5 6 2 6 0 7 6 0 -TA[T>C]GT 27 10 24 12 14 3 10 9 3 6 1 5 5 11 7 -TA[T>C]TA 22 7 12 10 12 3 4 13 10 10 1 3 6 5 4 -TA[T>C]TC 23 4 14 9 10 1 3 12 4 14 1 2 8 13 4 -TA[T>C]TG 14 8 10 12 14 1 9 5 10 10 3 0 6 9 2 -TA[T>C]TT 18 13 14 21 19 4 11 14 14 19 4 0 7 26 9 -TA[T>G]AA 9 3 5 3 3 0 3 4 5 4 0 0 4 0 3 -TA[T>G]AC 2 3 0 1 3 1 1 1 0 0 1 0 1 0 0 -TA[T>G]AG 7 0 0 1 1 0 2 2 2 2 0 0 1 3 3 -TA[T>G]AT 15 2 2 0 4 2 3 6 0 5 0 1 1 0 1 -TA[T>G]CA 6 1 4 2 3 1 1 3 1 3 0 0 0 0 0 -TA[T>G]CC 1 0 2 1 2 0 0 0 0 0 0 0 2 0 0 -TA[T>G]CG 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -TA[T>G]CT 3 1 4 3 1 2 0 1 2 0 0 0 0 0 1 -TA[T>G]GA 1 1 2 0 4 1 2 3 0 4 1 0 2 1 2 -TA[T>G]GC 5 2 1 0 1 0 2 4 0 1 1 2 1 0 1 -TA[T>G]GG 1 0 1 0 1 1 0 2 1 0 0 1 0 0 0 -TA[T>G]GT 3 2 2 1 3 0 4 2 2 0 1 1 1 0 1 -TA[T>G]TA 3 3 5 5 8 0 1 9 4 8 1 1 5 1 1 -TA[T>G]TC 0 0 3 2 1 1 2 2 1 5 0 0 2 0 1 -TA[T>G]TG 1 2 1 2 1 0 1 0 2 4 0 0 0 1 2 -TA[T>G]TT 10 0 9 5 8 0 5 9 3 8 2 1 3 4 3 -TC[C>A]AA 16 4 17 9 10 2 1 5 7 7 0 1 3 7 3 -TC[C>A]AC 19 4 10 6 3 0 2 6 3 8 2 0 1 7 1 -TC[C>A]AG 12 3 3 9 6 0 4 9 6 2 1 0 4 3 5 -TC[C>A]AT 35 14 27 12 11 0 6 8 4 4 1 1 13 20 1 -TC[C>A]CA 16 2 21 7 8 0 3 10 10 3 2 0 7 4 5 -TC[C>A]CC 14 6 12 10 7 4 3 9 3 2 0 1 4 9 3 -TC[C>A]CG 4 1 0 0 2 0 0 0 0 2 0 0 0 1 0 -TC[C>A]CT 23 14 19 11 11 3 2 9 4 4 4 4 5 6 7 -TC[C>A]GA 1 0 1 2 0 0 0 2 0 0 0 0 1 1 0 -TC[C>A]GC 0 0 0 0 0 0 0 0 1 3 0 0 0 1 1 -TC[C>A]GG 1 2 1 0 0 0 1 1 0 0 0 0 0 0 0 -TC[C>A]GT 2 0 0 1 2 0 1 1 1 1 0 0 2 0 1 -TC[C>A]TA 14 3 5 2 1 1 1 2 2 3 0 1 1 4 2 -TC[C>A]TC 15 0 16 7 3 1 7 4 5 4 1 2 7 5 3 -TC[C>A]TG 14 3 11 4 11 1 5 9 12 7 0 1 1 5 2 -TC[C>A]TT 28 10 16 9 9 3 5 11 5 7 4 1 7 12 7 -TC[C>G]AA 7 5 7 3 4 0 3 2 2 2 0 1 1 3 4 -TC[C>G]AC 3 2 2 3 2 0 0 1 0 1 0 0 0 3 1 -TC[C>G]AG 5 1 4 4 0 2 1 2 1 1 1 1 2 3 0 -TC[C>G]AT 1 0 2 3 2 0 0 3 1 1 0 3 4 0 1 -TC[C>G]CA 13 2 3 2 4 1 3 8 1 8 0 1 2 2 4 -TC[C>G]CC 4 1 7 2 2 0 0 2 2 3 4 1 1 2 1 -TC[C>G]CG 2 0 1 0 0 0 1 0 0 0 0 0 0 0 0 -TC[C>G]CT 4 1 4 4 0 1 1 6 2 5 1 1 3 5 3 -TC[C>G]GA 2 0 0 0 1 1 1 0 0 0 0 0 0 0 0 -TC[C>G]GC 1 0 1 0 1 0 0 1 0 1 0 0 1 0 0 -TC[C>G]GG 0 0 0 2 0 0 0 0 0 0 0 0 0 0 1 -TC[C>G]GT 0 0 1 1 2 0 0 2 2 1 0 0 0 0 0 -TC[C>G]TA 6 3 7 1 3 0 2 6 4 5 2 1 3 0 1 -TC[C>G]TC 1 2 4 3 10 3 6 6 4 3 1 1 3 4 2 -TC[C>G]TG 5 1 9 3 3 1 2 6 0 4 1 1 2 1 2 -TC[C>G]TT 4 2 5 4 6 2 3 13 6 5 0 0 7 4 2 -TC[C>T]AA 8 5 8 12 9 0 5 9 4 8 1 0 6 7 4 -TC[C>T]AC 11 3 7 11 6 2 2 7 4 7 0 1 3 4 3 -TC[C>T]AG 8 6 7 4 5 3 5 6 2 8 1 3 5 6 6 -TC[C>T]AT 18 8 13 8 10 2 3 5 9 9 1 1 3 12 6 -TC[C>T]CA 10 7 11 8 5 0 7 11 8 11 5 3 7 7 5 -TC[C>T]CC 14 7 4 4 11 4 6 8 6 4 1 1 12 10 6 -TC[C>T]CG 1 2 1 2 1 0 0 0 0 0 0 0 0 1 0 -TC[C>T]CT 18 13 12 15 7 3 11 12 5 18 1 1 4 5 11 -TC[C>T]GA 3 5 1 11 6 0 0 4 3 7 2 2 5 3 4 -TC[C>T]GC 18 9 4 6 6 1 3 8 2 6 1 0 7 7 4 -TC[C>T]GG 11 3 8 4 4 1 4 4 5 7 0 2 4 3 1 -TC[C>T]GT 14 5 3 6 6 3 5 5 10 8 1 1 4 2 4 -TC[C>T]TA 11 5 11 11 5 0 3 9 5 6 2 1 8 5 1 -TC[C>T]TC 11 7 3 5 7 1 4 8 5 13 2 0 3 8 3 -TC[C>T]TG 15 8 15 7 13 2 6 24 11 10 1 1 6 7 6 -TC[C>T]TT 10 6 12 8 11 2 9 7 8 9 4 4 6 11 2 -TC[T>A]AA 38 4 2 1 2 3 2 4 5 10 3 5 2 0 2 -TC[T>A]AC 12 1 2 3 2 1 5 8 4 1 1 0 2 0 0 -TC[T>A]AG 40 1 3 1 2 0 4 2 2 5 0 2 3 1 1 -TC[T>A]AT 80 0 4 3 5 3 2 6 3 4 2 4 0 3 1 -TC[T>A]CA 17 2 3 7 8 0 2 3 5 2 1 0 1 7 1 -TC[T>A]CC 8 4 4 6 8 2 3 6 6 6 1 1 2 8 2 -TC[T>A]CG 0 0 1 0 0 0 1 2 0 1 0 0 0 0 0 -TC[T>A]CT 22 4 9 5 6 1 1 9 6 1 1 3 2 7 0 -TC[T>A]GA 35 1 6 1 4 1 3 6 8 3 1 1 3 5 3 -TC[T>A]GC 8 0 9 5 1 1 5 3 0 6 1 1 1 1 1 -TC[T>A]GG 17 1 5 3 3 1 3 0 4 4 0 3 3 1 0 -TC[T>A]GT 60 1 6 6 4 3 5 7 4 6 1 0 2 6 3 -TC[T>A]TA 21 2 6 1 4 0 1 5 3 7 1 0 2 3 1 -TC[T>A]TC 7 2 9 2 3 1 4 2 2 3 0 2 1 0 4 -TC[T>A]TG 22 2 5 2 5 1 4 5 4 5 1 1 1 2 3 -TC[T>A]TT 17 5 12 10 10 2 4 11 4 12 3 4 2 2 1 -TC[T>C]AA 11 7 6 4 3 2 1 6 2 3 2 4 2 9 3 -TC[T>C]AC 14 5 17 1 5 2 7 8 5 4 2 2 5 7 4 -TC[T>C]AG 8 3 6 5 6 2 2 13 10 6 2 2 2 3 3 -TC[T>C]AT 17 2 19 16 12 0 6 6 5 10 4 1 4 7 5 -TC[T>C]CA 11 11 17 14 5 1 1 3 4 9 2 2 3 8 2 -TC[T>C]CC 11 4 8 10 7 3 4 4 3 4 3 1 4 5 0 -TC[T>C]CG 2 1 0 0 0 0 0 1 0 4 0 0 2 1 0 -TC[T>C]CT 21 12 28 17 19 2 11 12 7 7 3 5 10 23 8 -TC[T>C]GA 11 2 8 6 8 0 3 5 1 5 1 0 5 8 2 -TC[T>C]GC 10 0 6 4 0 2 3 6 6 6 1 0 3 9 2 -TC[T>C]GG 7 1 4 5 1 2 1 4 4 6 1 1 2 2 1 -TC[T>C]GT 16 5 7 9 6 2 4 13 8 5 4 1 4 4 0 -TC[T>C]TA 10 6 5 4 1 2 5 8 1 7 2 0 5 5 1 -TC[T>C]TC 11 5 16 13 6 1 6 8 4 4 0 1 0 10 4 -TC[T>C]TG 7 5 15 7 4 0 4 5 6 6 1 4 2 7 3 -TC[T>C]TT 21 9 33 26 17 4 9 15 13 16 1 4 7 14 5 -TC[T>G]AA 4 0 0 0 1 1 1 3 1 3 0 1 0 1 0 -TC[T>G]AC 3 0 1 2 0 0 0 0 0 0 0 0 1 0 0 -TC[T>G]AG 4 2 1 1 2 0 0 0 1 1 0 0 0 0 0 -TC[T>G]AT 5 0 3 2 0 2 2 1 0 2 1 0 2 0 0 -TC[T>G]CA 2 0 1 6 2 0 3 6 3 6 1 1 3 2 0 -TC[T>G]CC 3 0 1 1 4 0 1 4 1 1 0 0 0 1 1 -TC[T>G]CG 0 0 0 0 1 0 0 2 0 0 0 1 1 0 0 -TC[T>G]CT 7 2 3 0 5 0 1 3 0 4 0 1 2 1 3 -TC[T>G]GA 1 1 1 4 2 0 4 2 2 3 0 0 1 2 1 -TC[T>G]GC 1 2 0 0 2 1 1 3 1 0 1 1 2 0 1 -TC[T>G]GG 3 1 3 1 1 0 1 1 1 2 0 0 0 2 0 -TC[T>G]GT 10 1 3 1 1 0 2 1 1 2 2 1 3 0 1 -TC[T>G]TA 5 5 5 3 4 1 2 7 5 3 1 0 0 1 1 -TC[T>G]TC 5 3 1 2 2 0 0 8 1 5 3 0 0 0 2 -TC[T>G]TG 4 1 8 2 0 1 3 0 2 4 0 1 1 2 0 -TC[T>G]TT 5 6 7 2 7 1 4 7 7 14 1 2 3 4 3 -TG[C>A]AA 17 5 13 7 5 0 5 6 9 9 3 4 7 10 4 -TG[C>A]AC 8 4 9 6 4 1 3 1 4 2 0 0 3 2 4 -TG[C>A]AG 12 6 7 7 5 3 0 4 6 4 0 2 5 10 4 -TG[C>A]AT 29 11 20 7 11 0 5 7 10 10 1 4 4 13 7 -TG[C>A]CA 13 5 7 6 5 2 5 3 7 1 0 3 2 5 4 -TG[C>A]CC 4 4 8 3 4 1 2 4 3 3 0 0 2 4 3 -TG[C>A]CG 3 0 2 0 2 0 1 0 0 0 0 0 0 1 0 -TG[C>A]CT 15 7 17 9 2 3 3 8 9 2 0 4 5 5 2 -TG[C>A]GA 1 0 0 1 0 0 1 0 0 1 0 0 0 2 0 -TG[C>A]GC 1 2 0 2 0 0 0 0 0 1 0 1 2 1 0 -TG[C>A]GG 4 1 0 2 0 1 0 0 0 0 0 0 2 1 2 -TG[C>A]GT 1 0 1 0 0 0 0 2 0 0 0 0 0 1 2 -TG[C>A]TA 8 0 2 4 1 0 2 0 4 4 1 0 2 3 3 -TG[C>A]TC 3 4 5 4 2 0 4 6 3 1 1 1 0 5 5 -TG[C>A]TG 13 2 4 5 5 1 5 10 8 3 0 0 6 3 3 -TG[C>A]TT 9 7 11 11 5 2 5 8 9 7 1 4 2 3 3 -TG[C>G]AA 2 2 2 2 3 1 2 5 0 4 2 0 2 2 1 -TG[C>G]AC 1 0 1 1 0 1 2 0 1 2 0 0 0 1 0 -TG[C>G]AG 3 0 1 4 1 1 0 2 1 3 1 2 1 3 4 -TG[C>G]AT 3 1 4 3 1 0 1 2 1 2 0 1 2 0 1 -TG[C>G]CA 5 0 4 1 4 2 0 2 1 3 1 0 4 1 2 -TG[C>G]CC 3 1 1 2 1 0 2 4 0 2 1 1 2 0 0 -TG[C>G]CG 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 -TG[C>G]CT 6 0 3 2 6 2 2 5 0 4 2 1 4 3 2 -TG[C>G]GA 3 0 1 0 0 0 0 0 1 0 0 0 0 0 1 -TG[C>G]GC 0 0 2 0 0 0 1 0 0 0 0 0 1 1 0 -TG[C>G]GG 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -TG[C>G]GT 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 -TG[C>G]TA 4 2 2 1 4 1 3 3 1 1 0 0 0 1 2 -TG[C>G]TC 6 1 4 0 2 0 0 1 3 2 2 0 1 0 0 -TG[C>G]TG 6 2 2 2 2 0 1 6 4 4 1 0 1 2 0 -TG[C>G]TT 2 1 7 1 2 1 2 4 3 3 1 0 2 4 4 -TG[C>T]AA 11 7 16 6 9 0 2 12 7 13 2 3 7 8 7 -TG[C>T]AC 9 4 2 8 6 3 4 4 11 6 0 0 5 6 2 -TG[C>T]AG 11 2 14 13 10 3 4 12 9 13 2 2 8 7 8 -TG[C>T]AT 7 11 11 11 4 1 5 9 4 9 2 1 9 12 5 -TG[C>T]CA 10 6 9 11 6 4 11 3 7 4 0 4 9 7 2 -TG[C>T]CC 13 2 10 7 4 0 6 9 12 9 1 1 5 7 6 -TG[C>T]CG 1 2 1 2 3 0 1 0 1 2 0 0 2 0 1 -TG[C>T]CT 9 9 19 18 18 3 3 14 11 14 2 2 7 12 8 -TG[C>T]GA 14 3 5 3 4 1 7 3 3 10 1 2 2 1 1 -TG[C>T]GC 5 1 6 8 2 0 5 3 5 6 0 1 4 2 3 -TG[C>T]GG 15 4 2 4 5 3 3 4 4 3 2 3 8 2 3 -TG[C>T]GT 9 3 8 4 2 2 6 5 4 11 0 1 5 2 1 -TG[C>T]TA 7 6 7 11 3 2 1 3 8 3 0 1 2 8 6 -TG[C>T]TC 10 7 5 4 5 3 9 9 11 7 1 2 7 5 2 -TG[C>T]TG 9 3 13 10 11 2 14 6 8 9 3 2 3 10 5 -TG[C>T]TT 14 7 9 9 3 2 8 8 7 6 3 2 6 12 7 -TG[T>A]AA 29 3 2 1 4 2 4 1 3 4 0 1 1 0 1 -TG[T>A]AC 13 0 2 0 0 0 3 5 3 1 0 0 0 1 0 -TG[T>A]AG 25 0 1 2 0 0 0 3 2 1 0 0 3 1 2 -TG[T>A]AT 36 0 3 1 6 0 2 1 3 4 0 0 1 1 1 -TG[T>A]CA 12 2 10 2 3 2 4 7 2 4 0 1 2 0 1 -TG[T>A]CC 6 0 1 2 3 2 0 3 4 2 3 3 1 1 1 -TG[T>A]CG 1 0 0 0 0 1 0 2 0 0 0 0 0 0 0 -TG[T>A]CT 7 2 4 7 4 1 4 3 5 4 2 3 2 3 1 -TG[T>A]GA 7 0 7 2 5 2 1 3 1 3 0 0 2 5 3 -TG[T>A]GC 5 1 6 1 0 0 1 3 1 4 0 1 2 3 2 -TG[T>A]GG 3 2 4 1 3 0 2 3 4 3 0 2 0 1 0 -TG[T>A]GT 18 1 2 4 4 3 1 2 3 3 0 0 1 1 2 -TG[T>A]TA 3 1 4 5 5 0 2 0 3 0 0 1 3 1 4 -TG[T>A]TC 6 1 2 2 2 0 1 0 5 1 0 1 0 3 2 -TG[T>A]TG 12 0 0 4 2 2 2 4 1 1 0 1 3 0 4 -TG[T>A]TT 5 2 3 3 6 1 0 6 3 3 4 1 3 2 1 -TG[T>C]AA 15 11 20 5 6 0 8 11 3 4 2 2 7 13 4 -TG[T>C]AC 17 5 15 12 2 1 4 7 2 4 2 3 7 11 0 -TG[T>C]AG 19 5 13 8 2 1 3 9 4 0 0 0 6 3 2 -TG[T>C]AT 29 13 24 11 12 3 6 11 11 13 2 4 7 18 7 -TG[T>C]CA 18 10 11 6 4 0 7 5 2 12 1 3 1 7 0 -TG[T>C]CC 4 5 8 2 5 1 2 3 3 3 0 0 0 4 1 -TG[T>C]CG 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 -TG[T>C]CT 20 6 18 6 8 1 6 7 4 7 2 2 13 20 3 -TG[T>C]GA 9 7 9 4 3 0 3 5 4 2 0 0 1 2 2 -TG[T>C]GC 7 4 5 2 3 1 3 5 2 5 0 1 2 7 1 -TG[T>C]GG 3 5 7 4 1 1 6 5 5 6 1 0 2 6 3 -TG[T>C]GT 9 2 10 7 5 1 6 5 9 6 1 1 3 1 2 -TG[T>C]TA 8 4 7 5 5 0 7 12 4 3 0 0 3 4 2 -TG[T>C]TC 21 6 14 8 7 2 7 4 7 6 1 2 12 9 4 -TG[T>C]TG 9 8 12 9 6 2 11 9 7 7 2 2 6 10 3 -TG[T>C]TT 8 11 17 11 9 2 11 11 10 12 1 1 7 13 6 -TG[T>G]AA 4 2 0 2 0 0 1 0 2 3 0 0 2 0 0 -TG[T>G]AC 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 -TG[T>G]AG 3 1 0 1 0 0 0 0 1 1 1 0 0 0 1 -TG[T>G]AT 4 0 0 1 3 0 0 2 0 0 0 0 0 0 1 -TG[T>G]CA 1 0 0 1 0 0 1 3 1 2 1 0 0 0 1 -TG[T>G]CC 0 3 3 0 1 0 1 1 0 1 0 0 1 0 0 -TG[T>G]CG 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 -TG[T>G]CT 3 2 1 2 2 0 0 1 0 4 0 1 2 1 2 -TG[T>G]GA 0 1 2 3 2 0 1 4 1 3 0 0 1 0 0 -TG[T>G]GC 4 1 1 2 0 0 2 2 1 0 1 0 1 1 0 -TG[T>G]GG 3 1 1 2 0 0 0 3 1 1 0 0 0 1 0 -TG[T>G]GT 3 0 1 0 1 1 0 5 1 1 0 0 2 1 0 -TG[T>G]TA 3 1 3 0 3 0 4 2 0 6 1 0 1 0 1 -TG[T>G]TC 4 0 1 2 2 0 2 3 1 3 0 0 2 0 1 -TG[T>G]TG 4 3 1 0 1 1 0 1 1 6 0 0 1 0 1 -TG[T>G]TT 4 1 4 2 7 0 1 3 6 3 0 1 2 4 1 -TT[C>A]AA 16 6 16 14 9 4 5 19 5 5 2 3 4 5 2 -TT[C>A]AC 10 3 16 8 7 2 6 13 7 5 1 3 2 5 6 -TT[C>A]AG 10 6 5 4 8 0 3 7 6 12 0 1 3 2 4 -TT[C>A]AT 26 5 18 9 18 2 8 18 20 8 2 2 8 4 9 -TT[C>A]CA 13 8 8 12 4 0 5 10 17 7 3 3 8 8 3 -TT[C>A]CC 17 4 16 11 7 2 2 8 10 6 1 1 7 1 4 -TT[C>A]CG 2 0 2 1 1 0 0 1 0 1 0 0 0 2 0 -TT[C>A]CT 12 11 22 12 9 0 6 16 11 12 4 3 3 10 11 -TT[C>A]GA 2 0 1 0 1 0 4 3 1 2 0 0 0 1 1 -TT[C>A]GC 4 0 1 0 1 0 0 2 1 1 0 0 2 1 0 -TT[C>A]GG 0 1 0 1 0 0 0 1 0 2 0 0 1 0 0 -TT[C>A]GT 2 1 2 4 0 0 0 2 0 1 0 1 0 1 3 -TT[C>A]TA 13 3 10 3 10 1 2 8 11 10 3 3 3 6 3 -TT[C>A]TC 20 4 7 8 8 2 4 10 9 10 1 0 3 7 6 -TT[C>A]TG 20 4 6 8 14 2 5 6 15 6 2 3 5 7 5 -TT[C>A]TT 48 10 12 9 21 3 7 18 28 11 5 4 2 12 10 -TT[C>G]AA 5 2 15 2 8 1 4 13 6 6 3 2 3 4 3 -TT[C>G]AC 0 0 5 0 5 0 1 0 2 0 0 1 1 2 1 -TT[C>G]AG 0 4 4 5 5 0 1 3 3 0 3 1 4 0 3 -TT[C>G]AT 1 0 6 2 3 0 1 5 2 1 2 1 0 1 0 -TT[C>G]CA 9 4 6 8 4 2 4 11 12 2 1 0 5 3 3 -TT[C>G]CC 2 2 2 1 5 0 5 7 2 5 2 0 2 5 2 -TT[C>G]CG 4 0 1 0 0 0 0 2 0 1 0 0 0 0 0 -TT[C>G]CT 8 3 6 4 2 0 3 5 3 7 1 3 2 3 3 -TT[C>G]GA 1 1 3 0 2 1 1 1 1 0 0 0 0 0 0 -TT[C>G]GC 0 1 0 1 1 0 0 2 0 0 0 0 1 1 0 -TT[C>G]GG 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 -TT[C>G]GT 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 -TT[C>G]TA 13 5 8 14 13 2 6 22 6 8 1 0 4 6 6 -TT[C>G]TC 8 3 12 5 13 1 9 12 5 5 2 2 3 2 3 -TT[C>G]TG 5 3 3 0 7 0 6 9 10 9 3 1 1 2 1 -TT[C>G]TT 13 8 12 9 10 1 15 32 16 14 1 4 4 5 5 -TT[C>T]AA 14 7 13 13 14 0 2 7 4 18 0 1 5 8 9 -TT[C>T]AC 11 6 11 9 5 2 2 6 6 5 2 2 5 6 3 -TT[C>T]AG 15 5 8 6 9 1 5 17 7 8 1 2 3 7 5 -TT[C>T]AT 17 15 14 13 10 4 9 16 15 21 2 4 6 12 5 -TT[C>T]CA 7 7 10 10 11 3 7 18 5 5 1 5 6 8 6 -TT[C>T]CC 16 15 10 16 9 5 8 22 8 9 3 1 10 17 2 -TT[C>T]CG 1 1 1 1 2 2 1 2 0 1 0 0 0 0 0 -TT[C>T]CT 19 18 23 15 18 4 13 22 12 20 2 1 11 21 10 -TT[C>T]GA 20 7 11 7 7 3 5 5 10 11 2 1 3 5 2 -TT[C>T]GC 7 5 2 3 3 0 3 3 0 6 2 0 0 2 4 -TT[C>T]GG 15 3 3 2 7 1 5 4 1 4 0 2 5 3 5 -TT[C>T]GT 11 7 4 4 3 4 3 3 5 8 0 1 4 3 2 -TT[C>T]TA 13 4 8 5 7 0 3 15 12 6 3 1 5 7 10 -TT[C>T]TC 19 7 9 11 10 0 10 17 11 8 2 0 3 1 9 -TT[C>T]TG 16 6 14 5 9 0 5 9 13 9 1 2 5 8 6 -TT[C>T]TT 32 12 18 18 18 1 5 15 8 6 2 7 7 14 8 -TT[T>A]AA 63 3 14 17 6 3 12 10 17 7 1 4 4 5 6 -TT[T>A]AC 13 2 4 2 4 0 3 3 4 3 1 0 3 2 3 -TT[T>A]AG 45 1 1 2 1 0 1 3 5 5 0 3 4 1 6 -TT[T>A]AT 77 4 11 14 12 3 6 21 7 9 0 4 2 5 7 -TT[T>A]CA 16 5 4 9 6 2 2 7 3 4 0 1 3 2 4 -TT[T>A]CC 7 2 8 6 5 1 1 6 6 6 1 2 1 4 2 -TT[T>A]CG 0 1 2 0 0 0 0 1 1 0 0 0 0 0 0 -TT[T>A]CT 21 6 12 8 9 3 13 21 10 7 4 3 4 5 4 -TT[T>A]GA 26 0 5 1 5 0 1 3 6 4 2 0 2 5 1 -TT[T>A]GC 13 3 7 5 0 1 1 3 1 3 1 0 1 2 1 -TT[T>A]GG 32 2 2 2 5 1 4 9 3 1 0 0 3 1 1 -TT[T>A]GT 47 3 6 6 6 2 7 6 2 5 1 2 3 1 2 -TT[T>A]TA 26 2 8 3 11 1 2 13 2 13 2 3 3 1 2 -TT[T>A]TC 2 3 9 4 5 0 4 4 4 13 3 1 3 3 1 -TT[T>A]TG 20 1 4 2 3 2 1 4 5 2 2 3 1 1 3 -TT[T>A]TT 27 3 19 8 11 1 5 6 9 16 6 2 10 10 8 -TT[T>C]AA 23 22 43 20 12 2 9 17 10 13 2 9 19 24 7 -TT[T>C]AC 24 11 24 15 13 1 7 8 4 12 5 6 8 18 2 -TT[T>C]AG 36 5 27 17 11 1 11 9 5 13 2 4 11 6 3 -TT[T>C]AT 68 30 76 40 31 2 22 26 21 25 5 8 19 41 3 -TT[T>C]CA 25 15 28 16 8 1 12 15 7 11 2 5 11 19 0 -TT[T>C]CC 24 11 32 16 10 1 9 12 7 9 3 4 11 14 4 -TT[T>C]CG 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 -TT[T>C]CT 31 17 45 23 15 1 12 20 12 14 2 5 22 28 4 -TT[T>C]GA 20 8 20 8 11 2 3 10 3 9 1 2 4 9 3 -TT[T>C]GC 20 5 26 12 4 1 7 5 8 7 1 4 4 10 2 -TT[T>C]GG 8 7 12 7 4 0 7 10 5 7 3 1 10 6 2 -TT[T>C]GT 33 15 32 17 17 3 9 9 9 12 4 4 14 25 4 -TT[T>C]TA 15 8 33 17 4 2 6 10 11 5 2 0 3 13 4 -TT[T>C]TC 16 9 34 20 8 1 10 6 7 12 0 5 17 21 0 -TT[T>C]TG 17 11 19 9 9 2 12 7 6 9 3 1 6 11 2 -TT[T>C]TT 31 25 40 23 19 2 18 14 11 26 2 10 21 20 4 -TT[T>G]AA 9 2 2 6 8 0 3 10 5 7 0 2 6 1 2 -TT[T>G]AC 4 1 1 1 1 0 1 2 0 1 0 0 0 0 0 -TT[T>G]AG 5 1 1 1 0 0 1 6 4 5 0 3 0 2 1 -TT[T>G]AT 8 1 4 4 3 0 3 5 1 3 0 0 2 2 2 -TT[T>G]CA 4 0 9 2 3 1 6 13 1 7 2 3 5 3 3 -TT[T>G]CC 12 2 3 2 1 2 3 5 4 4 1 0 5 0 6 -TT[T>G]CG 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 -TT[T>G]CT 9 6 11 4 11 0 10 7 2 10 3 2 1 3 2 -TT[T>G]GA 12 0 3 2 4 1 1 8 1 8 0 1 1 5 5 -TT[T>G]GC 2 3 2 1 2 0 1 4 2 1 1 0 3 1 2 -TT[T>G]GG 4 2 2 0 2 1 2 5 2 2 0 0 0 1 1 -TT[T>G]GT 11 1 8 1 2 2 2 4 3 2 3 0 3 2 0 -TT[T>G]TA 11 5 8 5 7 2 6 15 8 11 2 1 3 5 7 -TT[T>G]TC 5 2 8 6 6 0 2 13 6 11 2 0 4 4 1 -TT[T>G]TG 7 1 4 2 5 2 2 5 1 5 0 1 1 1 1 -TT[T>G]TT 15 5 15 18 13 0 14 27 11 17 2 8 5 6 11 \ No newline at end of file diff --git a/setup.py b/setup.py index cde6fb6..3039072 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,7 @@ def run(self): import sigProfilerPlotting as sigPlt sigPlt.install_plot_templates('SBS96') sigPlt.install_plot_templates('SBS288') + sigPlt.install_plot_templates('DBS78') os.system("echo 'installed figure templates' ") except: os.system("echo 'Failed to install templates' ") @@ -80,7 +81,7 @@ def run(self): license='UCSD', packages=['sigProfilerPlotting'], install_requires =[ - "matplotlib>=3.3.0,<=3.4.3", "pandas", "seaborn"], + "matplotlib>=3.3.0,<=3.4.3", "pandas", "seaborn","sklearn"], package_data={'':['fonts/*.ttf']}, include_package_data=True, #Specify the custom install class diff --git a/sigProfilerPlotting/sigProfilerPlotting.py b/sigProfilerPlotting/sigProfilerPlotting.py index 1229673..9cc62a0 100644 --- a/sigProfilerPlotting/sigProfilerPlotting.py +++ b/sigProfilerPlotting/sigProfilerPlotting.py @@ -29,6 +29,8 @@ import sigProfilerPlotting as spplt import pdb import itertools,time +import sklearn +from sklearn.preprocessing import LabelEncoder warnings.filterwarnings("ignore") @@ -262,8 +264,88 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): handles, labels = panel2.get_legend_handles_labels() panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) pickle.dump(plot1, open(path, 'wb')) - + + elif context =='DBS78': + + plot_custom_text = False + pcawg = False + sig_probs = False + plt.rcParams['axes.linewidth'] = 4 + plot1 = plt.figure(figsize=(43.93,9.92)) + plt.rc('axes', edgecolor='grey') + panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[3/256,189/256,239/256], [3/256,102/256,204/256],[162/256,207/256,99/256], + [1/256,102/256,1/256], [255/256,153/256,153/256], [228/256,41/256,38/256], + [255/256,178/256,102/256], [255/256,128/256,1/256], [204/256,153/256,255/256], + [76/256,1/256,153/256]] + + x = .043 + y3 = .87 + y = int(ymax*1.25) + y2 = y+2 + i = 0 + panel1.add_patch(plt.Rectangle((.043,y3), .101, .05, facecolor=colors[0], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.151,y3), .067, .05, facecolor=colors[1], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.225,y3), .102, .05, facecolor=colors[2], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.334,y3), .067, .05, facecolor=colors[3], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.408,y3), .102, .05, facecolor=colors[4], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.517,y3), .067, .05, facecolor=colors[5], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.591,y3), .067, .05, facecolor=colors[6], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.665,y3), .102, .05, facecolor=colors[7], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.774,y3), .102, .05, facecolor=colors[8], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((.883,y3), .102, .05, facecolor=colors[9], clip_on=False, transform=plt.gcf().transFigure)) + + yText = y3 + .06 + plt.text(.07, yText, 'AC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.163, yText, 'AT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.255, yText, 'CC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.345, yText, 'CG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.435, yText, 'CT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.527, yText, 'GC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.6, yText, 'TA>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.69, yText, 'TC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.8, yText, 'TG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + plt.text(.915, yText, 'TT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) + + if y <= 4: + y += 4 + + while y%4 != 0: + y += 1 + ytick_offest = int(y/4) + + labs = np.arange(0.44,78.44,1) + panel1.set_xlim([0, 78]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + # panel1.set_yticks(ylabs) + panel1.set_xticklabels(xlabels, rotation='vertical', fontsize=30, color='grey', fontname='Courier New', verticalalignment='top', fontweight='bold') + + # panel1.set_yticklabels(ylabels, fontsize=25) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.93,0.93,0.93], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + # if percentage: + # plt.ylabel("Percentage of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + # else: + # plt.ylabel("Number of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=True,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + [i.set_color("grey") for i in plt.gca().get_xticklabels()] + pickle.dump(plot1, open(path, 'wb')) @@ -3539,25 +3621,6 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if not percentage: ylabels = getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 96]) panel1.set_ylim([0, y]) @@ -3942,25 +4005,6 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo if not percentage: ylabels=getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 83]) panel1.set_ylim([0, y]) @@ -4805,25 +4849,6 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo if not percentage: ylabels = getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 83]) panel1.set_ylim([0, y]) @@ -4920,154 +4945,101 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo print("The provided plot_type: ", plot_type, " is not supported by this plotting function") def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None): - # if 'roman' in matplotlib.font_manager.weight_dict: - # del matplotlib.font_manager.weight_dict['roman'] - # matplotlib.font_manager._rebuild() + + + # context ='DBS78' + # package_path = spplt.__path__[0] + # install_path =os.path.join(package_path,'templates/') + # if not os.path.exists(install_path): + # os.mkdir(install_path) + + # filename= os.path.join(install_path,context+'.pkl') + # getdbstemp(context,path=filename) plot_custom_text = False pcawg = False sig_probs = False if plot_type == '78' or plot_type == '78DBS' or plot_type == 'DBS78': - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - mutation_type = first_line[0] - if first_line[0][2] != ">": - pcawg = True - if len(mutation_type) != 5 and first_line[0][2] == ">": - sys.exit("The matrix does not match the correct DBS96 format. Please check you formatting and rerun this plotting function.") - pp = PdfPages(output_path + 'DBS_78_plots_' + project + '.pdf') + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + # import pdb; + # pdb.set_trace() + # with open(matrix_path) as f: + # next(f) + # first_line = f.readline() + # first_line = first_line.strip().split() + # mutation_type = first_line[0] + # if first_line[0][2] != ">": + # pcawg = True + # if len(mutation_type) != 5 and first_line[0][2] == ">": + # sys.exit("The matrix does not match the correct DBS96 format. Please check you formatting and rerun this plotting function.") + # pp = PdfPages(output_path + 'DBS_78_plots_' + project + '.pdf') dinucs = ['TT>GG','TT>CG','TT>AG','TT>GC','TT>CC','TT>AC','TT>GA','TT>CA','TT>AA','AC>CA','AC>CG','AC>CT','AC>GA', - 'AC>GG','AC>GT','AC>TA','AC>TG','AC>TT','CT>AA','CT>AC','CT>AG','CT>GA','CT>GC','CT>GG','CT>TG','CT>TC', - 'CT>TA','AT>CA','AT>CC','AT>CG','AT>GA','AT>GC','AT>TA','TG>GT','TG>CT','TG>AT','TG>GC','TG>CC','TG>AC', - 'TG>GA','TG>CA','TG>AA','CC>AA','CC>AG','CC>AT','CC>GA','CC>GG','CC>GT','CC>TA','CC>TG','CC>TT','CG>AT', - 'CG>GC','CG>GT','CG>TC','CG>TA','CG>TT','TC>GT','TC>CT','TC>AT','TC>GG','TC>CG','TC>AG','TC>GA','TC>CA', - 'TC>AA','GC>AA','GC>AG','GC>AT','GC>CA','GC>CG','GC>TA','TA>GT','TA>CT','TA>AT','TA>GG','TA>CG','TA>GC'] + 'AC>GG','AC>GT','AC>TA','AC>TG','AC>TT','CT>AA','CT>AC','CT>AG','CT>GA','CT>GC','CT>GG','CT>TG','CT>TC', + 'CT>TA','AT>CA','AT>CC','AT>CG','AT>GA','AT>GC','AT>TA','TG>GT','TG>CT','TG>AT','TG>GC','TG>CC','TG>AC', + 'TG>GA','TG>CA','TG>AA','CC>AA','CC>AG','CC>AT','CC>GA','CC>GG','CC>GT','CC>TA','CC>TG','CC>TT','CG>AT', + 'CG>GC','CG>GT','CG>TC','CG>TA','CG>TT','TC>GT','TC>CT','TC>AT','TC>GG','TC>CG','TC>AG','TC>GA','TC>CA', + 'TC>AA','GC>AA','GC>AG','GC>AT','GC>CA','GC>CG','GC>TA','TA>GT','TA>CT','TA>AT','TA>GG','TA>CG','TA>GC'] revcompl = lambda x: ''.join([{'A':'T','C':'G','G':'C','T':'A'}[B] for B in x][::-1]) mutations = OrderedDict() + try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[2:] - samples = [x.replace('"','') for x in samples] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['AC'] = OrderedDict() - mutations[sample]['AT'] = OrderedDict() - mutations[sample]['CC'] = OrderedDict() - mutations[sample]['CG'] = OrderedDict() - mutations[sample]['CT'] = OrderedDict() - mutations[sample]['GC'] = OrderedDict() - mutations[sample]['TA'] = OrderedDict() - mutations[sample]['TC'] = OrderedDict() - mutations[sample]['TG'] = OrderedDict() - mutations[sample]['TT'] = OrderedDict() + vals=set(list(data.index))-set(dinucs) + vals=sorted(list(vals)) + for ech in vals: + ech_mod = ech.split('>')[0]+'>'+revcompl(ech.split('>')[1]) + data.rename(index={ech:ech_mod}, inplace=True) + + data = data.sort_index() + ctx = data.index + xlabels=[dn.split('>')[1] for dn in ctx] + colors = [[3/256,189/256,239/256], [3/256,102/256,204/256],[162/256,207/256,99/256], + [1/256,102/256,1/256], [255/256,153/256,153/256], [228/256,41/256,38/256], + [255/256,178/256,102/256], [255/256,128/256,1/256], [204/256,153/256,255/256], + [76/256,1/256,153/256]] + mainlist=[dn.split('>')[0] for dn in ctx] + le = LabelEncoder() + colors_idxs = le.fit_transform(mainlist) + colors_flat_list = [colors[i] for i in colors_idxs] + sample_count = 0 - for lines in f: - if pcawg: - line = lines.strip().split(",") - line = [x.replace('"','') for x in line] - mut = line[0] + ">" + line[1] - nuc = line[1] - mut_type = line[0] - if mut not in dinucs: - nuc = revcompl(nuc) - mut_type = revcompl(mut_type) - sample_index = 2 - else: - line = lines.strip().split() - mut = line[0] - nuc = line[0][3:] - mut_type = line[0][0:2] - if mut not in dinucs: - nuc = revcompl(nuc) - mut_type = revcompl(mut_type) - sample_index = 1 - - for sample in samples: - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') + buf= io.BytesIO() + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/DBS78.pkl','rb')) + pickle.dump(fig_orig, buf) + figs={} - # mutCount = int(line[sample_index]) - mutations[sample][mut_type][nuc] = mutCount - sample_index += 1 - sample_count = 0 - for sample in mutations.keys(): - total_count = sum(sum(nuc.values()) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 4 - plot1 = plt.figure(figsize=(43.93,9.92)) - plt.rc('axes', edgecolor='grey') - panel1 = plt.axes([0.04, 0.09, 0.95, 0.77]) - xlabels = [] + for sample in data.columns: + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + total_count = np.sum(data[sample].values)#sum(sum(nuc.values()) for nuc in mutations[sample].values()) x = 0.4 - ymax = 0 - colors = [[3/256,189/256,239/256], [3/256,102/256,204/256],[162/256,207/256,99/256], - [1/256,102/256,1/256], [255/256,153/256,153/256], [228/256,41/256,38/256], - [255/256,178/256,102/256], [255/256,128/256,1/256], [204/256,153/256,255/256], - [76/256,1/256,153/256]] - i = 0 - for key in mutations[sample]: - muts = mutations[sample][key].keys() - muts = sorted(muts) - for seq in muts: - xlabels.append(seq) - if percentage: - if total_count > 0: - plt.bar(x, mutations[sample][key][seq]/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq]/total_count*100 > ymax: - ymax = mutations[sample][key][seq]/total_count*100 - else: - plt.bar(x, mutations[sample][key][seq],width=0.4,color=colors[i],align='center', zorder=1000) - if mutations[sample][key][seq] > ymax: - ymax = mutations[sample][key][seq] - x += 1 - i += 1 + muts = data[sample].values + if percentage: + if total_count > 0: + plt.bar(np.asarray(range(len(ctx)))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + + plt.bar(np.asarray(range(len(ctx)))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) + # for i in range(len(xlabels)): + # print(xlabels[i],muts[i]) x = .043 y3 = .87 y = int(ymax*1.25) y2 = y+2 i = 0 - panel1.add_patch(plt.Rectangle((.043,y3), .101, .05, facecolor=colors[0], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.151,y3), .067, .05, facecolor=colors[1], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.225,y3), .102, .05, facecolor=colors[2], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.334,y3), .067, .05, facecolor=colors[3], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.408,y3), .102, .05, facecolor=colors[4], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.517,y3), .067, .05, facecolor=colors[5], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.591,y3), .067, .05, facecolor=colors[6], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.665,y3), .102, .05, facecolor=colors[7], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.774,y3), .102, .05, facecolor=colors[8], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((.883,y3), .102, .05, facecolor=colors[9], clip_on=False, transform=plt.gcf().transFigure)) - - yText = y3 + .06 - plt.text(.07, yText, 'AC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.163, yText, 'AT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.255, yText, 'CC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.345, yText, 'CG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.435, yText, 'CT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.527, yText, 'GC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.6, yText, 'TA>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.69, yText, 'TC>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.8, yText, 'TG>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) - plt.text(.915, yText, 'TT>NN', fontsize=40, fontweight='bold', fontname='Arial', transform=plt.gcf().transFigure) if y <= 4: y += 4 @@ -5080,11 +5052,11 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] if sig_probs: @@ -5138,33 +5110,8 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') - - - - - if not percentage: - ylabels =getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp - + ylabels =spplt.getylabels(ylabels) labs = np.arange(0.44,78.44,1) panel1.set_xlim([0, 78]) @@ -5185,19 +5132,23 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust plt.ylabel("Number of Double Base Substitutions", fontsize=35, fontname="Times New Roman", weight = 'bold') panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=True,\ - left=True, labelleft=True,\ - right=True, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='lightgray', width=2) + bottom=False, labelbottom=True,\ + left=True, labelleft=True,\ + right=True, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='lightgray', width=2) [i.set_color("black") for i in plt.gca().get_yticklabels()] [i.set_color("grey") for i in plt.gca().get_xticklabels()] - pp.savefig(plot1) - plt.close() - sample_count += 1 + # pp.savefig(plot1) + # plt.close() + # sample_count += 1 + pp = PdfPages(output_path + 'DBS_78_plots_' + project + '.pdf') + for fig in figs: + figs[fig].savefig(pp, format='pdf') pp.close() + except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'DBS_78_plots_' + project + '.pdf') @@ -5366,26 +5317,6 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust if not percentage: ylabels= getylabels(ylabels) - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp - labs = np.arange(0.55,36.44,1) panel1.set_xlim([0, 36]) @@ -5426,18 +5357,4 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust os.remove(output_path + 'DBS_186_plots_' + project + '.pdf') else: - print("The provided plot_type: ", plot_type, " is not supported by this plotting function") - - -# def main(): -# # # #plotSBS("/Users/ebergstr/Desktop/AID/output/SBS/AID.SBS384.all", "/Users/ebergstr/Desktop/", "AID", '384', False, custom_text_upper=['Similarity to PCAWG: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7'], custom_text_bottom=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9']) -# plotID("/Users/ebergstr/Desktop/BRCA/output/INDEL/BRCA.INDEL83.all", "/Users/ebergstr/Desktop/", "BRCA", '83', True, custom_text_upper=['Similarity to PCAWG: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7'], custom_text_middle=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9'], custom_text_bottom=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9']) -# # # plotDBS("/Users/ebergstr/Desktop/Mel/output/DINUC/Mel.DBS186.all", "/Users/ebergstr/Desktop/", "Mel", '186', False, custom_text_upper=['Similarity to PCAWG: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7'], custom_text_middle=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9'], custom_text_bottom=['Stability: 0.98', 'Similarity to PCAWG: 0.9', 'Similarity to PCAWG: 0.7', 'Similarity to PCAWG: 0.9']) - -# # # # #plotSBS("/Users/ebergstr/Desktop/BRCA/output/SBS/BRCA.SBS1536.all", "/Users/ebergstr/Desktop/", "BRCA", '1536', False, custom_text_upper=['Similarity to PCAWG: 0.98'], custom_text_middle= ['Similarity to PCAWG: 0.98'], custom_text_bottom=['Stability: 0.98']) -# # # #plotSBS("/Users/ebergstr/Desktop/BRCA/output/SBS/BRCA.SBS1536.all", "/Users/ebergstr/Desktop/", "BRCA", '1536', False, custom_text_upper=['Similarity to PCAWG: 0.98'], custom_text_middle= ['Similarity to PCAWG: 0.98']) - -# # # # plotDBS("/Users/ebergstr/Downloads/Biliary-AdenoCA.dinucs.csv", "/Users/ebergstr/Desktop/", "test", '78', False) - -# if __name__ == '__main__': -# main() + print("The provided plot_type: ", plot_type, " is not supported by this plotting function") \ No newline at end of file From 2e12d6d9392ac358f20ca14a1ab30f514f196ab0 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Wed, 12 Oct 2022 10:28:07 -0700 Subject: [PATCH 20/21] Update on ID83 plots --- build/lib/sigProfilerPlotting/idplt.py | 355 ++++++++++ .../sigProfilerPlotting.py | 661 ++++++------------ plot_example.py | 2 +- setup.py | 1 + sigProfilerPlotting/sigProfilerPlotting.py | 661 ++++++------------ 5 files changed, 753 insertions(+), 927 deletions(-) create mode 100644 build/lib/sigProfilerPlotting/idplt.py diff --git a/build/lib/sigProfilerPlotting/idplt.py b/build/lib/sigProfilerPlotting/idplt.py new file mode 100644 index 0000000..ad89e05 --- /dev/null +++ b/build/lib/sigProfilerPlotting/idplt.py @@ -0,0 +1,355 @@ +# #!/usr/bin/env python3 + +# #Author: Erik Bergstrom + +# #Contact: ebergstr@eng.ucsd.edu + +# from bdb import set_trace +# from copy import deepcopy +# import matplotlib +# matplotlib.use('Agg') +# import matplotlib.pyplot as plt +# import matplotlib.font_manager +# from matplotlib.backends.backend_pdf import PdfPages +# import matplotlib.patches as mplpatches +# import matplotlib.ticker as ticker +# from matplotlib.ticker import LinearLocator +# import matplotlib.lines as lines +# import matplotlib.transforms as transforms +# import re +# import os +# import sys +# import argparse +# from collections import OrderedDict +# import pandas as pd +# import numpy as np +# import io +# import string +# import warnings +# import pickle +# import sigProfilerPlotting as spplt +# import pdb +# import itertools,time +# import sklearn +# from sklearn.preprocessing import LabelEncoder + + +# def getIDtemp(output_path,project): +# # pp = PdfPages(output_path + 'ID83_template_' + project + '.pdf') +# plt.rcParams['axes.linewidth'] = 2 +# plot1 = plt.figure(figsize=(43.93,12)) +# plt.rc('axes', edgecolor='black') +# panel1 = plt.axes([0.045, 0.17, 0.92, 0.65]) +# xlabels = [] + +# x = 0.4 +# ymax = 0 +# colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256], +# [253/256,202/256,181/256], [252/256,138/256,106/256], [241/256,68/256,50/256], [188/256,25/256,26/256], +# [208/256,225/256,242/256], [148/256,196/256,223/256], [74/256,152/256,201/256], [23/256,100/256,171/256], +# [226/256,226/256,239/256], [182/256,182/256,216/256], [134/256,131/256,189/256], [98/256,64/256,155/256]] + +# x = .0475 +# y_top = .827 +# y_bottom = .114 +# y = int(ymax*1.25) +# y2 = y+2 +# for i in range(0, 12, 1): +# panel1.add_patch(plt.Rectangle((x,y_top), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) +# panel1.add_patch(plt.Rectangle((x,y_bottom), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) +# x += .0665 + +# panel1.add_patch(plt.Rectangle((x-.001,y_top), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) +# panel1.add_patch(plt.Rectangle((x-.001,y_bottom), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) +# x +=.011 +# panel1.add_patch(plt.Rectangle((x,y_top), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) +# panel1.add_patch(plt.Rectangle((x,y_bottom), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) +# x += .022 +# panel1.add_patch(plt.Rectangle((x,y_top), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) +# panel1.add_patch(plt.Rectangle((x,y_bottom), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) +# x += .0335 +# panel1.add_patch(plt.Rectangle((x,y_top), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) +# panel1.add_patch(plt.Rectangle((x,y_bottom), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) + + + + +# yText = y_top + .01 +# plt.text(.072, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) +# plt.text(.1385, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) +# plt.text(.205, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) +# plt.text(.2715, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) +# plt.text(.338, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.4045, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.471, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.5375, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) +# plt.text(.604, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.6705, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.737, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.8035, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) +# plt.text(.844, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.861, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.888, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.93, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) + +# yText_labels_top = yText + .075 +# yText_labels_bottom = y_bottom - .03 +# yText_labels_bottom_sec = yText_labels_bottom - .045 + +# plt.text(.08, yText_labels_top, '1bp Deletion', fontsize=40, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) +# plt.text(.21, yText_labels_top, '1bp Insertion', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.375, yText_labels_top, '>1bp Deletion at Repeats\n (Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.64, yText_labels_top, '>1bp Insertion at Repeats\n (Insertion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.85, yText_labels_top, ' Microhomology\n(Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + +# plt.text(.058, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) +# plt.text(.19, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.39, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.65, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# plt.text(.85, yText_labels_bottom_sec, 'Microhomology Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + +# x = .0477 +# for i in range (0, 8, 1): +# if i != 2 and i != 3: +# plt.text(x, yText_labels_bottom, '1 2 3 4 5 6+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# else: +# plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + +# x += .0665 + +# for i in range (0, 4, 1): +# plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# x += .0665 + +# plt.text(x, yText_labels_bottom, '1', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# x += .011 +# plt.text(x, yText_labels_bottom, '1 2', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# x += .022 +# plt.text(x, yText_labels_bottom, '1 2 3', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) +# x += .0335 +# plt.text(x, yText_labels_bottom, '1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + +# labs = np.arange(0.375,83.375,1) + +# panel1.set_xlim([0, 83]) +# panel1.set_ylim([0, y]) +# panel1.set_xticks(labs) + + + +# # panel1.set_yticklabels(ylabels, fontsize=30) +# plt.gca().yaxis.grid(True) +# plt.gca().grid(which='major', axis='y', color=[0.6,0.6,0.6], zorder=1) +# panel1.set_xlabel('') +# panel1.set_ylabel('') + +# panel1.tick_params(axis='both',which='both',\ +# bottom=False, labelbottom=False,\ +# left=False, labelleft=True,\ +# right=False, labelright=False,\ +# top=False, labeltop=False,\ +# direction='in', length=25, colors='gray', width=2) + +# [i.set_color("black") for i in plt.gca().get_yticklabels()] +# package_path = spplt.__path__[0] +# path_1 =os.path.join(package_path,'templates/') +# filename= os.path.join(path_1,'ID'+'.pkl') +# pickle.dump(plot1, open(filename, 'wb')) +# # pp.savefig(plot1) +# # pp.close() + + + +# def plotIDmod(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None,savefig_format = "pdf"): +# # if 'roman' in matplotlib.font_manager.weight_dict: +# # del matplotlib.font_manager.weight_dict['roman'] +# # matplotlib.font_manager._rebuild() +# # import pdb;pdb.set_trace() +# plot_custom_text = False +# sig_probs = False +# pcawg = False +# if plot_type == '94' or plot_type == 'ID94' or plot_type == '94ID' or plot_type == '83': + +# # getIDtemp(output_path,project) +# # import pdb;pdb.set_trace() +# if not isinstance(matrix_path, pd.DataFrame): +# data=pd.read_csv(matrix_path,sep='\t',index_col=0) +# data=data.dropna(axis=1, how='all') + +# if data.isnull().values.any(): +# raise ValueError("Input data contains Nans.") + + +# try: + + +# sample_count = 0 +# buf= io.BytesIO() +# fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/ID.pkl','rb')) +# pickle.dump(fig_orig, buf) + +# figs={} + +# colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256], +# [253/256,202/256,181/256], [252/256,138/256,106/256], [241/256,68/256,50/256], [188/256,25/256,26/256], +# [208/256,225/256,242/256], [148/256,196/256,223/256], [74/256,152/256,201/256], [23/256,100/256,171/256], +# [226/256,226/256,239/256], [182/256,182/256,216/256], [134/256,131/256,189/256], [98/256,64/256,155/256]] +# ctx = data.index +# xlabels= [i.split(":")[0]+i.split(":")[1]+i.split(":")[2] for i in ctx.to_list()] +# xlables_set= ['1DelC', '1DelT', '1InsC', '1InsT', '2DelR', '3DelR', '4DelR', '5DelR', '2InsR','3InsR','4InsR','5InsR', '2DelM', '3DelM','4DelM','5DelM'] +# colors_idx = deepcopy(xlabels) +# for ii in range(0,len(xlables_set)): +# colors_idx=[ii if x==xlables_set[ii] else x for x in colors_idx] + +# # pdb.set_trace() +# colors_flat_list = [colors[i] for i in colors_idx] + +# for sample in data.columns: #mutations.keys(): + +# buf.seek(0) +# figs[sample]=pickle.load(buf) +# panel1= figs[sample].axes[0] +# muts= data[sample].values +# total_count = np.sum(muts) +# x = 0.4 + +# if percentage: +# if total_count > 0: +# plt.bar(np.arange(len(ctx))+x, muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) +# ymax = np.max(muts/total_count*100) +# else: +# plt.bar(np.arange(len(ctx))+x, muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) +# ymax = np.max(muts) + +# x = .0475 +# y_top = .827 +# y_bottom = .114 +# y = int(ymax*1.25) +# y2 = y+2 + +# if y <= 4: +# y += 4 + +# while y%4 != 0: +# y += 1 +# ytick_offest = int(y/4) + +# if percentage: +# ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] +# ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", +# str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] +# else: +# ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] +# ylabels= [0, ytick_offest, ytick_offest*2, +# ytick_offest*3, ytick_offest*4] + +# labs = np.arange(0.375,83.375,1) + +# if not percentage: +# ylabels=spplt.getylabels(ylabels) + +# panel1.set_xlim([0, 83]) +# panel1.set_ylim([0, y]) +# panel1.set_xticks(labs) +# panel1.set_yticks(ylabs) +# # import pdb;pdb.set_trace() +# if sig_probs: +# plt.text(0.0475, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) +# else: +# plt.text(0.0475, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " indels", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) + +# custom_text_upper_plot = '' +# try: +# custom_text_upper[sample_count] +# except: +# custom_text_upper = False +# try: +# custom_text_middle[sample_count] +# except: +# custom_text_middle = False +# try: +# custom_text_bottom[sample_count] +# except: +# custom_text_bottom = False + +# if custom_text_upper: +# plot_custom_text = True +# if len(custom_text_upper[sample_count]) > 40: +# print("To add a custom text, please limit the string to <40 characters including spaces.") +# plot_custom_text = False +# if custom_text_middle: +# if len(custom_text_middle[sample_count]) > 40: +# print("To add a custom text, please limit the string to <40 characters including spaces.") +# plot_custom_text = False + +# if plot_custom_text: +# x_pos_custom = 0.95 +# if custom_text_upper and custom_text_middle: +# custom_text_upper_plot = custom_text_upper[sample_count] + "\n" + custom_text_middle[sample_count] +# if custom_text_bottom: +# custom_text_upper_plot += "\n" + custom_text_bottom[sample_count] + +# if custom_text_upper and not custom_text_middle: +# custom_text_upper_plot = custom_text_upper[sample_count] +# panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + +# elif custom_text_upper and custom_text_middle: +# if not custom_text_bottom: +# panel1.text(x_pos_custom, 0.72, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') +# else: +# panel1.text(x_pos_custom, 0.68, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + +# elif not custom_text_upper and custom_text_middle: +# custom_text_upper_plot = custom_text_middle[sample_count] +# panel1.text(x_pos_custom, 0.78, custom_text_upper_plot, fontsize=35, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure, ha='right') + + + + +# panel1.set_yticklabels(ylabels, fontsize=30) +# plt.gca().yaxis.grid(True) +# plt.gca().grid(which='major', axis='y', color=[0.6,0.6,0.6], zorder=1) +# panel1.set_xlabel('') +# panel1.set_ylabel('') + +# if percentage: +# plt.ylabel("Percentage of Indels", fontsize=35, fontname="Times New Roman", weight = 'bold') +# else: +# plt.ylabel("Number of Indels", fontsize=35, fontname="Times New Roman", weight = 'bold') + +# panel1.tick_params(axis='both',which='both',\ +# bottom=False, labelbottom=False,\ +# left=False, labelleft=True,\ +# right=False, labelright=False,\ +# top=False, labeltop=False,\ +# direction='in', length=25, colors='gray', width=2) + +# [i.set_color("black") for i in plt.gca().get_yticklabels()] +# # import pdb;pdb.set_trace() +# # pp.savefig(plot1) +# # plt.close() +# sample_count += 1 +# # pp.close() +# if savefig_format == "pdf": +# pp = PdfPages(output_path + 'ID_83_plots_' + project + '.pdf') # PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') + + +# if savefig_format == "pdf": +# for fig in figs: +# figs[fig].savefig(pp, format='pdf') +# pp.close() + +# if savefig_format == "png": +# for fig in figs: +# figs[fig].savefig(output_path + 'SBS_96_plots_'+fig+'.png',dpi=100) +# if savefig_format == "buffer_stream": +# buff_list={} +# for fig in figs: +# buffer2=io.BytesIO() +# figs[fig].savefig(buffer2,format='png') +# buff_list[fig]=buffer2 +# return buff_list +# except: +# print("There may be an issue with the formatting of your matrix file.") +# os.remove(output_path + 'ID_83_plots_' + project + '.pdf') diff --git a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py index 9cc62a0..a1124e8 100644 --- a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py +++ b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py @@ -29,8 +29,9 @@ import sigProfilerPlotting as spplt import pdb import itertools,time -import sklearn -from sklearn.preprocessing import LabelEncoder +# import sklearn +# from sklearn.preprocessing import LabelEncoder +import copy warnings.filterwarnings("ignore") @@ -124,15 +125,6 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): count = 0 m += 1 - # if sig_probs: - # plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - # else: - # plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - - - - - # panel1.set_yticklabels(ylabels, fontsize=font_label_size) plt.gca().yaxis.grid(True) @@ -346,6 +338,128 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): [i.set_color("black") for i in plt.gca().get_yticklabels()] [i.set_color("grey") for i in plt.gca().get_xticklabels()] pickle.dump(plot1, open(path, 'wb')) + + elif context =='ID83': + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,12)) + plt.rc('axes', edgecolor='black') + panel1 = plt.axes([0.045, 0.17, 0.92, 0.65]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256], + [253/256,202/256,181/256], [252/256,138/256,106/256], [241/256,68/256,50/256], [188/256,25/256,26/256], + [208/256,225/256,242/256], [148/256,196/256,223/256], [74/256,152/256,201/256], [23/256,100/256,171/256], + [226/256,226/256,239/256], [182/256,182/256,216/256], [134/256,131/256,189/256], [98/256,64/256,155/256]] + + x = .0475 + y_top = .827 + y_bottom = .114 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 12, 1): + panel1.add_patch(plt.Rectangle((x,y_top), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x,y_bottom), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .0665 + + panel1.add_patch(plt.Rectangle((x-.001,y_top), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x-.001,y_bottom), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) + x +=.011 + panel1.add_patch(plt.Rectangle((x,y_top), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x,y_bottom), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) + x += .022 + panel1.add_patch(plt.Rectangle((x,y_top), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x,y_bottom), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) + x += .0335 + panel1.add_patch(plt.Rectangle((x,y_top), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x,y_bottom), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) + + + + + yText = y_top + .01 + plt.text(.072, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) + plt.text(.1385, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) + plt.text(.205, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) + plt.text(.2715, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) + plt.text(.338, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.4045, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.471, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.5375, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) + plt.text(.604, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.6705, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.737, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.8035, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) + plt.text(.844, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.861, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.888, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.93, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) + + yText_labels_top = yText + .075 + yText_labels_bottom = y_bottom - .03 + yText_labels_bottom_sec = yText_labels_bottom - .045 + + plt.text(.08, yText_labels_top, '1bp Deletion', fontsize=40, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) + plt.text(.21, yText_labels_top, '1bp Insertion', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.375, yText_labels_top, '>1bp Deletion at Repeats\n (Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.64, yText_labels_top, '>1bp Insertion at Repeats\n (Insertion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.85, yText_labels_top, ' Microhomology\n(Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + plt.text(.058, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) + plt.text(.19, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.39, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.65, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.85, yText_labels_bottom_sec, 'Microhomology Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + x = .0477 + for i in range (0, 8, 1): + if i != 2 and i != 3: + plt.text(x, yText_labels_bottom, '1 2 3 4 5 6+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + else: + plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + x += .0665 + + for i in range (0, 4, 1): + plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + x += .0665 + + plt.text(x, yText_labels_bottom, '1', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + x += .011 + plt.text(x, yText_labels_bottom, '1 2', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + x += .022 + plt.text(x, yText_labels_bottom, '1 2 3', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + x += .0335 + plt.text(x, yText_labels_bottom, '1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + + labs = np.arange(0.375,83.375,1) + + panel1.set_xlim([0, 83]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + + + + # panel1.set_yticklabels(ylabels, fontsize=30) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.6,0.6,0.6], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=False, labelleft=True,\ + right=False, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='gray', width=2) + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + package_path = spplt.__path__[0] + path_1 =os.path.join(package_path,'templates/') + filename= os.path.join(path_1,'ID'+'.pkl') + pickle.dump(plot1, open(filename, 'wb')) @@ -856,7 +970,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust muts = data[sample].values if percentage: if total_count > 0: - plt.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + plt.bar(np.arange(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) ymax = np.max(muts/total_count*100) else: plt.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) @@ -3758,7 +3872,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust print("The provided plot_type: ", plot_type, " is not supported by this plotting function") -def plotID(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None): +def plotID(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format = "pdf"): # if 'roman' in matplotlib.font_manager.weight_dict: # del matplotlib.font_manager.weight_dict['roman'] # matplotlib.font_manager._rebuild() @@ -3766,224 +3880,58 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo sig_probs = False pcawg = False if plot_type == '94' or plot_type == 'ID94' or plot_type == '94ID' or plot_type == '83': - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - if first_line[0][1] == 'D' or first_line[0][0] == 'D': - pcawg = True - mutation_type = first_line[0] - mutation_type_list = mutation_type.split(":") - if len(mutation_type_list) != 4 and first_line[0][1] != 'D' and first_line[0][0] != 'D': - sys.exit("The matrix does not match the correct ID96 format. Please check you formatting and rerun this plotting function.") - pp = PdfPages(output_path + 'ID_83_plots_' + project + '.pdf') - indel_types = ['1:Del:C:0', '1:Del:C:1', '1:Del:C:2', '1:Del:C:3', '1:Del:C:4', '1:Del:C:5', - '1:Del:T:0', '1:Del:T:1', '1:Del:T:2', '1:Del:T:3', '1:Del:T:4', '1:Del:T:5', - '1:Ins:C:0', '1:Ins:C:1', '1:Ins:C:2', '1:Ins:C:3', '1:Ins:C:4', '1:Ins:C:5', - '1:Ins:T:0', '1:Ins:T:1', '1:Ins:T:2', '1:Ins:T:3', '1:Ins:T:4', '1:Ins:T:5', - # >1bp INDELS - '2:Del:R:0', '2:Del:R:1', '2:Del:R:2', '2:Del:R:3', '2:Del:R:4', '2:Del:R:5', - '3:Del:R:0', '3:Del:R:1', '3:Del:R:2', '3:Del:R:3', '3:Del:R:4', '3:Del:R:5', - '4:Del:R:0', '4:Del:R:1', '4:Del:R:2', '4:Del:R:3', '4:Del:R:4', '4:Del:R:5', - '5:Del:R:0', '5:Del:R:1', '5:Del:R:2', '5:Del:R:3', '5:Del:R:4', '5:Del:R:5', - '2:Ins:R:0', '2:Ins:R:1', '2:Ins:R:2', '2:Ins:R:3', '2:Ins:R:4', '2:Ins:R:5', - '3:Ins:R:0', '3:Ins:R:1', '3:Ins:R:2', '3:Ins:R:3', '3:Ins:R:4', '3:Ins:R:5', - '4:Ins:R:0', '4:Ins:R:1', '4:Ins:R:2', '4:Ins:R:3', '4:Ins:R:4', '4:Ins:R:5', - '5:Ins:R:0', '5:Ins:R:1', '5:Ins:R:2', '5:Ins:R:3', '5:Ins:R:4', '5:Ins:R:5', - #MicroHomology INDELS - '2:Del:M:1', '3:Del:M:1', '3:Del:M:2', '4:Del:M:1', '4:Del:M:2', '4:Del:M:3', - '5:Del:M:1', '5:Del:M:2', '5:Del:M:3', '5:Del:M:4', '5:Del:M:5'] - mutations = OrderedDict() + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[4:] - samples = [x.replace('"','') for x in samples] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['1DelC'] = [0,0,0,0,0,0] - mutations[sample]['1DelT'] = [0,0,0,0,0,0] - mutations[sample]['1InsC'] = [0,0,0,0,0,0] - mutations[sample]['1InsT'] = [0,0,0,0,0,0] - mutations[sample]['2DelR'] = [0,0,0,0,0,0] - mutations[sample]['3DelR'] = [0,0,0,0,0,0] - mutations[sample]['4DelR'] = [0,0,0,0,0,0] - mutations[sample]['5DelR'] = [0,0,0,0,0,0] - mutations[sample]['2InsR'] = [0,0,0,0,0,0] - mutations[sample]['3InsR'] = [0,0,0,0,0,0] - mutations[sample]['3InsR'] = [0,0,0,0,0,0] - mutations[sample]['4InsR'] = [0,0,0,0,0,0] - mutations[sample]['5InsR'] = [0,0,0,0,0,0] - mutations[sample]['2DelM'] = [0] - mutations[sample]['3DelM'] = [0,0] - mutations[sample]['4DelM'] = [0,0,0] - mutations[sample]['5DelM'] = [0,0,0,0,0] - - for lines in f: - if pcawg: - line = lines.strip().split(",") - line = [x.replace('"','') for x in line] - if line[1] == 'repeats': - mut_type = line[2][0] + line[0][0] + line[0][1].lower() + line[0][2].lower() + "R" - else: - mut_type = line[2][0] + line[0][0] + line[0][1].lower() + line[0][2].lower() + line[1][0] - try: - repeat_size = int(line[3]) - except: - repeat_size = int(line[3][0]) - if line[1] == 'MH': - repeat_size -= 1 - sample_index = 4 - else: - line = lines.strip().split() - if line[0] not in indel_types: - continue - categories = line[0].split(":") - mut_type = categories[0] + categories[1] + categories[2] - repeat_size = int(categories[3]) - if categories[2] == 'M': - repeat_size -= 1 - sample_index = 1 - - for sample in samples: - if mut_type in mutations[sample].keys(): - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') + sample_count = 0 + buf= io.BytesIO() + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/ID.pkl','rb')) + pickle.dump(fig_orig, buf) - # mutCount = int(line[sample_index]) - mutations[sample][mut_type][repeat_size] = mutCount - else: - continue - sample_index += 1 + figs={} - sample_count = 0 - for sample in mutations.keys(): - total_count = sum(sum(nuc) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,12)) - plt.rc('axes', edgecolor='black') - panel1 = plt.axes([0.045, 0.17, 0.92, 0.65]) - xlabels = [] + colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256], + [253/256,202/256,181/256], [252/256,138/256,106/256], [241/256,68/256,50/256], [188/256,25/256,26/256], + [208/256,225/256,242/256], [148/256,196/256,223/256], [74/256,152/256,201/256], [23/256,100/256,171/256], + [226/256,226/256,239/256], [182/256,182/256,216/256], [134/256,131/256,189/256], [98/256,64/256,155/256]] + ctx = data.index + xlabels= [i.split(":")[0]+i.split(":")[1]+i.split(":")[2] for i in ctx.to_list()] + xlables_set= ['1DelC', '1DelT', '1InsC', '1InsT', '2DelR', '3DelR', '4DelR', '5DelR', '2InsR','3InsR','4InsR','5InsR', '2DelM', '3DelM','4DelM','5DelM'] + colors_idx = copy.deepcopy(xlabels) + for ii in range(0,len(xlables_set)): + colors_idx=[ii if x==xlables_set[ii] else x for x in colors_idx] + + # pdb.set_trace() + colors_flat_list = [colors[i] for i in colors_idx] + for sample in data.columns: #mutations.keys(): + + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + muts= data[sample].values + total_count = np.sum(muts) x = 0.4 - ymax = 0 - colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256], - [253/256,202/256,181/256], [252/256,138/256,106/256], [241/256,68/256,50/256], [188/256,25/256,26/256], - [208/256,225/256,242/256], [148/256,196/256,223/256], [74/256,152/256,201/256], [23/256,100/256,171/256], - [226/256,226/256,239/256], [182/256,182/256,216/256], [134/256,131/256,189/256], [98/256,64/256,155/256]] - i = 0 - for key in mutations[sample]: - l = 1 - for seq in mutations[sample][key]: - xlabels.append(l) - if percentage: - if total_count > 0: - plt.bar(x, seq/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if seq/total_count*100 > ymax: - ymax = seq/total_count*100 - else: - plt.bar(x, seq,width=0.4,color=colors[i],align='center', zorder=1000) - if seq > ymax: - ymax = seq - x += 1 - l += 1 - i += 1 + if percentage: + if total_count > 0: + plt.bar(np.arange(len(ctx))+x, muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + plt.bar(np.arange(len(ctx))+x, muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) x = .0475 y_top = .827 y_bottom = .114 y = int(ymax*1.25) y2 = y+2 - for i in range(0, 12, 1): - panel1.add_patch(plt.Rectangle((x,y_top), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x,y_bottom), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .0665 - - panel1.add_patch(plt.Rectangle((x-.001,y_top), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x-.001,y_bottom), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) - x +=.011 - panel1.add_patch(plt.Rectangle((x,y_top), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x,y_bottom), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) - x += .022 - panel1.add_patch(plt.Rectangle((x,y_top), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x,y_bottom), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) - x += .0335 - panel1.add_patch(plt.Rectangle((x,y_top), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x,y_bottom), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) - - - - - yText = y_top + .01 - plt.text(.072, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) - plt.text(.1385, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) - plt.text(.205, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) - plt.text(.2715, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) - plt.text(.338, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.4045, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.471, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.5375, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) - plt.text(.604, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.6705, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.737, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.8035, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) - plt.text(.844, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.861, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.888, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.93, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) - - yText_labels_top = yText + .075 - yText_labels_bottom = y_bottom - .03 - yText_labels_bottom_sec = yText_labels_bottom - .045 - - plt.text(.08, yText_labels_top, '1bp Deletion', fontsize=40, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) - plt.text(.21, yText_labels_top, '1bp Insertion', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.375, yText_labels_top, '>1bp Deletion at Repeats\n (Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.64, yText_labels_top, '>1bp Insertion at Repeats\n (Insertion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.85, yText_labels_top, ' Microhomology\n(Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - - plt.text(.058, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) - plt.text(.19, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.39, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.65, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.85, yText_labels_bottom_sec, 'Microhomology Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - - x = .0477 - for i in range (0, 8, 1): - if i != 2 and i != 3: - plt.text(x, yText_labels_bottom, '1 2 3 4 5 6+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - else: - plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - - x += .0665 - - for i in range (0, 4, 1): - plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - x += .0665 - - plt.text(x, yText_labels_bottom, '1', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - x += .011 - plt.text(x, yText_labels_bottom, '1 2', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - x += .022 - plt.text(x, yText_labels_bottom, '1 2 3', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - x += .0335 - plt.text(x, yText_labels_bottom, '1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - if y <= 4: y += 4 @@ -3995,22 +3943,22 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] labs = np.arange(0.375,83.375,1) if not percentage: - ylabels=getylabels(ylabels) + ylabels=spplt.getylabels(ylabels) panel1.set_xlim([0, 83]) panel1.set_ylim([0, y]) panel1.set_xticks(labs) panel1.set_yticks(ylabs) - + # import pdb;pdb.set_trace() if sig_probs: plt.text(0.0475, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) else: @@ -4076,255 +4024,41 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo plt.ylabel("Number of Indels", fontsize=35, fontname="Times New Roman", weight = 'bold') panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=False, labelleft=True,\ - right=False, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='gray', width=2) + bottom=False, labelbottom=False,\ + left=False, labelleft=True,\ + right=False, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='gray', width=2) [i.set_color("black") for i in plt.gca().get_yticklabels()] - - pp.savefig(plot1) - plt.close() + # import pdb;pdb.set_trace() + # pp.savefig(plot1) + # plt.close() sample_count += 1 - pp.close() + # pp.close() + if savefig_format == "pdf": + pp = PdfPages(output_path + 'ID_83_plots_' + project + '.pdf') # PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') + + + if savefig_format == "pdf": + for fig in figs: + figs[fig].savefig(pp, format='pdf') + pp.close() + + if savefig_format == "png": + for fig in figs: + figs[fig].savefig(output_path + 'SBS_96_plots_'+fig+'.png',dpi=100) + if savefig_format == "buffer_stream": + buff_list={} + for fig in figs: + buffer2=io.BytesIO() + figs[fig].savefig(buffer2,format='png') + buff_list[fig]=buffer2 + return buff_list except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'ID_83_plots_' + project + '.pdf') - # =======================================OLD INDEL-TSB PLOT================================================================================== - # elif plot_type == '96' or plot_type == 'ID96' or plot_type == '96ID' or plot_type == 'IDSB': - # with open(matrix_path) as f: - # next(f) - # first_line = f.readline() - # first_line = first_line.strip().split("\t") - # mutation_type = first_line[0] - # mutation_type_list = mutation_type.split(":") - # if len(mutation_type_list) != 5: - # print(mutation_type_list) - # sys.exit("The matrix does not match the correct ID-96 format. Please check you formatting and rerun this plotting function.") - - # pp = PdfPages(output_path + 'ID_96_plots_' + project + '.pdf') - - # indel_types = ['1:Del:C:1', '1:Del:C:2', '1:Del:C:3', '1:Del:C:4', '1:Del:C:5', '1:Del:C:6' - # '1:Del:T:1', '1:Del:T:2', '1:Del:T:3', '1:Del:T:4', '1:Del:T:5', '1:Del:T:6' - # '1:Ins:C:0', '1:Ins:C:1', '1:Ins:C:2', '1:Ins:C:3', '1:Ins:C:4', '1:Ins:C:5', - # '1:Ins:T:0', '1:Ins:T:1', '1:Ins:T:2', '1:Ins:T:3', '1:Ins:T:4', '1:Ins:T:5'] - - # sig_probs = False - # mutations = OrderedDict() - # with open (matrix_path) as f: - # first_line = f.readline() - # samples = first_line.strip().split("\t") - # samples = samples[1:] - # for sample in samples: - # mutations[sample] = OrderedDict() - # mutations[sample]['1DelC'] = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] - # mutations[sample]['1DelT'] = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] - # mutations[sample]['1InsC'] = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] - # mutations[sample]['1InsT'] = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] - - # for lines in f: - # line = lines.strip().split() - # categories = line[0].split(":") - # if categories[1] != '1': - # break - # else: - # mut_type = categories[1] + categories[2] + categories[3] - # bias = categories[0] - # if bias != 'T' and bias != 'U': - # continue - # else: - # repeat_size = int(categories[4]) - # sample_index = 1 - # for sample in samples: - # if mut_type in mutations[sample]: - # if percentage: - # mutCount = float(line[sample_index]) - # if mutCount < 1 and mutCount > 0: - # sig_probs = True - # else: - # mutCount = int(line[sample_index]) - # if bias == 'T': - # mutations[sample][mut_type][repeat_size][0] = mutCount - # else: - # mutations[sample][mut_type][repeat_size][1] = mutCount - # else: - # continue - # sample_index += 1 - - # for sample in mutations: - # total_count = sum(sum(sum(tsb) for tsb in nuc) for nuc in mutations[sample].values()) - # plt.rcParams['axes.linewidth'] = 2 - # plot1 = plt.figure(figsize=(15,13)) - # plt.rc('axes', edgecolor='black') - # panel1 = plt.axes([0.12, 0.12, 0.8, 0.77]) - # xlabels = [] - - # x = 0.3 - # ymax = 0 - # colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256]] - - # i = 0 - # for key in mutations[sample]: - # l = 1 - # for seq in mutations[sample][key]: - # xlabels.append(l) - # if percentage: - # trans = plt.bar(x, seq[0]/total_count*100,width=0.2,color=[1/256,70/256,102/256],align='center', zorder=1000, label='Transcribed Strand') - # x += 0.2 - # untrans = plt.bar(x, seq[1]/total_count*100,width=0.2,color=[228/256,41/256,38/256],align='center', zorder=1000, label='Untranscribed Strand') - # x += 0.8 - # if seq[0]/total_count*100 > ymax: - # ymax = seq[0]/total_count*100 - # if seq[1]/total_count*100 > ymax: - # ymax = seq[1]/total_count*100 - # else: - # trans = plt.bar(x, seq[0],width=0.2,color=[1/256,70/256,102/256],align='center', zorder=1000, label='Transcribed Strand') - # x += 0.2 - # untrans = plt.bar(x, seq[1],width=0.2,color=[228/256,41/256,38/256],align='center', zorder=1000, label='Untranscribed Strand') - # x += 0.8 - # if seq[0] > ymax: - # ymax = seq[0] - # if seq[1] > ymax: - # ymax = seq[1] - # l += 1 - # i += 1 - - # x = .125 - # y_top = .8975 - # #y_bottom = .06525 - # y_bottom = .075 - # y = int(ymax*1.25) - # y2 = y+2 - - - - - - # for i in range(0, 4, 1): - # panel1.add_patch(plt.Rectangle((x,y_top), .185, .037, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - # panel1.add_patch(plt.Rectangle((x,y_bottom), .185, .037, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - # x += .202 - - - # yText = y_top + .005 - # plt.text(.205, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) - # plt.text(.407, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) - # plt.text(.609, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) - # plt.text(.811, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) - - # yText_labels_top = yText + .05 - # yText_labels_bottom = y_bottom - .03 - # yText_labels_bottom_sec = yText_labels_bottom -.025 - - # plt.text(.23, yText_labels_top, '1bp Deletion', fontsize=35, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) - # plt.text(.634, yText_labels_top, '1bp Insertion', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # plt.text(.18, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=30, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) - # plt.text(.58, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=30, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - - # x = .127 - # yText_labels_bottom = y_bottom - 0.025 - - # for l in range (0, 4, 1): - # if l < 2: - # for i in range(1, 6, 1): - # plt.text(x, yText_labels_bottom, str(i), fontsize=25, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # x += 0.034 - # x -= 0.008 - # plt.text(x, yText_labels_bottom, '6+', fontsize=25, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # x += 0.041 - # else: - # for i in range(0, 5, 1): - # plt.text(x, yText_labels_bottom, str(i), fontsize=25, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # x += 0.033 - # x -= 0.005 - # plt.text(x, yText_labels_bottom, '5+', fontsize=25, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # x += 0.044 - - # if y <= 4: - # y += 4 - - # while y%4 != 0: - # y += 1 - # ytick_offest = int(y/4) - - - # x_shaded = 0 - # for i in range(0, 4, 1): - # panel1.add_patch(plt.Rectangle((x_shaded,0), 6, y, facecolor=colors[i], zorder=0, alpha = 0.25, edgecolor='grey')) - # x_shaded += 6 - - # if percentage: - # ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - # ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - # str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - # else: - # ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] - # ylabels= [0, ytick_offest, ytick_offest*2, - # ytick_offest*3, ytick_offest*4] - - - # if not percentage: - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp - - # panel1.set_xlim([0, 23.8]) - # panel1.set_ylim([0, y]) - # panel1.set_yticks(ylabs) - - # if sig_probs: - # plt.text(0.13, 0.85, sample, fontsize=33, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - # else: - # plt.text(0.13, 0.85, sample + ": " + "{:,}".format(int(total_count)) + " transcribed indels", fontsize=33, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - - # panel1.set_yticklabels(ylabels, fontsize=30) - # plt.gca().yaxis.grid(True) - # plt.gca().grid(which='major', axis='y', color=[0.6,0.6,0.6], zorder=1) - # panel1.set_xlabel('') - # panel1.set_ylabel('') - # plt.legend(handles=[trans, untrans], prop={'size':20}) - - # if percentage: - # plt.ylabel("Percentage of Indels", fontsize=35, fontname="Times New Roman", weight = 'bold') - # else: - # plt.ylabel("Number of Indels", fontsize=35, fontname="Times New Roman", weight = 'bold') - - # panel1.tick_params(axis='both',which='both',\ - # bottom=False, labelbottom=False,\ - # left=False, labelleft=True,\ - # right=False, labelright=False,\ - # top=False, labeltop=False,\ - # direction='in', length=25, colors='gray', width=2) - - # [i.set_color("black") for i in plt.gca().get_yticklabels()] - - - - - - # pp.savefig(plot1) - # plt.close() - # pp.close() - # =================================================================================================================================== - elif plot_type == 'INDEL_simple' or plot_type == 'simple_INDEL' or plot_type == 'ID_simple' or plot_type == 'simple_ID' or plot_type == '28': @@ -5008,6 +4742,7 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust colors_idxs = le.fit_transform(mainlist) colors_flat_list = [colors[i] for i in colors_idxs] sample_count = 0 + buf= io.BytesIO() diff --git a/plot_example.py b/plot_example.py index fb5fe8e..c8b0354 100644 --- a/plot_example.py +++ b/plot_example.py @@ -16,4 +16,4 @@ sigPlt.plotSV(matrix_path + "breast_cancer_samples_example.RS32.all", output_path, "BRCA_example", "pdf", percentage=False, aggregate=False) #plotting of SV counts #sigPlt.plotDBS(matrix_path + "breast_cancer_samples_example.DBS78.all", output_path, "BRCA_example", "78") -#sigPlt.plotID(matrix_path + "breast_cancer_samples_example.ID94.all", output_path, "BRCA_example", "94") +# sigPlt.plotID(matrix_path + "breast_cancer_samples_example.ID94.all", output_path, "BRCA_example", "94") diff --git a/setup.py b/setup.py index 3039072..b638072 100644 --- a/setup.py +++ b/setup.py @@ -66,6 +66,7 @@ def run(self): sigPlt.install_plot_templates('SBS96') sigPlt.install_plot_templates('SBS288') sigPlt.install_plot_templates('DBS78') + sigPlt.install_plot_templates('ID83') os.system("echo 'installed figure templates' ") except: os.system("echo 'Failed to install templates' ") diff --git a/sigProfilerPlotting/sigProfilerPlotting.py b/sigProfilerPlotting/sigProfilerPlotting.py index 9cc62a0..a1124e8 100644 --- a/sigProfilerPlotting/sigProfilerPlotting.py +++ b/sigProfilerPlotting/sigProfilerPlotting.py @@ -29,8 +29,9 @@ import sigProfilerPlotting as spplt import pdb import itertools,time -import sklearn -from sklearn.preprocessing import LabelEncoder +# import sklearn +# from sklearn.preprocessing import LabelEncoder +import copy warnings.filterwarnings("ignore") @@ -124,15 +125,6 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): count = 0 m += 1 - # if sig_probs: - # plt.text(0.045, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - # else: - # plt.text(0.045, 0.75, sample + ": " + "{:,}".format(int(total_count)) + " subs", fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - - - - - # panel1.set_yticklabels(ylabels, fontsize=font_label_size) plt.gca().yaxis.grid(True) @@ -346,6 +338,128 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): [i.set_color("black") for i in plt.gca().get_yticklabels()] [i.set_color("grey") for i in plt.gca().get_xticklabels()] pickle.dump(plot1, open(path, 'wb')) + + elif context =='ID83': + plt.rcParams['axes.linewidth'] = 2 + plot1 = plt.figure(figsize=(43.93,12)) + plt.rc('axes', edgecolor='black') + panel1 = plt.axes([0.045, 0.17, 0.92, 0.65]) + xlabels = [] + + x = 0.4 + ymax = 0 + colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256], + [253/256,202/256,181/256], [252/256,138/256,106/256], [241/256,68/256,50/256], [188/256,25/256,26/256], + [208/256,225/256,242/256], [148/256,196/256,223/256], [74/256,152/256,201/256], [23/256,100/256,171/256], + [226/256,226/256,239/256], [182/256,182/256,216/256], [134/256,131/256,189/256], [98/256,64/256,155/256]] + + x = .0475 + y_top = .827 + y_bottom = .114 + y = int(ymax*1.25) + y2 = y+2 + for i in range(0, 12, 1): + panel1.add_patch(plt.Rectangle((x,y_top), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x,y_bottom), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) + x += .0665 + + panel1.add_patch(plt.Rectangle((x-.001,y_top), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x-.001,y_bottom), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) + x +=.011 + panel1.add_patch(plt.Rectangle((x,y_top), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x,y_bottom), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) + x += .022 + panel1.add_patch(plt.Rectangle((x,y_top), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x,y_bottom), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) + x += .0335 + panel1.add_patch(plt.Rectangle((x,y_top), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) + panel1.add_patch(plt.Rectangle((x,y_bottom), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) + + + + + yText = y_top + .01 + plt.text(.072, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) + plt.text(.1385, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) + plt.text(.205, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) + plt.text(.2715, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) + plt.text(.338, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.4045, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.471, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.5375, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) + plt.text(.604, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.6705, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.737, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.8035, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) + plt.text(.844, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.861, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.888, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.93, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) + + yText_labels_top = yText + .075 + yText_labels_bottom = y_bottom - .03 + yText_labels_bottom_sec = yText_labels_bottom - .045 + + plt.text(.08, yText_labels_top, '1bp Deletion', fontsize=40, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) + plt.text(.21, yText_labels_top, '1bp Insertion', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.375, yText_labels_top, '>1bp Deletion at Repeats\n (Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.64, yText_labels_top, '>1bp Insertion at Repeats\n (Insertion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.85, yText_labels_top, ' Microhomology\n(Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + plt.text(.058, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) + plt.text(.19, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.39, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.65, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + plt.text(.85, yText_labels_bottom_sec, 'Microhomology Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + x = .0477 + for i in range (0, 8, 1): + if i != 2 and i != 3: + plt.text(x, yText_labels_bottom, '1 2 3 4 5 6+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + else: + plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + x += .0665 + + for i in range (0, 4, 1): + plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + x += .0665 + + plt.text(x, yText_labels_bottom, '1', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + x += .011 + plt.text(x, yText_labels_bottom, '1 2', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + x += .022 + plt.text(x, yText_labels_bottom, '1 2 3', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + x += .0335 + plt.text(x, yText_labels_bottom, '1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) + + + labs = np.arange(0.375,83.375,1) + + panel1.set_xlim([0, 83]) + panel1.set_ylim([0, y]) + panel1.set_xticks(labs) + + + + # panel1.set_yticklabels(ylabels, fontsize=30) + plt.gca().yaxis.grid(True) + plt.gca().grid(which='major', axis='y', color=[0.6,0.6,0.6], zorder=1) + panel1.set_xlabel('') + panel1.set_ylabel('') + + panel1.tick_params(axis='both',which='both',\ + bottom=False, labelbottom=False,\ + left=False, labelleft=True,\ + right=False, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='gray', width=2) + + [i.set_color("black") for i in plt.gca().get_yticklabels()] + package_path = spplt.__path__[0] + path_1 =os.path.join(package_path,'templates/') + filename= os.path.join(path_1,'ID'+'.pkl') + pickle.dump(plot1, open(filename, 'wb')) @@ -856,7 +970,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust muts = data[sample].values if percentage: if total_count > 0: - plt.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + plt.bar(np.arange(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) ymax = np.max(muts/total_count*100) else: plt.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) @@ -3758,7 +3872,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust print("The provided plot_type: ", plot_type, " is not supported by this plotting function") -def plotID(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None): +def plotID(matrix_path, output_path, project, plot_type, percentage=False, custom_text_upper=None, custom_text_middle=None, custom_text_bottom=None, savefig_format = "pdf"): # if 'roman' in matplotlib.font_manager.weight_dict: # del matplotlib.font_manager.weight_dict['roman'] # matplotlib.font_manager._rebuild() @@ -3766,224 +3880,58 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo sig_probs = False pcawg = False if plot_type == '94' or plot_type == 'ID94' or plot_type == '94ID' or plot_type == '83': - with open(matrix_path) as f: - next(f) - first_line = f.readline() - first_line = first_line.strip().split() - if first_line[0][1] == 'D' or first_line[0][0] == 'D': - pcawg = True - mutation_type = first_line[0] - mutation_type_list = mutation_type.split(":") - if len(mutation_type_list) != 4 and first_line[0][1] != 'D' and first_line[0][0] != 'D': - sys.exit("The matrix does not match the correct ID96 format. Please check you formatting and rerun this plotting function.") - pp = PdfPages(output_path + 'ID_83_plots_' + project + '.pdf') - indel_types = ['1:Del:C:0', '1:Del:C:1', '1:Del:C:2', '1:Del:C:3', '1:Del:C:4', '1:Del:C:5', - '1:Del:T:0', '1:Del:T:1', '1:Del:T:2', '1:Del:T:3', '1:Del:T:4', '1:Del:T:5', - '1:Ins:C:0', '1:Ins:C:1', '1:Ins:C:2', '1:Ins:C:3', '1:Ins:C:4', '1:Ins:C:5', - '1:Ins:T:0', '1:Ins:T:1', '1:Ins:T:2', '1:Ins:T:3', '1:Ins:T:4', '1:Ins:T:5', - # >1bp INDELS - '2:Del:R:0', '2:Del:R:1', '2:Del:R:2', '2:Del:R:3', '2:Del:R:4', '2:Del:R:5', - '3:Del:R:0', '3:Del:R:1', '3:Del:R:2', '3:Del:R:3', '3:Del:R:4', '3:Del:R:5', - '4:Del:R:0', '4:Del:R:1', '4:Del:R:2', '4:Del:R:3', '4:Del:R:4', '4:Del:R:5', - '5:Del:R:0', '5:Del:R:1', '5:Del:R:2', '5:Del:R:3', '5:Del:R:4', '5:Del:R:5', - '2:Ins:R:0', '2:Ins:R:1', '2:Ins:R:2', '2:Ins:R:3', '2:Ins:R:4', '2:Ins:R:5', - '3:Ins:R:0', '3:Ins:R:1', '3:Ins:R:2', '3:Ins:R:3', '3:Ins:R:4', '3:Ins:R:5', - '4:Ins:R:0', '4:Ins:R:1', '4:Ins:R:2', '4:Ins:R:3', '4:Ins:R:4', '4:Ins:R:5', - '5:Ins:R:0', '5:Ins:R:1', '5:Ins:R:2', '5:Ins:R:3', '5:Ins:R:4', '5:Ins:R:5', - #MicroHomology INDELS - '2:Del:M:1', '3:Del:M:1', '3:Del:M:2', '4:Del:M:1', '4:Del:M:2', '4:Del:M:3', - '5:Del:M:1', '5:Del:M:2', '5:Del:M:3', '5:Del:M:4', '5:Del:M:5'] - mutations = OrderedDict() + if not isinstance(matrix_path, pd.DataFrame): + data=pd.read_csv(matrix_path,sep='\t',index_col=0) + data=data.dropna(axis=1, how='all') + if data.isnull().values.any(): + raise ValueError("Input data contains Nans.") + try: - with open (matrix_path) as f: - first_line = f.readline() - if pcawg: - samples = first_line.strip().split(",") - samples = samples[4:] - samples = [x.replace('"','') for x in samples] - else: - samples = first_line.strip().split("\t") - samples = samples[1:] - for sample in samples: - mutations[sample] = OrderedDict() - mutations[sample]['1DelC'] = [0,0,0,0,0,0] - mutations[sample]['1DelT'] = [0,0,0,0,0,0] - mutations[sample]['1InsC'] = [0,0,0,0,0,0] - mutations[sample]['1InsT'] = [0,0,0,0,0,0] - mutations[sample]['2DelR'] = [0,0,0,0,0,0] - mutations[sample]['3DelR'] = [0,0,0,0,0,0] - mutations[sample]['4DelR'] = [0,0,0,0,0,0] - mutations[sample]['5DelR'] = [0,0,0,0,0,0] - mutations[sample]['2InsR'] = [0,0,0,0,0,0] - mutations[sample]['3InsR'] = [0,0,0,0,0,0] - mutations[sample]['3InsR'] = [0,0,0,0,0,0] - mutations[sample]['4InsR'] = [0,0,0,0,0,0] - mutations[sample]['5InsR'] = [0,0,0,0,0,0] - mutations[sample]['2DelM'] = [0] - mutations[sample]['3DelM'] = [0,0] - mutations[sample]['4DelM'] = [0,0,0] - mutations[sample]['5DelM'] = [0,0,0,0,0] - - for lines in f: - if pcawg: - line = lines.strip().split(",") - line = [x.replace('"','') for x in line] - if line[1] == 'repeats': - mut_type = line[2][0] + line[0][0] + line[0][1].lower() + line[0][2].lower() + "R" - else: - mut_type = line[2][0] + line[0][0] + line[0][1].lower() + line[0][2].lower() + line[1][0] - try: - repeat_size = int(line[3]) - except: - repeat_size = int(line[3][0]) - if line[1] == 'MH': - repeat_size -= 1 - sample_index = 4 - else: - line = lines.strip().split() - if line[0] not in indel_types: - continue - categories = line[0].split(":") - mut_type = categories[0] + categories[1] + categories[2] - repeat_size = int(categories[3]) - if categories[2] == 'M': - repeat_size -= 1 - sample_index = 1 - - for sample in samples: - if mut_type in mutations[sample].keys(): - if percentage: - mutCount = float(line[sample_index]) - if mutCount < 1 and mutCount > 0: - sig_probs = True - else: - try: - mutCount = int(line[sample_index]) - except: - print("It appears that the provided matrix does not contain mutation counts.\n\tIf you have provided a signature activity matrix, please change the percentage parameter to True.\n\tOtherwise, ", end='') + sample_count = 0 + buf= io.BytesIO() + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/ID.pkl','rb')) + pickle.dump(fig_orig, buf) - # mutCount = int(line[sample_index]) - mutations[sample][mut_type][repeat_size] = mutCount - else: - continue - sample_index += 1 + figs={} - sample_count = 0 - for sample in mutations.keys(): - total_count = sum(sum(nuc) for nuc in mutations[sample].values()) - plt.rcParams['axes.linewidth'] = 2 - plot1 = plt.figure(figsize=(43.93,12)) - plt.rc('axes', edgecolor='black') - panel1 = plt.axes([0.045, 0.17, 0.92, 0.65]) - xlabels = [] + colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256], + [253/256,202/256,181/256], [252/256,138/256,106/256], [241/256,68/256,50/256], [188/256,25/256,26/256], + [208/256,225/256,242/256], [148/256,196/256,223/256], [74/256,152/256,201/256], [23/256,100/256,171/256], + [226/256,226/256,239/256], [182/256,182/256,216/256], [134/256,131/256,189/256], [98/256,64/256,155/256]] + ctx = data.index + xlabels= [i.split(":")[0]+i.split(":")[1]+i.split(":")[2] for i in ctx.to_list()] + xlables_set= ['1DelC', '1DelT', '1InsC', '1InsT', '2DelR', '3DelR', '4DelR', '5DelR', '2InsR','3InsR','4InsR','5InsR', '2DelM', '3DelM','4DelM','5DelM'] + colors_idx = copy.deepcopy(xlabels) + for ii in range(0,len(xlables_set)): + colors_idx=[ii if x==xlables_set[ii] else x for x in colors_idx] + + # pdb.set_trace() + colors_flat_list = [colors[i] for i in colors_idx] + for sample in data.columns: #mutations.keys(): + + buf.seek(0) + figs[sample]=pickle.load(buf) + panel1= figs[sample].axes[0] + muts= data[sample].values + total_count = np.sum(muts) x = 0.4 - ymax = 0 - colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256], - [253/256,202/256,181/256], [252/256,138/256,106/256], [241/256,68/256,50/256], [188/256,25/256,26/256], - [208/256,225/256,242/256], [148/256,196/256,223/256], [74/256,152/256,201/256], [23/256,100/256,171/256], - [226/256,226/256,239/256], [182/256,182/256,216/256], [134/256,131/256,189/256], [98/256,64/256,155/256]] - i = 0 - for key in mutations[sample]: - l = 1 - for seq in mutations[sample][key]: - xlabels.append(l) - if percentage: - if total_count > 0: - plt.bar(x, seq/total_count*100,width=0.4,color=colors[i],align='center', zorder=1000) - if seq/total_count*100 > ymax: - ymax = seq/total_count*100 - else: - plt.bar(x, seq,width=0.4,color=colors[i],align='center', zorder=1000) - if seq > ymax: - ymax = seq - x += 1 - l += 1 - i += 1 + if percentage: + if total_count > 0: + plt.bar(np.arange(len(ctx))+x, muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts/total_count*100) + else: + plt.bar(np.arange(len(ctx))+x, muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) + ymax = np.max(muts) x = .0475 y_top = .827 y_bottom = .114 y = int(ymax*1.25) y2 = y+2 - for i in range(0, 12, 1): - panel1.add_patch(plt.Rectangle((x,y_top), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x,y_bottom), .0595, .05, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - x += .0665 - - panel1.add_patch(plt.Rectangle((x-.001,y_top), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x-.001,y_bottom), .006, .05, facecolor=colors[12], clip_on=False, transform=plt.gcf().transFigure)) - x +=.011 - panel1.add_patch(plt.Rectangle((x,y_top), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x,y_bottom), .0155, .05, facecolor=colors[13], clip_on=False, transform=plt.gcf().transFigure)) - x += .022 - panel1.add_patch(plt.Rectangle((x,y_top), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x,y_bottom), .027, .05, facecolor=colors[14], clip_on=False, transform=plt.gcf().transFigure)) - x += .0335 - panel1.add_patch(plt.Rectangle((x,y_top), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) - panel1.add_patch(plt.Rectangle((x,y_bottom), .049, .05, facecolor=colors[15], clip_on=False, transform=plt.gcf().transFigure)) - - - - - yText = y_top + .01 - plt.text(.072, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) - plt.text(.1385, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) - plt.text(.205, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) - plt.text(.2715, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) - plt.text(.338, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.4045, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.471, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.5375, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) - plt.text(.604, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.6705, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.737, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.8035, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) - plt.text(.844, yText, '2', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.861, yText, '3', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.888, yText, '4', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.93, yText, '5+', fontsize=40, fontweight='bold', fontname='Times New Roman', color='white', transform=plt.gcf().transFigure) - - yText_labels_top = yText + .075 - yText_labels_bottom = y_bottom - .03 - yText_labels_bottom_sec = yText_labels_bottom - .045 - - plt.text(.08, yText_labels_top, '1bp Deletion', fontsize=40, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) - plt.text(.21, yText_labels_top, '1bp Insertion', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.375, yText_labels_top, '>1bp Deletion at Repeats\n (Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.64, yText_labels_top, '>1bp Insertion at Repeats\n (Insertion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.85, yText_labels_top, ' Microhomology\n(Deletion Length)', fontsize=40, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - - plt.text(.058, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) - plt.text(.19, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.39, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.65, yText_labels_bottom_sec, 'Number of Repeat Units', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - plt.text(.85, yText_labels_bottom_sec, 'Microhomology Length', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - - x = .0477 - for i in range (0, 8, 1): - if i != 2 and i != 3: - plt.text(x, yText_labels_bottom, '1 2 3 4 5 6+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - else: - plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - - x += .0665 - - for i in range (0, 4, 1): - plt.text(x, yText_labels_bottom, '0 1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - x += .0665 - - plt.text(x, yText_labels_bottom, '1', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - x += .011 - plt.text(x, yText_labels_bottom, '1 2', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - x += .022 - plt.text(x, yText_labels_bottom, '1 2 3', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - x += .0335 - plt.text(x, yText_labels_bottom, '1 2 3 4 5+', fontsize=32, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - if y <= 4: y += 4 @@ -3995,22 +3943,22 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo if percentage: ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] + str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] else: ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] ylabels= [0, ytick_offest, ytick_offest*2, - ytick_offest*3, ytick_offest*4] + ytick_offest*3, ytick_offest*4] labs = np.arange(0.375,83.375,1) if not percentage: - ylabels=getylabels(ylabels) + ylabels=spplt.getylabels(ylabels) panel1.set_xlim([0, 83]) panel1.set_ylim([0, y]) panel1.set_xticks(labs) panel1.set_yticks(ylabs) - + # import pdb;pdb.set_trace() if sig_probs: plt.text(0.0475, 0.75, sample, fontsize=60, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) else: @@ -4076,255 +4024,41 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo plt.ylabel("Number of Indels", fontsize=35, fontname="Times New Roman", weight = 'bold') panel1.tick_params(axis='both',which='both',\ - bottom=False, labelbottom=False,\ - left=False, labelleft=True,\ - right=False, labelright=False,\ - top=False, labeltop=False,\ - direction='in', length=25, colors='gray', width=2) + bottom=False, labelbottom=False,\ + left=False, labelleft=True,\ + right=False, labelright=False,\ + top=False, labeltop=False,\ + direction='in', length=25, colors='gray', width=2) [i.set_color("black") for i in plt.gca().get_yticklabels()] - - pp.savefig(plot1) - plt.close() + # import pdb;pdb.set_trace() + # pp.savefig(plot1) + # plt.close() sample_count += 1 - pp.close() + # pp.close() + if savefig_format == "pdf": + pp = PdfPages(output_path + 'ID_83_plots_' + project + '.pdf') # PdfPages(output_path + 'SBS_96_plots_' + project + '.pdf') + + + if savefig_format == "pdf": + for fig in figs: + figs[fig].savefig(pp, format='pdf') + pp.close() + + if savefig_format == "png": + for fig in figs: + figs[fig].savefig(output_path + 'SBS_96_plots_'+fig+'.png',dpi=100) + if savefig_format == "buffer_stream": + buff_list={} + for fig in figs: + buffer2=io.BytesIO() + figs[fig].savefig(buffer2,format='png') + buff_list[fig]=buffer2 + return buff_list except: print("There may be an issue with the formatting of your matrix file.") os.remove(output_path + 'ID_83_plots_' + project + '.pdf') - # =======================================OLD INDEL-TSB PLOT================================================================================== - # elif plot_type == '96' or plot_type == 'ID96' or plot_type == '96ID' or plot_type == 'IDSB': - # with open(matrix_path) as f: - # next(f) - # first_line = f.readline() - # first_line = first_line.strip().split("\t") - # mutation_type = first_line[0] - # mutation_type_list = mutation_type.split(":") - # if len(mutation_type_list) != 5: - # print(mutation_type_list) - # sys.exit("The matrix does not match the correct ID-96 format. Please check you formatting and rerun this plotting function.") - - # pp = PdfPages(output_path + 'ID_96_plots_' + project + '.pdf') - - # indel_types = ['1:Del:C:1', '1:Del:C:2', '1:Del:C:3', '1:Del:C:4', '1:Del:C:5', '1:Del:C:6' - # '1:Del:T:1', '1:Del:T:2', '1:Del:T:3', '1:Del:T:4', '1:Del:T:5', '1:Del:T:6' - # '1:Ins:C:0', '1:Ins:C:1', '1:Ins:C:2', '1:Ins:C:3', '1:Ins:C:4', '1:Ins:C:5', - # '1:Ins:T:0', '1:Ins:T:1', '1:Ins:T:2', '1:Ins:T:3', '1:Ins:T:4', '1:Ins:T:5'] - - # sig_probs = False - # mutations = OrderedDict() - # with open (matrix_path) as f: - # first_line = f.readline() - # samples = first_line.strip().split("\t") - # samples = samples[1:] - # for sample in samples: - # mutations[sample] = OrderedDict() - # mutations[sample]['1DelC'] = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] - # mutations[sample]['1DelT'] = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] - # mutations[sample]['1InsC'] = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] - # mutations[sample]['1InsT'] = [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]] - - # for lines in f: - # line = lines.strip().split() - # categories = line[0].split(":") - # if categories[1] != '1': - # break - # else: - # mut_type = categories[1] + categories[2] + categories[3] - # bias = categories[0] - # if bias != 'T' and bias != 'U': - # continue - # else: - # repeat_size = int(categories[4]) - # sample_index = 1 - # for sample in samples: - # if mut_type in mutations[sample]: - # if percentage: - # mutCount = float(line[sample_index]) - # if mutCount < 1 and mutCount > 0: - # sig_probs = True - # else: - # mutCount = int(line[sample_index]) - # if bias == 'T': - # mutations[sample][mut_type][repeat_size][0] = mutCount - # else: - # mutations[sample][mut_type][repeat_size][1] = mutCount - # else: - # continue - # sample_index += 1 - - # for sample in mutations: - # total_count = sum(sum(sum(tsb) for tsb in nuc) for nuc in mutations[sample].values()) - # plt.rcParams['axes.linewidth'] = 2 - # plot1 = plt.figure(figsize=(15,13)) - # plt.rc('axes', edgecolor='black') - # panel1 = plt.axes([0.12, 0.12, 0.8, 0.77]) - # xlabels = [] - - # x = 0.3 - # ymax = 0 - # colors = [[253/256,190/256,111/256], [255/256,128/256,2/256], [176/256,221/256,139/256], [54/256,161/256,46/256]] - - # i = 0 - # for key in mutations[sample]: - # l = 1 - # for seq in mutations[sample][key]: - # xlabels.append(l) - # if percentage: - # trans = plt.bar(x, seq[0]/total_count*100,width=0.2,color=[1/256,70/256,102/256],align='center', zorder=1000, label='Transcribed Strand') - # x += 0.2 - # untrans = plt.bar(x, seq[1]/total_count*100,width=0.2,color=[228/256,41/256,38/256],align='center', zorder=1000, label='Untranscribed Strand') - # x += 0.8 - # if seq[0]/total_count*100 > ymax: - # ymax = seq[0]/total_count*100 - # if seq[1]/total_count*100 > ymax: - # ymax = seq[1]/total_count*100 - # else: - # trans = plt.bar(x, seq[0],width=0.2,color=[1/256,70/256,102/256],align='center', zorder=1000, label='Transcribed Strand') - # x += 0.2 - # untrans = plt.bar(x, seq[1],width=0.2,color=[228/256,41/256,38/256],align='center', zorder=1000, label='Untranscribed Strand') - # x += 0.8 - # if seq[0] > ymax: - # ymax = seq[0] - # if seq[1] > ymax: - # ymax = seq[1] - # l += 1 - # i += 1 - - # x = .125 - # y_top = .8975 - # #y_bottom = .06525 - # y_bottom = .075 - # y = int(ymax*1.25) - # y2 = y+2 - - - - - - # for i in range(0, 4, 1): - # panel1.add_patch(plt.Rectangle((x,y_top), .185, .037, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - # panel1.add_patch(plt.Rectangle((x,y_bottom), .185, .037, facecolor=colors[i], clip_on=False, transform=plt.gcf().transFigure)) - # x += .202 - - - # yText = y_top + .005 - # plt.text(.205, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) - # plt.text(.407, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) - # plt.text(.609, yText, 'C', fontsize=40, fontname='Times New Roman', fontweight='bold', transform=plt.gcf().transFigure) - # plt.text(.811, yText, 'T', fontsize=40, fontname='Times New Roman', fontweight='bold', color='white', transform=plt.gcf().transFigure) - - # yText_labels_top = yText + .05 - # yText_labels_bottom = y_bottom - .03 - # yText_labels_bottom_sec = yText_labels_bottom -.025 - - # plt.text(.23, yText_labels_top, '1bp Deletion', fontsize=35, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) - # plt.text(.634, yText_labels_top, '1bp Insertion', fontsize=35, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # plt.text(.18, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=30, fontname='Times New Roman', weight='bold', color='black', transform=plt.gcf().transFigure) - # plt.text(.58, yText_labels_bottom_sec, 'Homopolymer Length', fontsize=30, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - - # x = .127 - # yText_labels_bottom = y_bottom - 0.025 - - # for l in range (0, 4, 1): - # if l < 2: - # for i in range(1, 6, 1): - # plt.text(x, yText_labels_bottom, str(i), fontsize=25, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # x += 0.034 - # x -= 0.008 - # plt.text(x, yText_labels_bottom, '6+', fontsize=25, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # x += 0.041 - # else: - # for i in range(0, 5, 1): - # plt.text(x, yText_labels_bottom, str(i), fontsize=25, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # x += 0.033 - # x -= 0.005 - # plt.text(x, yText_labels_bottom, '5+', fontsize=25, fontweight='bold', fontname='Times New Roman', color='black', transform=plt.gcf().transFigure) - # x += 0.044 - - # if y <= 4: - # y += 4 - - # while y%4 != 0: - # y += 1 - # ytick_offest = int(y/4) - - - # x_shaded = 0 - # for i in range(0, 4, 1): - # panel1.add_patch(plt.Rectangle((x_shaded,0), 6, y, facecolor=colors[i], zorder=0, alpha = 0.25, edgecolor='grey')) - # x_shaded += 6 - - # if percentage: - # ylabs = [0, round(ytick_offest, 1), round(ytick_offest*2, 1), round(ytick_offest*3, 1), round(ytick_offest*4, 1)] - # ylabels= [str(0), str(round(ytick_offest, 1)) + "%", str(round(ytick_offest*2, 1)) + "%", - # str(round(ytick_offest*3, 1)) + "%", str(round(ytick_offest*4, 1)) + "%"] - # else: - # ylabs = [0, ytick_offest, ytick_offest*2, ytick_offest*3, ytick_offest*4] - # ylabels= [0, ytick_offest, ytick_offest*2, - # ytick_offest*3, ytick_offest*4] - - - # if not percentage: - # ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp - - # panel1.set_xlim([0, 23.8]) - # panel1.set_ylim([0, y]) - # panel1.set_yticks(ylabs) - - # if sig_probs: - # plt.text(0.13, 0.85, sample, fontsize=33, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - # else: - # plt.text(0.13, 0.85, sample + ": " + "{:,}".format(int(total_count)) + " transcribed indels", fontsize=33, weight='bold', color='black', fontname= "Arial", transform=plt.gcf().transFigure) - - # panel1.set_yticklabels(ylabels, fontsize=30) - # plt.gca().yaxis.grid(True) - # plt.gca().grid(which='major', axis='y', color=[0.6,0.6,0.6], zorder=1) - # panel1.set_xlabel('') - # panel1.set_ylabel('') - # plt.legend(handles=[trans, untrans], prop={'size':20}) - - # if percentage: - # plt.ylabel("Percentage of Indels", fontsize=35, fontname="Times New Roman", weight = 'bold') - # else: - # plt.ylabel("Number of Indels", fontsize=35, fontname="Times New Roman", weight = 'bold') - - # panel1.tick_params(axis='both',which='both',\ - # bottom=False, labelbottom=False,\ - # left=False, labelleft=True,\ - # right=False, labelright=False,\ - # top=False, labeltop=False,\ - # direction='in', length=25, colors='gray', width=2) - - # [i.set_color("black") for i in plt.gca().get_yticklabels()] - - - - - - # pp.savefig(plot1) - # plt.close() - # pp.close() - # =================================================================================================================================== - elif plot_type == 'INDEL_simple' or plot_type == 'simple_INDEL' or plot_type == 'ID_simple' or plot_type == 'simple_ID' or plot_type == '28': @@ -5008,6 +4742,7 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust colors_idxs = le.fit_transform(mainlist) colors_flat_list = [colors[i] for i in colors_idxs] sample_count = 0 + buf= io.BytesIO() From be33da7c1f11da72a8898e370507945c8f88d5c7 Mon Sep 17 00:00:00 2001 From: Raviteja Vangara Date: Tue, 18 Oct 2022 16:06:32 -0700 Subject: [PATCH 21/21] bug fixes with deployment --- .../sigProfilerPlotting.py | 70 ++++++------- build/lib/sigProfilerPlotting/version.py | 4 +- setup.py | 2 +- sigProfilerPlotting/sigProfilerPlotting.py | 99 ++++++++++--------- sigProfilerPlotting/version.py | 4 +- 5 files changed, 92 insertions(+), 87 deletions(-) diff --git a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py index a1124e8..0b10e27 100644 --- a/build/lib/sigProfilerPlotting/sigProfilerPlotting.py +++ b/build/lib/sigProfilerPlotting/sigProfilerPlotting.py @@ -29,8 +29,8 @@ import sigProfilerPlotting as spplt import pdb import itertools,time -# import sklearn -# from sklearn.preprocessing import LabelEncoder +import sklearn +from sklearn.preprocessing import LabelEncoder import copy warnings.filterwarnings("ignore") @@ -58,7 +58,7 @@ def install_plot_templates(context='SBS96'): filename= os.path.join(install_path,context+'.pkl') make_pickle_file(context,path=filename) -def make_pickle_file(context='SBS96',path='SBS96.pkl'): +def make_pickle_file(context='SBS96',path='SBS96.pkl', return_plot_template=False): if context == 'SBS96': plot_custom_text = False sig_probs = False @@ -148,7 +148,10 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): [i.set_color("black") for i in plt.gca().get_yticklabels()] - pickle.dump(plot1, open(path, 'wb')) + if return_plot_template == False: + pickle.dump(plot1, open(path, 'wb')) + else: + return plot1 elif context =='SBS288': plot_custom_text = False sig_probs = False @@ -255,7 +258,10 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): # panel2.set_xticks(xlabels) handles, labels = panel2.get_legend_handles_labels() panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) - pickle.dump(plot1, open(path, 'wb')) + if return_plot_template == False: + pickle.dump(plot1, open(path, 'wb')) + else: + return plot1 elif context =='DBS78': @@ -337,7 +343,10 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): [i.set_color("black") for i in plt.gca().get_yticklabels()] [i.set_color("grey") for i in plt.gca().get_xticklabels()] - pickle.dump(plot1, open(path, 'wb')) + if return_plot_template == False: + pickle.dump(plot1, open(path, 'wb')) + else: + return plot1 elif context =='ID83': plt.rcParams['axes.linewidth'] = 2 @@ -456,12 +465,15 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): direction='in', length=25, colors='gray', width=2) [i.set_color("black") for i in plt.gca().get_yticklabels()] - package_path = spplt.__path__[0] - path_1 =os.path.join(package_path,'templates/') - filename= os.path.join(path_1,'ID'+'.pkl') - pickle.dump(plot1, open(filename, 'wb')) - + # package_path = spplt.__path__[0] + # path_1 =os.path.join(package_path,'templates/') + # filename= os.path.join(path_1,'ID'+'.pkl') + # pickle.dump(plot1, open(filename, 'wb')) + if return_plot_template == False: + pickle.dump(plot1, open(path, 'wb')) + else: + return plot1 def getylabels(ylabels): if max(ylabels) >=10**9: @@ -947,10 +959,15 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust data= reindex_sbs96(data) sample_count = 0 + buf= io.BytesIO() - - fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS96.pkl','rb')) - pickle.dump(fig_orig, buf) + try: + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS96.pkl','rb')) + pickle.dump(fig_orig, buf) + except: + fig_orig=make_pickle_file(context='SBS96',path='SBS96.pkl', return_plot_template=True) + pickle.dump(fig_orig, buf) + figs={} buff_list={} ctx = data.index #[seq[0]+seq[2]+seq[6] for seq in data.index] @@ -1574,30 +1591,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if not percentage: ylabels = getylabels(ylabels) - #ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if max(ylabels)< 10**5: - # ylabels = ['{:,.2f}'.format(x/1000)+'k' for x in ylabels] - # elif max(ylabels)<= 10**9: - # ylabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 264]) panel1.set_ylim([0, y]) @@ -3891,7 +3885,7 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo try: sample_count = 0 buf= io.BytesIO() - fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/ID.pkl','rb')) + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/ID83.pkl','rb')) pickle.dump(fig_orig, buf) figs={} diff --git a/build/lib/sigProfilerPlotting/version.py b/build/lib/sigProfilerPlotting/version.py index 86a2e82..a599e6e 100644 --- a/build/lib/sigProfilerPlotting/version.py +++ b/build/lib/sigProfilerPlotting/version.py @@ -1,6 +1,6 @@ # THIS FILE IS GENERATED FROM SIGPROFILERPLOTTING SETUP.PY -short_version = '1.2.2' -version = '1.2.2' +short_version = '1.2.3' +version = '1.2.3' \ No newline at end of file diff --git a/setup.py b/setup.py index b638072..438b73d 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ def readme(): with open('README.rst') as f: return(f.read()) -VERSION = '1.2.2' +VERSION = '1.2.3' def write_version_py(filename='sigProfilerPlotting/version.py'): # Copied from numpy setup.py diff --git a/sigProfilerPlotting/sigProfilerPlotting.py b/sigProfilerPlotting/sigProfilerPlotting.py index a1124e8..ee4b469 100644 --- a/sigProfilerPlotting/sigProfilerPlotting.py +++ b/sigProfilerPlotting/sigProfilerPlotting.py @@ -29,8 +29,8 @@ import sigProfilerPlotting as spplt import pdb import itertools,time -# import sklearn -# from sklearn.preprocessing import LabelEncoder +import sklearn +from sklearn.preprocessing import LabelEncoder import copy warnings.filterwarnings("ignore") @@ -58,7 +58,7 @@ def install_plot_templates(context='SBS96'): filename= os.path.join(install_path,context+'.pkl') make_pickle_file(context,path=filename) -def make_pickle_file(context='SBS96',path='SBS96.pkl'): +def make_pickle_file(context='SBS96',path='SBS96.pkl', return_plot_template=False): if context == 'SBS96': plot_custom_text = False sig_probs = False @@ -148,7 +148,10 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): [i.set_color("black") for i in plt.gca().get_yticklabels()] - pickle.dump(plot1, open(path, 'wb')) + if return_plot_template == False: + pickle.dump(plot1, open(path, 'wb')) + else: + return plot1 elif context =='SBS288': plot_custom_text = False sig_probs = False @@ -255,7 +258,10 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): # panel2.set_xticks(xlabels) handles, labels = panel2.get_legend_handles_labels() panel2.legend(handles[:3], labels[:3], loc='best', prop={'size':30}) - pickle.dump(plot1, open(path, 'wb')) + if return_plot_template == False: + pickle.dump(plot1, open(path, 'wb')) + else: + return plot1 elif context =='DBS78': @@ -337,7 +343,10 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): [i.set_color("black") for i in plt.gca().get_yticklabels()] [i.set_color("grey") for i in plt.gca().get_xticklabels()] - pickle.dump(plot1, open(path, 'wb')) + if return_plot_template == False: + pickle.dump(plot1, open(path, 'wb')) + else: + return plot1 elif context =='ID83': plt.rcParams['axes.linewidth'] = 2 @@ -456,12 +465,15 @@ def make_pickle_file(context='SBS96',path='SBS96.pkl'): direction='in', length=25, colors='gray', width=2) [i.set_color("black") for i in plt.gca().get_yticklabels()] - package_path = spplt.__path__[0] - path_1 =os.path.join(package_path,'templates/') - filename= os.path.join(path_1,'ID'+'.pkl') - pickle.dump(plot1, open(filename, 'wb')) - + # package_path = spplt.__path__[0] + # path_1 =os.path.join(package_path,'templates/') + # filename= os.path.join(path_1,'ID'+'.pkl') + # pickle.dump(plot1, open(filename, 'wb')) + if return_plot_template == False: + pickle.dump(plot1, open(path, 'wb')) + else: + return plot1 def getylabels(ylabels): if max(ylabels) >=10**9: @@ -947,10 +959,15 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust data= reindex_sbs96(data) sample_count = 0 + buf= io.BytesIO() - - fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS96.pkl','rb')) - pickle.dump(fig_orig, buf) + try: + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS96.pkl','rb')) + pickle.dump(fig_orig, buf) + except: + fig_orig=make_pickle_file(context='SBS96',path='SBS96.pkl', return_plot_template=True) + pickle.dump(fig_orig, buf) + figs={} buff_list={} ctx = data.index #[seq[0]+seq[2]+seq[6] for seq in data.index] @@ -1574,30 +1591,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust if not percentage: ylabels = getylabels(ylabels) - #ylabels = ['{:,}'.format(int(x)) for x in ylabels] - # if max(ylabels)< 10**5: - # ylabels = ['{:,.2f}'.format(x/1000)+'k' for x in ylabels] - # elif max(ylabels)<= 10**9: - # ylabels = ['{:,.2f}'.format(x/(10**6))+'m' for x in ylabels] - # if len(ylabels[-1]) > 3: - # ylabels_temp = [] - # if len(ylabels[-1]) > 7: - # for label in ylabels: - # if len(label) > 7: - # ylabels_temp.append(label[0:-8] + "m") - # elif len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - - # else: - # for label in ylabels: - # if len(label) > 3: - # ylabels_temp.append(label[0:-4] + "k") - # else: - # ylabels_temp.append(label) - # ylabels = ylabels_temp panel1.set_xlim([0, 264]) panel1.set_ylim([0, y]) @@ -3362,8 +3356,13 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust data,tsb_mats = reindex_sbs288(data) buf= io.BytesIO() - fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS288.pkl','rb')) - pickle.dump(fig_orig, buf) + try: + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/SBS288.pkl','rb')) + pickle.dump(fig_orig, buf) + except: + fig_orig=make_pickle_file(context='SBS288',path='SBS288.pkl', return_plot_template=True) + pickle.dump(fig_orig, buf) + figs = {} buff_list = {} ctx = data.index @@ -3383,7 +3382,7 @@ def plotSBS(matrix_path, output_path, project, plot_type, percentage=False, cust x=0.4 if percentage: if total_count > 0: - panel1.bar(range(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) + panel1.bar(np.arange(len(ctx))+x,muts/total_count*100,width=0.4,color=colors_flat_list,align='center', zorder=1000) ymax = np.max(muts/total_count*100) else: panel1.bar(np.arange(len(ctx))+x,muts,width=0.4,color=colors_flat_list,align='center', zorder=1000) @@ -3891,8 +3890,13 @@ def plotID(matrix_path, output_path, project, plot_type, percentage=False, custo try: sample_count = 0 buf= io.BytesIO() - fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/ID.pkl','rb')) - pickle.dump(fig_orig, buf) + try: + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/ID83.pkl','rb')) + pickle.dump(fig_orig, buf) + except: + fig_orig=make_pickle_file(context='ID83',path='ID83.pkl', return_plot_template=True) + pickle.dump(fig_orig, buf) + figs={} @@ -4746,8 +4750,15 @@ def plotDBS(matrix_path, output_path, project, plot_type, percentage=False, cust buf= io.BytesIO() - fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/DBS78.pkl','rb')) - pickle.dump(fig_orig, buf) + # fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/DBS78.pkl','rb')) + # pickle.dump(fig_orig, buf) + try: + fig_orig=pickle.load(open(spplt.__path__[0]+'/templates/DBS78.pkl','rb')) + pickle.dump(fig_orig, buf) + except: + fig_orig=make_pickle_file(context='DBS78',path='DBS78.pkl', return_plot_template=True) + pickle.dump(fig_orig, buf) + figs={} diff --git a/sigProfilerPlotting/version.py b/sigProfilerPlotting/version.py index 86a2e82..a599e6e 100644 --- a/sigProfilerPlotting/version.py +++ b/sigProfilerPlotting/version.py @@ -1,6 +1,6 @@ # THIS FILE IS GENERATED FROM SIGPROFILERPLOTTING SETUP.PY -short_version = '1.2.2' -version = '1.2.2' +short_version = '1.2.3' +version = '1.2.3' \ No newline at end of file