In [1]:
import pandas as pd
import numpy as np
import seaborn as sns
from matplotlib import pyplot as plt
import zlib
import xmltodict, json
from scipy import stats
from collections import namedtuple
sns.set_palette("tab10")
plt.figure(figsize=(15,10))
Out[1]:
<Figure size 1080x720 with 0 Axes>
<Figure size 1080x720 with 0 Axes>
In [2]:
def parseDataEntry(entry):
    return {y[0]: None if y[1]=="" else float(y[1]) for y in [x.replace('"', "").split('=')for x in entry.split(' ')]}
In [3]:
def importMetaSpec(filename):
    with open(filename, "rb") as f:
        data = f.read()
        xmlBytes = zlib.decompress(data[4:])
    return xmlBytes.decode()
In [4]:
def WLStoDataFrame(filename):
    data = xmltodict.parse(importMetaSpec(filename))
    scanData = data["TWLSFiles"]["subs"]["TWLSFile"]["ScanData"]['TWLSScanDatas']["subs"]["TWLSScanData"]
    scanData = [parseDataEntry(x) for x in scanData]
    df = pd.DataFrame(scanData)
    df.ScanIndex = df.ScanIndex.astype(int)
    df.ItemIndex = df.ItemIndex.astype(int)
    df.rename(columns={"WaveLength":"Wavelength"}, inplace=True)
    
    scanParams = data["TWLSFiles"]["subs"]["TWLSFile"]["ScanParam"]["TWLSParams"]["subs"]['TWLSParam']["Threshold"]['TThresholds']["subs"]['TThreshold']
    scanParams = parseDataEntry(scanParams)
    
    chartParams = data["TWLSFiles"]["subs"]["TWLSFile"]["ScanParam"]["TWLSParams"]["subs"]['TWLSParam']["ChartParam"]["TChartParams"]["subs"]['TChartParam']
    chartParams = parseDataEntry(chartParams)
    
    return df, scanParams, chartParams
In [5]:
def copyBlank(data, scanIndex, blanks):
    newBlank = data.copy()[data.ScanIndex==scanIndex]
    newBlank.ScanIndex = max(blanks.ScanIndex)+1
    return blanks.append(newBlank), data[~(data.ScanIndex==scanIndex)]
In [6]:
def labelScans(listOfLabels, df):
    scans = sorted(df.ScanIndex.unique())
    try:
        assert len(scans)==len(listOfLabels)
    except AssertionError as e:
        print(f"There are {len(listOfLabels)} labels but {len(scans)} scans to label.")
        raise e
    print(list(df.ScanIndex.unique()))
    df["Label"] = df.ScanIndex.apply(lambda i: listOfLabels[scans.index(i)])
In [7]:
blanks, scanParams, chartParams = WLStoDataFrame("./data/blanks.WLS")

noCitrate, scanParams, chartParams = WLStoDataFrame("./data/no_citrate.WLS")
blanks, noCitrate = copyBlank(noCitrate, 1, blanks)


T1_E, scanParams, chartParams = WLStoDataFrame("./data/T1_E.WLS")
T2_E, scanParams, chartParams = WLStoDataFrame("./data/T2_E.WLS")
T1_T2, scanParams, chartParams = WLStoDataFrame("./data/T1_T2.WLS")
T1_titrate, scanParams, chartParams = WLStoDataFrame("./data/T1_titrate.WLS")
T2_titrate, scanParams, chartParams = WLStoDataFrame("./data/T2_titrate.WLS")
In [8]:
plt.figure(figsize=(10,3))
ax = sns.lineplot(x=blanks.Wavelength, y=blanks.Abs, data=blanks, hue=blanks.ScanIndex, palette="tab10")
ax.set_title(f"Blanks (n={len(blanks.ScanIndex.unique())})")
ax.set_title("Blanks")
plt.savefig("./figs/blanks.png", dpi=300)
In [9]:
plt.figure(figsize=(10,5))
labelScans(["AuNP (Synthesized on 09/27/2020)", "AuNP (Synthesized on 08/13/2020)", "AuNP (Synthesized on 05/20/2020)", "AuNP (Synthesized on 09/27/2020)", "AuNP (Synthesized on 09/27/2020)", "AuNP (Synthesized on 08/13/2020)", "AuNP (Synthesized on 08/13/2020)", "AuNP (Synthesized on 05/20/2020)", "AuNP (Synthesized on 05/20/2020)", "T1 aptamer no salt", "T1 aptamer no salt"], noCitrate)
ax = sns.lineplot(x=noCitrate.Wavelength, y=noCitrate.Abs, data=noCitrate, hue=noCitrate.Label, palette="tab10")
ax.set_title("AuNP Absorbtions")
plt.savefig("./figs/aunps.png", dpi=300)
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
In [22]:
plt.figure(figsize=(10,5))
labelScans(["T1 no NaCl", "T2 no NaCl", "T1 NaCl", "T2 NaCl"], T1_T2)
ax = sns.lineplot(x=T1_T2.Wavelength, y=T1_T2.Abs, data=T1_T2, hue=T1_T2.Label, palette="tab10")
ax.set_title("PG13T1, PG13T2 Coated AuNPs With and Without NaCl")
plt.savefig("./figs/NaCl.png", dpi=300)
[1, 2, 3, 4]
In [24]:
plt.figure(figsize=(5,3))
labelScans(["0X", "5X", "10X", "15X",
            "50X", "100X", "500X", "1000X"], T1_titrate)
ax = sns.lineplot(x=T1_titrate.Wavelength, y=T1_titrate.Abs, data=T1_titrate, hue=T1_titrate.Label, palette="rocket_r")
ax.set_title("PG13T1 P4")
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), ncol=1)
plt.savefig("./figs/P4T1.png", dpi=300, bbox_inches='tight')
[1, 2, 3, 4, 5, 6, 7, 8]
In [25]:
def getByLabelAtWavelengths(inputDf, wavelengths):
    dfs = []
    display(inputDf)
    for wavelength in wavelengths:
        df = inputDf[inputDf.Wavelength==wavelength][["Abs", "Label"]].T
        df.columns = df.loc["Label"]
        df.drop("Label", inplace=True)
        df.rename({"Abs":wavelength}, inplace=True)
        dfs.append(df)
    df = dfs[0]
    for i in range(1, len(dfs)):
        df = df.append(dfs[i])
    return df
'''
df = getByLabelAtWavelengths(T1_titrate, [523, 625]).T
df["625/523"] = (df[625]/df[523]).astype(float)
df["uL Added"] = list(map(lambda x: int(x.replace("uL", "").replace("T1 +","")), df.index))
df["uL Added"] = df["uL Added"].astype(int)
display(df)
'''
Out[25]:
'\ndf = getByLabelAtWavelengths(T1_titrate, [523, 625]).T\ndf["625/523"] = (df[625]/df[523]).astype(float)\ndf["uL Added"] = list(map(lambda x: int(x.replace("uL", "").replace("T1 +","")), df.index))\ndf["uL Added"] = df["uL Added"].astype(int)\ndisplay(df)\n'
In [26]:
def getRatioDf(dff, label1, label2):
    df = getByLabelAtWavelengths(dff, [523, 625]).T
    df["625/523"] = (df[625]/df[523]).astype(float)
    df["uL Added"] = list(map(lambda x: int(x.replace(label1, "").replace(label2,"")), df.index))
    df["uL Added"] = df["uL Added"].astype(int)
    return df
In [27]:
T1_ratios = getRatioDf(T1_titrate, "", "X")
T1_ratios
plt.figure(figsize=(15,10))
ax = sns.regplot(x="uL Added", y="625/523", data=T1_ratios)
ax = sns.regplot(x="uL Added", y="625/523", data=T1_ratios.loc["0X":"100X"])
ax.set_title("T1 P4 Dilutions")
plt.savefig("./figs/P4T1_line.png", dpi=300)
ScanIndexItemIndexWavelengthAbsTransEnergyConcPVProItemMarkBrightEnergyDarkEnergyAmpLabel
011625.01.78341.64680.00.00.0None35431.0151.03.00X
112624.01.78331.64690.00.00.0None35491.0151.03.00X
213623.01.78351.64630.00.00.0None35563.0151.03.00X
314622.01.78441.64290.00.00.0None35637.0151.03.00X
415621.01.78461.64200.00.00.0None35717.0151.03.00X
..........................................
14038172454.01.42063.79650.00.00.0None14006.0151.03.01000X
14048173453.01.42153.78880.00.00.0None13770.0151.03.01000X
14058174452.01.42163.78750.00.00.0None13537.0151.03.01000X
14068175451.01.42333.77270.00.00.0None13298.0151.03.01000X
14078176450.01.42413.76600.00.00.0None13056.0151.03.01000X

1408 rows × 13 columns

In [28]:
plt.figure(figsize=(5,3))
labelScans(["0X", "5X", "10X", "15X",
            "50X", "100X", "500X", "1000X"], T2_titrate)
ax = sns.lineplot(x=T2_titrate.Wavelength, y=T2_titrate.Abs, data=T2_titrate, hue=T2_titrate.Label, palette="rocket_r")
ax.set_title("PG13T2 P4")
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), ncol=1)
plt.savefig("./figs/P4T2.png", dpi=300, bbox_inches='tight')
[1, 2, 3, 4, 5, 6, 7, 8]
In [29]:
T2_ratios = getRatioDf(T2_titrate, "", "X")
T2_ratios
plt.figure(figsize=(15,10))
ax = sns.regplot(x="uL Added", y="625/523", data=T2_ratios)
ax = sns.regplot(x="uL Added", y="625/523", data=T2_ratios.loc["0X":"100X"])
ax.set_title("T2 P4 Dilutions")
plt.savefig("./figs/P4T2_line.png", dpi=300)
ScanIndexItemIndexWavelengthAbsTransEnergyConcPVProItemMarkBrightEnergyDarkEnergyAmpLabel
011625.01.96471.08480.00.00.0None35180.0151.03.00X
112624.01.96321.08850.00.00.0None35246.0151.03.00X
213623.01.96431.08560.00.00.0None35339.0151.03.00X
314622.01.96431.08570.00.00.0None35427.0151.03.00X
415621.01.96431.08580.00.00.0None35516.0151.03.00X
..........................................
14038172454.01.51883.02830.00.00.0None13921.0151.03.01000X
14048173453.01.51853.03010.00.00.0None13682.0151.03.01000X
14058174452.01.51973.02230.00.00.0None13452.0151.03.01000X
14068175451.01.51933.02450.00.00.0None13211.0151.03.01000X
14078176450.01.52123.01160.00.00.0None12968.0151.03.01000X

1408 rows × 13 columns

In [31]:
plt.figure(figsize=(5,3))
labelScans(["0X", "5X", "10X", "15X",
            "50X", "100X", "500X", "1000X"], T1_E)
ax = sns.lineplot(x=T1_E.Wavelength, y=T1_E.Abs, data=T1_E, hue=T1_E.Label, palette="tab10")
ax.set_title("PG13T1 E2")
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), ncol=1)
plt.savefig("./figs/E2T1.png", dpi=300, bbox_inches='tight')
[1, 2, 3, 4, 5, 6, 7, 8]
In [32]:
E2T1_ratios = getRatioDf(T1_E, "", "X")
E2T1_ratios
plt.figure(figsize=(15,10))
ax = sns.regplot(x="uL Added", y="625/523", data=E2T1_ratios)
ax = sns.regplot(x="uL Added", y="625/523", data=E2T1_ratios.loc["0X":"100X"])
ax.set_title("T1 E2 Dilutions")
plt.savefig("./figs/E2T1_line.png", dpi=300)
ScanIndexItemIndexWavelengthAbsTransEnergyConcPVProItemMarkBrightEnergyDarkEnergyAmpLabel
011625.01.77371.68380.00.00.0None35190.0151.03.00X
112624.01.77361.68430.00.00.0None35240.0151.03.00X
213623.01.77381.68330.00.00.0None35319.0151.03.00X
314622.01.77411.68240.00.00.0None35399.0151.03.00X
415621.01.77461.68050.00.00.0None35497.0151.03.00X
..........................................
14038172454.01.40493.93680.00.00.0None13944.0151.03.01000X
14048173453.01.40643.92300.00.00.0None13712.0151.03.01000X
14058174452.01.40613.92550.00.00.0None13474.0151.03.01000X
14068175451.01.40753.91290.00.00.0None13236.0151.03.01000X
14078176450.01.40973.89320.00.00.0None12994.0151.03.01000X

1408 rows × 13 columns

In [33]:
plt.figure(figsize=(5,3))
labelScans(["0X", "5X", "10X", "15X",
            "50X", "100X", "500X", "1000X"], T2_E)
