In [1]:
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from IPython.display import display, Math, Latex #Do we even need this anymore?
%pylab inline
This is a simple model of our system.
We are assuming complex concentration [PL] is proportional to complex fluorescence (in this particular assay).
We estimate/know the total Ligand $[L]_{tot} = [L] + [PL]$ and Protein $[P]_{tot} = [P] + [PL]$ concentration from the experimental setup, and presume we can measure the complex concentration in some way $[PL]$.
From this relation can calculate $K_d$ from these three values.
What binding curve would we expect?
In [2]:
Kd = 2e-9 # M
The protein concentration for our assay will be 1 nM (half of the Kd).
In [3]:
Ptot = 1e-9 # M
The ligand concentration will be a 12-point half-log dilution from 20 uM ligand (down to ~60 pM).
In [4]:
Ltot = 20.0e-6 / np.array([10**(float(i)/2.0) for i in range(12)]) # M
To calculate $[PL]$ as a function of $[P]_{tot}$, $[L]_{tot}$, and $K_d$, we start with
Then we need to put L and P in terms of $[L]_{tot}$ and $[P]_{tot}$, using
This gives us:
Rearranging to form a quadratic equations, we get:
Using the solution for the quadratic equation:
where $x = [PL]$, $a = 1$, $b = -([P]_{tot}+[L]_{tot}+K_d)$, and $c = [P]_{tot} [L]_{tot}$. We get as the only reasonable solution:
In [5]:
# Now we can use this to define a function that gives us PL from Kd, Ptot, and Ltot.
def two_component_binding(Kd, Ptot, Ltot):
"""
Parameters
----------
Kd : float
Dissociation constant
Ptot : float
Total protein concentration
Ltot : float
Total ligand concentration
Returns
-------
P : float
Free protein concentration
L : float
Free ligand concentration
PL : float
Complex concentration
"""
PL = 0.5 * ((Ptot + Ltot + Kd) - np.sqrt((Ptot + Ltot + Kd)**2 - 4*Ptot*Ltot)) # complex concentration (uM)
P = Ptot - PL; # free protein concentration in sample cell after n injections (uM)
L = Ltot - PL; # free ligand concentration in sample cell after n injections (uM)
return [P, L, PL]
In [6]:
[L, P, PL] = two_component_binding(Kd, Ptot, Ltot)
In [7]:
print Ltot
In [8]:
print PL
In [9]:
# y will be complex concentration
# x will be total ligand concentration
plt.semilogx(Ltot, PL, 'ko')
plt.xlabel('$[L]_{tot}$ / M')
plt.ylabel('$[PL]$')
plt.ylim(0, 1.05*np.max(PL))
plt.axvline(Kd,color='r',linestyle='--',label='K_d')
plt.legend(loc=0);
Okay, so now lets do something a little more fun.
In [10]:
[L2, P2, PL2] = two_component_binding(Kd, Ptot/2, Ltot)
[L3, P3, PL3] = two_component_binding(Kd, Ptot*2, Ltot)
In [11]:
# y will be complex concentration
# x will be total ligand concentration
plt.semilogx(Ltot,PL,'b',Ltot,PL2,'g',Ltot,PL3,'k')
plt.xlabel('$[L]_{tot}$ / M')
plt.ylabel('$[PL]$ / M')
plt.ylim(0,2.05e-9)
plt.axhline(Ptot,color='b',linestyle='--',label='$[P]_{tot}$')
plt.axhline(Ptot/2,color='g',linestyle='--',label='$[P]_{tot}$/2')
plt.axhline(Ptot*2,color='k',linestyle='--', label='$[P]_{tot}$*2')
plt.axvline(Kd,color='r',linestyle='--',label='$K_d$')
plt.legend();
Say we have one molecule that has a different Kd for a bunch of proteins. We'll keep the protein concentration the same, but look at how our complex concentration changes as a function of Kd.
In [12]:
[L4, P4, PL4] = two_component_binding(Kd/10, Ptot, Ltot)
[L5, P5, PL5] = two_component_binding(Kd*10, Ptot, Ltot)
In [13]:
# y will be complex concentration
# x will be total ligand concentration
plt.semilogx(Ltot,PL,'o',label='$K_d$');
plt.semilogx(Ltot,PL4,'violet',label='0.1 $K_d$');
plt.semilogx(Ltot,PL5,'.75',label='10 $K_d$')
plt.xlabel('$[L]_{tot} / M$')
plt.ylabel('$[PL]$ / M')
plt.ylim(0,1.05e-9)
plt.axhline(Ptot,color='0.75',linestyle='--',label='$[P]_{tot}$')
#plt.axvline(Kd/10,color='violet',label='Kd/10')
#plt.axvline(Kd*10,color='.75',label='Kd*10')
plt.axvline(Kd,color='r',linestyle='--',label='$K_d$')
plt.legend();
In [14]:
# Let's plot Kd's ranging from 1mM to 10pM
Kd_max = 1e-3 # M
In [15]:
[La, Pa, PLa] = two_component_binding(Kd_max, Ptot, Ltot)
[Lb, Pb, PLb] = two_component_binding(Kd_max/10, Ptot, Ltot)
[Lc, Pc, PLc] = two_component_binding(Kd_max/100, Ptot, Ltot)
[Ld, Pd, PLd] = two_component_binding(Kd_max/1e3, Ptot, Ltot)
[Le, Pe, PLe] = two_component_binding(Kd_max/1e4, Ptot, Ltot)
[Lf, Pf, PLf] = two_component_binding(Kd_max/1e5, Ptot, Ltot)
[Lg, Pg, PLg] = two_component_binding(Kd_max/1e6, Ptot, Ltot)
[Lh, Ph, PLh] = two_component_binding(Kd_max/1e7, Ptot, Ltot)
[Li, Pi, PLi] = two_component_binding(Kd_max/1e8, Ptot, Ltot)
[Lj, Pj, PLj] = two_component_binding(Kd_max/1e9, Ptot, Ltot)
In [16]:
# y will be complex concentration
# x will be total ligand concentration
plt.figure(figsize=(10,3))
plt.semilogx(Ltot,PLa,'-bo',label='1 mM');
plt.semilogx(Ltot,PLb,'-ko',label='100 $\mu$M');
plt.semilogx(Ltot,PLc,'-go',label='10 $\mu$M');
plt.semilogx(Ltot,PLd,'-ro',label='1 $\mu$M');
plt.semilogx(Ltot,PLe,'-co',label='100 nM');
plt.semilogx(Ltot,PLf,'-mo',label='10 nM');
plt.semilogx(Ltot,PLg,'-yo',label='1 nM');
plt.semilogx(Ltot,PLh,'-bo',label='100 pM');
plt.semilogx(Ltot,PLi,'-ko',label='10 pM');
plt.semilogx(Ltot,PLj,'-go',label='1 pM');
plt.xlabel('$[L]_{tot}$ / M')
plt.ylabel('$[PL]$ / M')
plt.xlim(1.5e-12,1.5e-4)
plt.axhline(0.1e-9,color='0.75',linestyle='--',label='detection limit');
plt.legend(loc=0);
In [ ]:
We're going to pick 10 kinases and look at what binding curves we would expect to the fluorescent inhibitor bosutinib. Info from: http://www.guidetopharmacology.org/GRAC/LigandDisplayForward?tab=screens&ligandId=5710 Specifically: http://www.guidetopharmacology.org/GRAC/LigandScreenDisplayForward?ligandId=5710&screenId=2
In [17]:
Kd_Src = 1.0e-9 # M
Kd_Abl = 0.12e-9 # M
Kd_Abl_T315I = 21.0e-9 # M
Kd_p38 = 3000.0e-9 # M
Kd_Aur = 3000.0e-9 # M
Kd_CK2 = 3000.0e-9 # M
Kd_SYK = 290.0e-9 # M
Kd_DDR = 120.0e-9 # M
Kd_MEK = 19.0e-9 # M
#This CK2, Aur, and p38 value is actually 'greater than'.
In [18]:
[L6, P6, PL6] = two_component_binding(Kd_Src, Ptot, Ltot)
[L7, P7, PL7] = two_component_binding(Kd_Abl, Ptot, Ltot)
[L8, P8, PL8] = two_component_binding(Kd_Abl_T315I, Ptot, Ltot)
[L9, P9, PL9] = two_component_binding(Kd_p38, Ptot, Ltot)
In [19]:
# y will be complex concentration
# x will be total ligand concentration
Src, = plt.semilogx(Ltot,PL6,'o', label='Src')
Abl, = plt.semilogx(Ltot,PL7,'violet', label = 'Abl')
AblGK, = plt.semilogx(Ltot,PL8,'.75', label = 'AblGK')
p38, = plt.semilogx(Ltot,PL9,'k', label = 'p38')
plt.axhline(0.1e-9,color='0.75',linestyle='--', label='detection limit');
plt.xlabel('$[L]_{tot}$')
plt.ylabel('$[PL]$')
#plt.legend(handles=[Src, Abl, AblGK, p38], loc =0);
plt.legend(loc=0);
In [ ]: