<jupyter_start><jupyter_text>Make Neut Curves and Analyze Mouse Neuts<jupyter_code>import math

import pandas as pd
import numpy as np
import seaborn as sns

import neutcurve

from plotnine import *

import csv
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.font_manager import FontProperties

import scipy.stats

from IPython.display import display, HTML
CBP = neutcurve.colorschemes.CBPALETTE
CBM = neutcurve.colorschemes.CBMARKERS
theme_set(theme_seaborn(style='white', context='talk', font_scale=1))
fidfs = {}
fidfs['rnd1'] = pd.read_csv('./fract_infect/201015_fractinfect.csv').drop(['Unnamed: 0'], axis=1)
fidfs['rnd2'] = pd.read_csv('./fract_infect/201016_fractinfect_rnd2.csv').drop(['Unnamed: 0'], axis=1)
fidfs['rnd3'] = pd.read_csv('./fract_infect/201017_fractinfect_rnd3.csv').drop(['Unnamed: 0'], axis=1)
fidfs['rnd4'] = pd.read_csv('./fract_infect/201020_fractinfect_rnd4.csv').drop(['Unnamed: 0'], axis=1)
fidfs['rnd5'] = pd.read_csv('./fract_infect/201021_fractinfect_rnd5.csv').drop(['Unnamed: 0'], axis=1)
fidfs['rnd6'] = pd.read_csv('./fract_infect/201022_fractinfect_rnd6.csv').drop(['Unnamed: 0'], axis=1)
for fidf in fidfs.keys():
    display(HTML(fidfs[fidf].head().to_html(index=False)))
smpls = {}
smpls['rnd1'] = pd.read_csv('./sample_maps/rnd1_sample_map.csv').rename(columns={'Sample': 'serum'})
smpls['rnd2'] = pd.read_csv('./sample_maps/rnd2_sample_map.csv').rename(columns={'Sample': 'serum'})
smpls['rnd3'] = pd.read_csv('./sample_maps/rnd3_sample_map.csv').rename(columns={'Sample': 'serum'})
smpls['rnd4'] = pd.read_csv('./sample_maps/rnd4_sample_map.csv').rename(columns={'Sample': 'serum'})
smpls['rnd5'] = pd.read_csv('./sample_maps/rnd5_sample_map.csv').rename(columns={'Sample': 'serum'})
smpls['rnd6'] = pd.read_csv('./sample_maps/rnd6_sample_map.csv').rename(columns={'Sample': 'serum'})
for smpl in smpls.keys():
    display(HTML(smpls[smpl].head().to_html(index=False)))<jupyter_output><empty_output><jupyter_text>Add plate number to fraction infectivity df<jupyter_code>dfs={}
for rnd in fidfs.keys():
    dfs[rnd] = fidfs[rnd].merge(smpls[rnd], how='outer', on='serum').drop(['Virus', 'PlateLayout', 'StartDil', 'DilFactor'], axis=1)
for rnd in dfs.keys():
    display(HTML(dfs[rnd].head().to_html(index=False)))<jupyter_output><empty_output><jupyter_text>Fix Plate 4 Issue for Rnd1I forgot to discard the last 30 uL from the serum dilutions in row H of plate 4 in Rnd1, so I need to drop the final dilution for all plate<jupyter_code>dfs['rnd1'].drop(dfs['rnd1'][(dfs['rnd1']['Plate']=='Plate4')&(dfs['rnd1']['concentration']==(0.05/(3**6)))].index, axis=0, inplace=True)
dfs['rnd1'] = dfs['rnd1'].sort_values(['Plate', 'SampleNum', 'replicate'])
display(HTML(dfs['rnd1'].head().to_html(index=False)))<jupyter_output><empty_output><jupyter_text>Calculate Fits using Neut CurveFor some reason must drop serum pool from rnd2.<jupyter_code>display(HTML(dfs['rnd2'][dfs['rnd2']['serum'] == '2017-2018 serum pool'].to_html(index=False)))
dfs['rnd2'] = dfs['rnd2'][dfs['rnd2']['serum'] != '2017-2018 serum pool']
fits = {}
fit_params = {}

for rnd in dfs.keys():
    fits[rnd] = neutcurve.CurveFits(dfs[rnd], fixtop=True)
    fit_params[rnd] = fits[rnd].fitParams(ics=[50, 90])
    fit_params[rnd]['nt50'] = 1/fit_params[rnd]['ic50']
    fit_params[rnd]['nt90'] = 1/fit_params[rnd]['ic90']
for rnd in fit_params.keys():
    display(HTML(fit_params[rnd].head().to_html(index=False)))<jupyter_output><empty_output><jupyter_text>Merge fit parameter data and sample data<jupyter_code>fits_dfs = {}

for rnd in fit_params.keys():
    fits_dfs[rnd] = pd.merge(fit_params[rnd], smpls[rnd], how='outer', on='serum')
    fits_dfs[rnd].drop(['PlateLayout', 'Virus', 'DilFactor', 'StartDil'], axis=1, inplace=True)
for rnd in fits_dfs.keys():
    display(HTML(fits_dfs[rnd].head().to_html(index=False)))<jupyter_output><empty_output><jupyter_text>Find any samples with interpolated IC50sNote that these samples were re-run in later rounds of neuts<jupyter_code>for rnd in fits_dfs.keys():
    print(rnd)
    display(HTML(fits_dfs[rnd][fits_dfs[rnd]['ic50_bound']=='upper'].to_html(index=False)))<jupyter_output>rnd1<jupyter_text>Plot all neut curves<jupyter_code>for rnd in fits.keys():
    fig, axes = fits[rnd].plotSera(xlabel='concentration/dilution')<jupyter_output>/home/kdusenbu/.local/lib/python3.8/site-packages/numpy/core/_asarray.py:83: UserWarning: Warning: converting a masked element to nan.
/home/kdusenbu/.local/lib/python3.8/site-packages/numpy/core/_asarray.py:83: UserWarning: Warning: converting a masked element to nan.
/home/kdusenbu/.local/lib/python3.8/site-packages/numpy/core/_asarray.py:83: UserWarning: Warning: converting a masked element to nan.<jupyter_text>Plot Ty1-Fc control neut curves<jupyter_code>curve = fits['rnd1'].getCurve(serum='Ty1-Fc', virus='S-d21-D614G', replicate='1')
print(f"The IC50 is {curve.ic50():.3g}")
fig, ax = curve.plot()
curve = fits['rnd2'].getCurve(serum='Ty1-FC', virus='S-d21-D614G', replicate='1')
print(f"The IC50 is {curve.ic50():.3g}")
fig, ax = curve.plot()
curve = fits['rnd3'].getCurve(serum='Ty1', virus='S-d21-D614G', replicate='average')
print(f"The IC50 is {curve.ic50():.3g}")
fig, ax = curve.plot()
curve = fits['rnd4'].getCurve(serum='Ty1', virus='S-d21-D614G', replicate='average')
print(f"The IC50 is {curve.ic50():.3g}")
fig, ax = curve.plot()
curve = fits['rnd5'].getCurve(serum='Ty1', virus='S-d21-D614G', replicate='average')
print(f"The IC50 is {curve.ic50():.3g}")
fig, ax = curve.plot()
curve = fits['rnd6'].getCurve(serum='Ty1-Fc', virus='S-d21-D614G', replicate='average')
print(f"The IC50 is {curve.ic50():.3g}")
fig, ax = curve.plot()
curve = fits['rnd1'].getCurve(serum='20/130 Ref', virus='S-d21-D614G', replicate='average')
print(f"The IC50 is {1/curve.ic50():.3g}")
fig, ax = curve.plot()
curve = fits['rnd3'].getCurve(serum='Ref 20/130', virus='S-d21-D614G', replicate='average')
print(f"The IC50 is {1/curve.ic50():.3g}")
fig, ax = curve.plot()
curve = fits['rnd5'].getCurve(serum='Ref 20/130', virus='S-d21-D614G', replicate='average')
print(f"The IC50 is {1/curve.ic50():.3g}")
fig, ax = curve.plot()<jupyter_output>The IC50 is 2.63e+03<jupyter_text>Combine data into one df<jupyter_code>all_data_df = pd.concat(fits_dfs)<jupyter_output><empty_output><jupyter_text>Drop Earlier Data for Samples that were re-runDrop first sample and only keep re-run for samples that were re-run.<jupyter_code>rerun = ['0829-1', '0879-1', '0858-1', '0854-1', '0856-1', '0805-1', '0818-1',
         '0817-1', '0835-1', '0873-1', '0866-1', '0824-1', '0834-1']
print(len(all_data_df))
drop_idxs = []
for sample in rerun:
    sample_data = all_data_df[all_data_df['serum']==sample]
    drop_idxs.append(sample_data['DateSetUp'].idxmin()) # drop earlier run

cleaned_data_df = all_data_df.drop(drop_idxs).reset_index(drop=True)
display(HTML(cleaned_data_df.head().to_html(index=False)))
print(len(cleaned_data_df))<jupyter_output>126<jupyter_text>Output relevant data to csvOutput columns: `serum`, `ic50`, `ic90`, `nt50`, `nt90`, `DateSetUp`, `Plate`, `SampleNum`<jupyter_code>export_df_all = all_data_df[['serum', 'ic50', 'ic90', 'nt50', 'nt90', 'DateSetUp', 'Plate', 'SampleNum']]
export_df_clean = cleaned_data_df[['serum', 'ic50', 'ic90', 'nt50', 'nt90', 'DateSetUp', 'Plate', 'SampleNum']]

# `all_neut_results` includes all neuts, including the first neuts
# from samples I reran and all controls.
export_df_all.to_csv('./all_neut_results.csv') 
# `mouse_plus_ctrls_neuts` only includes the later neuts for the
# samples I re-ran and all controls.
export_df_clean.to_csv('./mouse_plus_ctrls_neuts.csv')<jupyter_output><empty_output><jupyter_text>Initial AnalysesOnly including re-runs for samples I ran twice.Not including controls.Export csv after adding timepoint and mouse data.<jupyter_code>drop_samples = ['GF-8', 'Ref 20/130', '2017-2018 Serum Pool', '2017-2018 Pool', '20/130 Ref', '2017-2018 serum pool', 'Ty1', 'Ty1-FC', 'Ty1-Fc']
cleaned_data_df = cleaned_data_df[~cleaned_data_df['serum'].isin(drop_samples)].copy()
cleaned_data_df['Timepoint'] = cleaned_data_df['serum'].apply(lambda x: 'Prime' if '-1' in x else 'Boost')
cleaned_data_df['Mouse'] = cleaned_data_df['serum'].apply(lambda x: x[:-2])
display(HTML(cleaned_data_df.sort_values('Mouse').reset_index(drop=True).head().to_html(index=False)))
groups = {'Group 1': ['0840', '0837', '0839', '0794', '0795', '0793'], 
          'Group 2': ['0801', '0803', '0805', '0850', '0848', '0846'],
          'Group 3': ['0808', '0807', '0810', '0853', '0854', '0852'],
          'Group 4': ['0813', '0812', '0815', '0856', '0858', '0859'],
          'Group 5': ['0816', '0818', '0817', '0864', '0861', '0863'],
          'Group 6': ['0835', '0831', '0834', '0867', '0866', '0870'],
          'Group 7': ['0827', '0828', '0829', '0874', '0873', '0872'],
          'Group 8': ['0823', '0824', '0825', '0879', '0877', '0876']}
cleaned_data_df["Group"] = cleaned_data_df["Mouse"].apply(lambda x: [group for group in groups.keys() if x in groups[group]][0])
display(HTML(cleaned_data_df.head().to_html(index=False)))<jupyter_output><empty_output><jupyter_text>Export csv of cleaned mouse neut dataOnly includes latest run for samples I re-ran and doesn't include human serum (e.g. naive serum, ref serum or GF-8 sample) or Ty1-FC controls.<jupyter_code>export_df_clean_noctrls = cleaned_data_df[['serum', 'ic50', 'ic90', 'nt50', 'nt90', 'DateSetUp', 'Plate', 'SampleNum', 'Timepoint', 'Mouse', 'Group']]
# `mouse_neuts` only includes the mouse neuts (no controls) and 
# only includes the later data for the samples I re-ran
export_df_clean_noctrls.to_csv('./mouse_neuts.csv')<jupyter_output><empty_output><jupyter_text>Initial plotting<jupyter_code>group_list = ['Group 1', 'Group 2', 'Group 3', 'Group 4', 'Group 5',
              'Group 6', 'Group 7', 'Group 8']
group_cat = pd.Categorical(cleaned_data_df['Group'], categories=group_list)

tp_list = ['Prime', 'Boost']
tp_cat = pd.Categorical(cleaned_data_df['Timepoint'], categories=tp_list)

# assign to a new column in the DataFrame
cleaned_data_df = cleaned_data_df.assign(group_order = group_cat)
cleaned_data_df = cleaned_data_df.assign(timepoint_order = tp_cat)
xlabs = ['HexaPro-foldon', 'RBD trimer', 'Rpk4 trimer', 'Rpk9 trimer', 'RBD nanoparticle\nCHAPS buffer', 'RBD nanoparticle', 'Rpk4 nanoparticle', 'Rpk9 nanoparticle']

# display(cleaned_data_df.columns)

ic50s_plot = (ggplot(cleaned_data_df, aes('group_order', 'nt50', color = 'group_order')) +
              geom_boxplot(outlier_alpha=0) +
              geom_point(size=2, alpha=0.5, position=position_dodge(width=0.75)) +
              scale_color_manual(values=['#000000', CBP[0], '#44AA99', '#CC6677', '#555555', '#555555', '#225555', '#882255'], guide=False) +
              theme(axis_text_x=element_text(angle=90, vjust=1, hjust=0.5),
                    figure_size=(12, 4)) +
              facet_wrap('~ timepoint_order') +
              geom_hline(yintercept=20, color='grey', linetype='dashed') +
              scale_y_continuous(trans='log10') +
#               labs(color='Timepoint') +
              scale_x_discrete(labels=xlabs) +
              xlab('') +
              ylab('Neutralizing Titer 50')
             )
fig.tight_layout()
ic50s_plot.save('./NT50_plot.pdf')

_ = ic50s_plot.draw()<jupyter_output>/home/kdusenbu/.local/lib/python3.8/site-packages/plotnine/ggplot.py:727: PlotnineWarning: Saving 12 x 4 in image.
/home/kdusenbu/.local/lib/python3.8/site-packages/plotnine/ggplot.py:730: PlotnineWarning: Filename: ./NT50_plot.pdf<jupyter_text>Convert to Markdown<jupyter_code>!jupyter nbconvert MouseNeuts.ipynb --to markdown<jupyter_output>[NbConvertApp] Converting notebook MouseNeuts.ipynb to markdown
[NbConvertApp] Support files will be in MouseNeuts_files/
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Making directory MouseNeuts_files
[NbConvertApp] Writing 83683 bytes to MouseNeuts.md
{'fraction_non_alphanumeric': 0.17364181933038533, 'fraction_numerical': 0.057248894504106126, 'mean_word_length': 6.350551363900174, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '272372', 'license': 'MIT', 'n_tokens_mistral': 5277, 'n_tokens_neox': 4828, 'n_words': 899, 'path': 'MouseNeuts.ipynb', 'repo_name': 'jbloomlab/RBD_nanoparticle_vaccine', 'size': '12664'}