ax = sns.lineplot(x=T2_E.Wavelength, y=T2_E.Abs, data=T2_E, hue=T2_E.Label, palette="tab10")
ax.set_title("PG13T2 E2")
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), ncol=1)
plt.savefig("./figs/E2T2.png", dpi=300, bbox_inches='tight')
[1, 2, 3, 4, 5, 6, 7, 8]
In [34]:
E2T2_ratios = getRatioDf(T2_E, "", "X")
E2T2_ratios
plt.figure(figsize=(15,10))
ax = sns.regplot(x="uL Added", y="625/523", data=E2T2_ratios)
ax = sns.regplot(x="uL Added", y="625/523", data=E2T2_ratios.loc["T2 +0 uL E2":"T2 + 100 uL E2"])
ax.set_title("T2 E2 Dilutions")
plt.savefig("./figs/E2T2_line.png", dpi=300)
ScanIndexItemIndexWavelengthAbsTransEnergyConcPVProItemMarkBrightEnergyDarkEnergyAmpLabel
011625.01.79971.58590.00.00.0None35209.0151.03.00X
112624.01.80041.58330.00.00.0None35268.0151.03.00X
213623.01.80001.58500.00.00.0None35356.0151.03.00X
314622.01.80101.58110.00.00.0None35442.0151.03.00X
415621.01.80051.58290.00.00.0None35528.0151.03.00X
..........................................
14038172454.01.40433.94170.00.00.0None13952.0151.03.01000X
14048173453.01.40513.93460.00.00.0None13723.0151.03.01000X
14058174452.01.40553.93130.00.00.0None13480.0151.03.01000X
14068175451.01.40773.91080.00.00.0None13243.0151.03.01000X
14078176450.01.40823.90630.00.00.0None13002.0151.03.01000X

1408 rows × 13 columns

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~/.local/lib/python3.8/site-packages/pandas/core/indexes/base.py in get_slice_bound(self, label, side, kind)
   4843             try:
-> 4844                 return self._searchsorted_monotonic(label, side)
   4845             except ValueError:

~/.local/lib/python3.8/site-packages/pandas/core/indexes/base.py in _searchsorted_monotonic(self, label, side)
   4804 
-> 4805         raise ValueError("index must be monotonic increasing or decreasing")
   4806 

ValueError: index must be monotonic increasing or decreasing

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
<ipython-input-34-294599a2504d> in <module>
      3 plt.figure(figsize=(15,10))
      4 ax = sns.regplot(x="uL Added", y="625/523", data=E2T2_ratios)
----> 5 ax = sns.regplot(x="uL Added", y="625/523", data=E2T2_ratios.loc["T2 +0 uL E2":"T2 + 100 uL E2"])
      6 ax.set_title("T2 E2 Dilutions")
      7 plt.savefig("./figs/E2T2_line.png", dpi=300)

~/.local/lib/python3.8/site-packages/pandas/core/indexing.py in __getitem__(self, key)
   1766 
   1767             maybe_callable = com.apply_if_callable(key, self.obj)
-> 1768             return self._getitem_axis(maybe_callable, axis=axis)
   1769 
   1770     def _is_scalar_access(self, key: Tuple):

~/.local/lib/python3.8/site-packages/pandas/core/indexing.py in _getitem_axis(self, key, axis)
   1910         if isinstance(key, slice):
   1911             self._validate_key(key, axis)
-> 1912             return self._get_slice_axis(key, axis=axis)
   1913         elif com.is_bool_indexer(key):
   1914             return self._getbool_axis(key, axis=axis)

~/.local/lib/python3.8/site-packages/pandas/core/indexing.py in _get_slice_axis(self, slice_obj, axis)
   1794 
   1795         labels = obj._get_axis(axis)
-> 1796         indexer = labels.slice_indexer(
   1797             slice_obj.start, slice_obj.stop, slice_obj.step, kind=self.name
   1798         )

~/.local/lib/python3.8/site-packages/pandas/core/indexes/base.py in slice_indexer(self, start, end, step, kind)
   4710         slice(1, 3)
   4711         """
-> 4712         start_slice, end_slice = self.slice_locs(start, end, step=step, kind=kind)
   4713 
   4714         # return a slice

~/.local/lib/python3.8/site-packages/pandas/core/indexes/base.py in slice_locs(self, start, end, step, kind)
   4923         start_slice = None
   4924         if start is not None:
-> 4925             start_slice = self.get_slice_bound(start, "left", kind)
   4926         if start_slice is None:
   4927             start_slice = 0

~/.local/lib/python3.8/site-packages/pandas/core/indexes/base.py in get_slice_bound(self, label, side, kind)
   4845             except ValueError:
   4846                 # raise the original KeyError
-> 4847                 raise err
   4848 
   4849         if isinstance(slc, np.ndarray):

~/.local/lib/python3.8/site-packages/pandas/core/indexes/base.py in get_slice_bound(self, label, side, kind)
   4839         # we need to look up the label
   4840         try:
-> 4841             slc = self.get_loc(label)
   4842         except KeyError as err:
   4843             try:

~/.local/lib/python3.8/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   2646                 return self._engine.get_loc(key)
   2647             except KeyError:
-> 2648                 return self._engine.get_loc(self._maybe_cast_indexer(key))
   2649         indexer = self.get_indexer([key], method=method, tolerance=tolerance)
   2650         if indexer.ndim > 1 or indexer.size > 1:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'T2 +0 uL E2'
In [35]:
ratios = [x.copy() for x in [E2T1_ratios, E2T2_ratios, T1_ratios, T2_ratios]]
In [36]:
aunpConc = [3/(3+(x/1000)) for x in [0,5,10,15,50,100,500,1000]]
for r in ratios:
    r["AuNP Conc"] = aunpConc
    r["523 (adj.)"] = (r[523]/r["AuNP Conc"]).astype(float)
    r["625 (adj.)"] = (r[625]/r["AuNP Conc"]).astype(float)
    r["523/625 (adj.)"] = (r[523]/r[625]).astype(float)
    r["625/523 (adj.)"] = (r[523]/r[625]).astype(float)
    
    r["523/625 (adj.)"] = r["523/625 (adj.)"]-r.iloc[0]["523/625 (adj.)"]
In [37]:
for r in ratios[0:2]:
    #https://www.wolframalpha.com/input/?i=(0.0041g-0.0015g)*(356.5g%2Fmol)^-1*(10%2F1500)(10%2F1500)(10%2F1500)(580%2F1000)(100%2F1000)*1.5mL
    r["E2 Conc (pM)"] = [(0.41725*x)/(3+(x/1000)) for x in [0,5,10,15,50,100,500,1000]]
    r["E2 Conc (pM)"] = r["E2 Conc (pM)"].astype(float)
    r["Titrant"]="E2"
for r in ratios[2:]:
    #https://www.wolframalpha.com/input/?i=((1g%2F70mg*314g%2Fmol)^-1*4mg%2F1mL*10^-8)*5uL+to+fmol = 0.04459fmol
    r["P4 Conc (pM)"] = [(0.04459*x)/(3+(x/1000)) for x in [0,5,10,15,50,100,500,1000]]
    r["P4 Conc (pM)"] = r["P4 Conc (pM)"].astype(float)
    r["Titrant"]="P4"
In [38]:
for r in ratios:
    display(r)
523625625/523uL AddedAuNP Conc523 (adj.)625 (adj.)523/625 (adj.)625/523 (adj.)E2 Conc (pM)Titrant
Label
0X2.92341.77370.60672501.0000002.9234001.7737000.0000001.6481930.000000E2
5X2.92341.77150.60597250.9983362.9282721.7744520.0020471.6502400.694260E2
10X2.92341.76640.604228100.9966782.9331451.7722880.0068111.6550051.386213E2
15X2.92341.76210.602757150.9950252.9380171.7709110.0108501.6590432.075871E2
50X2.86551.73840.606666500.9836072.9132581.7673730.0001621.6483556.840164E2
100X2.81421.70320.6052161000.9677422.9080071.7599730.0041091.65230213.459677E2
500X2.45681.53170.6234535000.8571432.8662671.786983-0.0442241.60396959.607143E2
1000X2.13011.34920.63339710000.7500002.8401331.798933-0.0694061.578787104.312500E2
523625625/523uL AddedAuNP Conc523 (adj.)625 (adj.)523/625 (adj.)625/523 (adj.)E2 Conc (pM)Titrant
Label
0X2.92371.79970.61555601.0000002.9237001.7997000.0000001.6245490.000000E2
5X2.86581.78970.62450350.9983362.8705761.792683-0.0232751.6012740.694260E2
10X2.89381.7920.619255100.9966782.9034461.797973-0.0097051.6148441.386213E2
15X2.86581.77760.620281150.9950252.8801291.786488-0.0123751.6121742.075871E2
50X2.81471.76090.625608500.9836072.8616121.790248-0.0261051.5984446.840164E2
100X2.7691.72390.6225711000.9677422.8613001.781363-0.0183071.60624213.459677E2
500X2.40721.53620.6381695000.8571432.8084001.792233-0.0575651.56698359.607143E2
1000X2.09231.34970.64508010000.7500002.7897331.799600-0.0743521.550196104.312500E2
523625625/523uL AddedAuNP Conc523 (adj.)625 (adj.)523/625 (adj.)625/523 (adj.)P4 Conc (pM)Titrant
Label
0X2.65661.78340.67130901.0000002.6566001.7834000.0000001.4896270.000000P4
5X2.65661.77740.66905150.9983362.6610281.7803620.0050291.4946550.074193P4
10X2.64021.77810.673472100.9966782.6490011.784027-0.0047831.4848430.148140P4
15X2.64021.77520.672373150.9950252.6534011.784076-0.0023581.4872690.221841P4
50X2.62451.75940.670375500.9836072.6682421.7887230.0020751.4917020.730984P4
100X2.59451.730.6667951000.9677422.6809831.7876670.0100841.4997111.438387P4
500X2.38141.55940.6548255000.8571432.7783001.8193000.0374991.5271266.370000P4
1000X2.10781.37350.65162710000.7500002.8104001.8313330.0449931.53462011.147500P4
523625625/523uL AddedAuNP Conc523 (adj.)625 (adj.)523/625 (adj.)625/523 (adj.)P4 Conc (pM)Titrant
Label
0X2.81361.96470.69828701.0000002.8136001.9647000.0000001.4320760.000000P4
5X2.81361.95790.69587050.9983362.8182891.9611630.0049741.4370500.074193P4
10X2.81361.95450.694662100.9966782.8229791.9610150.0074741.4395500.148140P4
15X2.81361.94780.692280150.9950252.8276681.9575390.0124251.4445010.221841P4
50X2.81361.92430.683928500.9836072.8604931.9563720.0300661.4621420.730984P4
100X2.76781.88830.6822391000.9677422.8600601.9512430.0336871.4657631.438387P4
500X2.53731.69930.6697285000.8571432.9601831.9825170.0610681.4931446.370000P4
1000X2.231.48870.66757810000.7500002.9733331.9849330.0658751.49795111.147500P4
In [39]:
for r in ratios[0:2]:
    r["P4 Conc (pM)"] = 0
for r in ratios[2:]:
    r["E2 Conc (pM)"] = 0
In [40]:
ratios[0]["Aptamer"] = "T1"
ratios[2]["Aptamer"] = "T1"
ratios[1]["Aptamer"] = "T2"
ratios[3]["Aptamer"] = "T2"
In [41]:
df = ratios[0]
for r in ratios[1:]:
    df = df.append(r)
df.index = df.Aptamer+df.Titrant#+df["uL Added"].astype(str)
df
Out[41]:
523625625/523uL AddedAuNP Conc523 (adj.)625 (adj.)523/625 (adj.)625/523 (adj.)E2 Conc (pM)TitrantP4 Conc (pM)Aptamer
T1E22.92341.77370.60672501.0000002.9234001.7737000.0000001.6481930.000000E20.000000T1
T1E22.92341.77150.60597250.9983362.9282721.7744520.0020471.6502400.694260E20.000000T1
T1E22.92341.76640.604228100.9966782.9331451.7722880.0068111.6550051.386213E20.000000T1
T1E22.92341.76210.602757150.9950252.9380171.7709110.0108501.6590432.075871E20.000000T1
T1E22.86551.73840.606666500.9836072.9132581.7673730.0001621.6483556.840164E20.000000T1
T1E22.81421.70320.6052161000.9677422.9080071.7599730.0041091.65230213.459677E20.000000T1
T1E22.45681.53170.6234535000.8571432.8662671.786983-0.0442241.60396959.607143E20.000000T1
T1E22.13011.34920.63339710000.7500002.8401331.798933-0.0694061.578787104.312500E20.000000T1
T2E22.92371.79970.61555601.0000002.9237001.7997000.0000001.6245490.000000E20.000000T2
T2E22.86581.78970.62450350.9983362.8705761.792683-0.0232751.6012740.694260E20.000000T2
T2E22.89381.7920.619255100.9966782.9034461.797973-0.0097051.6148441.386213E20.000000T2
T2E22.86581.77760.620281150.9950252.8801291.786488-0.0123751.6121742.075871E20.000000T2
T2E22.81471.76090.625608500.9836072.8616121.790248-0.0261051.5984446.840164E20.000000T2
T2E22.7691.72390.6225711000.9677422.8613001.781363-0.0183071.60624213.459677E20.000000T2
T2E22.40721.53620.6381695000.8571432.8084001.792233-0.0575651.56698359.607143E20.000000T2
T2E22.09231.34970.64508010000.7500002.7897331.799600-0.0743521.550196104.312500E20.000000T2
T1P42.65661.78340.67130901.0000002.6566001.7834000.0000001.4896270.000000P40.000000T1
T1P42.65661.77740.66905150.9983362.6610281.7803620.0050291.4946550.000000P40.074193T1
T1P42.64021.77810.673472100.9966782.6490011.784027-0.0047831.4848430.000000P40.148140T1
T1P42.64021.77520.672373150.9950252.6534011.784076-0.0023581.4872690.000000P40.221841T1
T1P42.62451.75940.670375500.9836072.6682421.7887230.0020751.4917020.000000P40.730984T1
T1P42.59451.730.6667951000.9677422.6809831.7876670.0100841.4997110.000000P41.438387T1
T1P42.38141.55940.6548255000.8571432.7783001.8193000.0374991.5271260.000000P46.370000T1
T1P42.10781.37350.65162710000.7500002.8104001.8313330.0449931.5346200.000000P411.147500T1
T2P42.81361.96470.69828701.0000002.8136001.9647000.0000001.4320760.000000P40.000000T2
T2P42.81361.95790.69587050.9983362.8182891.9611630.0049741.4370500.000000P40.074193T2
T2P42.81361.95450.694662100.9966782.8229791.9610150.0074741.4395500.000000P40.148140T2
T2P42.81361.94780.692280150.9950252.8276681.9575390.0124251.4445010.000000P40.221841T2
T2P42.81361.92430.683928500.9836072.8604931.9563720.0300661.4621420.000000P40.730984T2
T2P42.76781.88830.6822391000.9677422.8600601.9512430.0336871.4657630.000000P41.438387T2
T2P42.53731.69930.6697285000.8571432.9601831.9825170.0610681.4931440.000000P46.370000T2
T2P42.231.48870.66757810000.7500002.9733331.9849330.0658751.4979510.000000P411.147500T2
In [42]:
df = df[df["uL Added"]<600]
In [43]:
def getfit(X,Y,df):
    y=df[Y]
    x=df[X]
    values = ["slope", "intercept", "r", "pvalue", "stderr"]
    Fit = namedtuple("Fit", values)
    return Fit(*list(stats.linregress(x,y)))
#getfit("x", "y", pd.DataFrame({"x":[1,2,3], "y":[2,3,4]}))
In [47]:
fig, ax = plt.subplots(nrows=2, ncols=2)
fig.set_size_inches(11, 4, forward=True)

tests = list(set(df.index))
display(list(enumerate(tests)))
for i, row in enumerate(ax):
    for j, col in enumerate(row):
        l = {0:{0:2, 1:1}, 1:{0:0, 1:3}}[i][j]
        dff = df.loc[tests[l]]
        x=dff.iloc[0]["Titrant"]+" Conc (pM)"
        y="523/625 (adj.)"
        sns.regplot(x=dff.iloc[0]["Titrant"]+" Conc (pM)", y="523/625 (adj.)", data=dff, ax=col)
        if i==0: col.set_xlabel("")
        if j==1: col.set_ylabel("")
        col.set_ylim(-0.1,0.1)
        fit = getfit(x,y,dff)
        lod = getfit(y,x,dff).stderr * 0.001 * 3.3
        col.set_title(tests[l][0:2].replace("T", "PG13T") + " Coated AuNPs Titrated with " + tests[l][2:], fontsize=14)
        col.text(0.01, 0.99, 
                 f"R$^2$={round(fit.r**2,3)}, Slope={str(round(fit.slope*10**4,5))}E-4, LOD: {round(lod*10,2)}E-1 nM", 
                 fontsize=12,
                 horizontalalignment='left',verticalalignment='top', transform=col.transAxes)
print("Titrations of P4/E2 in AuNP Solutions doped with T1 or T2 Aptamers")
fig.tight_layout()
plt.savefig("./figs/final-fig.png", dpi=300, transparent=True)
[(0, 'T1P4'), (1, 'T1E2'), (2, 'T2E2'), (3, 'T2P4')]
Titrations of P4/E2 in AuNP Solutions doped with T1 or T2 Aptamers
In [ ]: