An Online Calculator to perform the calculations described in this document

Source Code for the online calculator

In [1]:
# Initialize
import numpy as np
import scipy.constants as const

Conditions in the CK Clamp

This section sets up the variables used in the CK Clamp.

Temperature

In [2]:
# Temperature of the assay
temp37 = 273.15 + 37

Mg

In [3]:
# Free Magnesium [M]
# Measured with Magnesium Green at each titration setp
freeMg = [
    0.000407972,
    0.000395923,
    0.000377038,
    0.000364626,
    0.0003487,
    0.00033737,
    0.000323291,
    0.000309397,
    0.000299109,
    0.000292253,
    0.000281548,
]

Phosphate

In [4]:
phosphate = 0.010

pH

In [5]:
pH = 7.1

Ionic Strength

Ionic Composition of Assay Buffer

Salt [M]
K-MES 0.105
KCl 0.030
KH₂PO₄ 0.010
MgCl₂ 0.005
EGTA K₂ 0.001

pH 7.1 at 37°C

Ionic Strength is defined as:

$$ \begin{equation} \frac{1}{2} \sum_{i=1}^n M_i \times z^2_i \end{equation} $$

Where $M_i$ is the Molarity of the individual ion

This system is buffered at a specific pH and contains a few weak acids (H₂PO₄, EGTA K₄, K-MES). Therefore, in addition to their concentration, we need to consider the percent ionization of each species.

EGTA

J. P. Y. Kao, G. Li, and D. A. Auston, “Chapter 5 - Practical Aspects of Measuring Intracellular Calcium Signals with Fluorescent Indicators,” in Methods in Cell Biology, vol. 99, Supplement C vols., M. Whitaker, Ed. Academic Press, 2010, pp. 113–152.

From Figure 7 of the above citation, we know that at pH 7.1, ~99% of the EGTA is H2EGTA2- . Therefore, we will make the approximation that the added ionic strenght comes from K2EGTA

For the following two ions, the pKa were obtained from the online calculator http://www.reachdevices.com/Protein/BiologicalBuffers.html

H₂PO₄

The pKa of 10 mM H2PO4 is 7. To determine the ion concentrations, we will use the Henderson–Hasselbalch equation:

$$\text{pH} = \text{pKa} + \log\frac{\text{H}\text{PO}_4^{2-}}{\text{H}_2\text{PO}_4^{1-}}$$

Doing this, we find that ~45% of the acid is H₂PO₄1- and ~55% is HPO₄2-

MES

The pKa of of 105 mM MES is 6. Again, using the H-H equation, we find that ~92% of the MES is in the ionic (deprotonated) form

Using this information, the basal ionic strength of our buffer is calculated to be 0.168 M

Ionic Strength Over the CK Clamp

The salts utilized in the CK Clamp have the following stoichiometry and charge

$$\text{PCr}^{-2} \cdot \text{Tris}^{+1}_2$$$$\text{ATP}^{-4} \cdot \text{Tris}^{+1}_2$$

The following is an extended table listing the steps in the CK clamp:

Steps for the CK Clamp:

Step Conc. added [M]
Initial PCr 0.001
+ ATP 0.005
+ PCr 1 0.002
+ PCr 2 0.003
+ PCr 3 0.003
+ PCr 4 0.003
+ PCr 5 0.003
+ PCr 6 0.003
+ PCr 7 0.003
+ PCr 8 0.003
+ PCr 9 0.003
+ PCr 10 0.003

Below, we generate a list containing the calculated ionic strength at each step.

In [6]:
#
basal_IS = 0.168

# Initial PCr and Tris Concentrations
pcr_0 = 0.001
tris_0 = 2*pcr_0

# Initial PCr and Tris Ionic Strength
pcr_0_is = 0.5*(pcr_0*(-2)**2 + tris_0*(1)**2)

# ATP and Tris
atp_conc = 0.005
tris_atp = atp_conc*2
# ATP Ionic Strength 
atp_is = 0.5*(atp_conc*(-4)**2 + tris_atp*(1)**2)

# First PCr Addition
pcr_1 = 0.002
tris_1 = pcr_1*2
# First PCr Addition Ionic Strength
pcr_1_is = 0.5*(pcr_1*(-2)**2 + tris_1*(1)**2)

# Subsequent PCr Addition's Added Concentration
pcr_add = 0.003
tris_add = 2*pcr_add
pcr_is_add = 0.5*(pcr_add*(-2)**2 + tris_add*(1)**2)

# A list to hold the ionic strengths over the CK Clamp
ionicStrengths = []

# Workign Buffer  
changing_IS = basal_IS + pcr_0_is

# After ATP Addition
ionicStrengths.append(changing_IS + atp_is)

#After 1st PCr Addition
ionicStrengths.append(ionicStrengths[0] + pcr_1_is)

#After Each Subsequent PCr Addition
for step in np.arange(1, 10):
    ionicStrengths.append(ionicStrengths[step] + pcr_is_add)


# Print the Results
print('{0: <8}{1: <16}'.format('Step', 'Ionic Strength (mM)'))
print('{:-^27}'.format(''))

for idx, step in enumerate(ionicStrengths):
    print('{0: <8}{1: <12.6}'.format(idx+1, step*1000))
Step    Ionic Strength (mM)
---------------------------
1       216.0       
2       222.0       
3       231.0       
4       240.0       
5       249.0       
6       258.0       
7       267.0       
8       276.0       
9       285.0       
10      294.0       
11      303.0       

Equations, Functions, and Constants

This section lists the necessary equilibrium constants and briefly describes the equations utilized to adjust them. For a more detialed discussion on the theory, please consult the references listed at the bottom of this document.

Van't Hoff: Adjusting Temperature

The Van't Hoff Equation to adjust the temperature of $K_{ref}$

$$ \begin{equation} \ln\left(\frac{K_2}{K_1}\right) = -\frac{\Delta H ^\circ}{R}\left( \frac{1}{T_2} - \frac{1}{T_1} \right) \end{equation} $$

$R = 8.3144598 \frac{J}{K mol}$
$K_1 = K_{ref_{I=0}}$
$T_1 = T $ for temperature of $K_1$
$K_2 = K_{ref_{I=0}}$ at new temperature $T_2$
The equation assumes constant enthalpy $(\Delta H)$

To solve for $K_2$ in the Van't Hoff Equation: $$ \begin{equation} K_2 = e^{\left\{-\frac{\Delta H ^\circ}{R}\left( \frac{1}{T_2} - \frac{1}{T_1} \right) + \ln \left(K_1\right)\right\}} \end{equation} $$

The following function vant_hoff solves this equation. It is through this function that the reference constants (Kref) will be adjusted to the specified Temperature of the assay.

In [7]:
def vant_hoff(temp1, temp2, Kref1, dH):
    
    '''
    temp1  =   temperature for constant Kref1 (Kelvins)
    Kref1  =   constant at temp1 and ionic strength 0 
                 [the original constant from which Kref2 will be adjusted]
    temp2  =   temperature for constant Kref2 (Kelvins)
                 [the new temperature to which Kref1 is to be adjusted] 
    dH     =   ΔH° associated with Kref1 at temp1 and ionic strength 0 (kilojoules)
    
    Returns the modified constant at ionic strength 0, temp2
    '''
    
    # note, constants stored in the data table are in kJ; they are converted inline.
    
    return np.e**((-1000*dH/const.R)*(1/temp2 - 1/temp1) + np.log(Kref1))

Debye–Hückel: Adjusting the Ionic Strength

The following function is designed to solve for Γ as defined as:

$$ \begin{equation} \Gamma = \frac{\prod \gamma_{\text{products}_{I=\text{finite}}}} {\prod \gamma_{\text{reactants}_{I=\text{finite}}}} \end{equation} $$

Where γ is derived from the extended Debye–Hückel equation:

$$ \begin{equation} \ln γ = \frac{-A_m \sqrt{I} z^2}{1 + B \sqrt{I}} \end{equation} $$

$I= \text{ionic strength} (\frac{mol}{L})$
$B = 1.6 \frac{kg^{1/2}}{mol^{1/2}}$
$z = \text{charge}$

$$ \begin{equation} γ = e^{\frac{-A_m \sqrt{I} z^2}{1 + B \sqrt{I}}} \end{equation} $$

The variable Am is derived from the following equation (Clark and Glew, 1980):

$$ \begin{equation} A_m = 3 \left(-16.390 23 + \frac{261.337 1}{T} + 3.368 9633\ln T - 1.437 167\left(\frac{T}{100}\right) + 0.111 995 \left(\frac{T}{100}\right)^2 \right) \end{equation} $$

Γ relates the reference constant (Kref) at a specified (non-zero) ionic strength to the constant at zero ionic strength:

$$ \begin{equation} K_{\text{ref}_{I=O\text{, }T=\text{finite}}} = \Gamma K_{\text{ref}_{I=\text{finite, }T=\text{finite}}} \end{equation} $$

It is through this relationship that the reference constants (Kref) will be adjusted to the specified Ionic Strength of the assay.

In [8]:
def solve_gamma(products, reactants, temp, ionic_strength):
    '''
    products        =  list of all charged product ions
    reactants       =  list of all charged reactant ions
    temp            =  temperature in Kelvins
    ionic_strength  =  ionic strength in Molarity 
    
    Returns the calculated Γ 
    '''

    # Function to solve for Γ 
    # Debye–Hückel
    Am = 3*(-16.39023 + (261.3371/temp) + 3.3689633*np.log(temp) - 1.437167*(temp/100) + 0.111995*(temp/100)**2)
    # constant with units of kg**1/2 mol**-1/2
    B = 1.6
    
    # reactants = list of the charge carried by each reactant ionic species
    reactant_gammas = []
    # If there isn't a charged species, pass in None to ensure the returned value divides by 1
    if reactants[0] == None:
        reactant_gammas = [1]
    else:
        for react in reactants:
            reactant_gammas.append(np.e**((-Am * np.sqrt(ionic_strength) * react**2)/(1 + B*np.sqrt(ionic_strength))))
    
    
    # products = list of the charge carried by each product ionic species    
    product_gammas = []
    # if there isn't a charged species, pass in None to ensure the returned value divides by 1
    if products[0] == None:
        product_gammas = [1]
    else:
        for prod in products:
            product_gammas.append(np.e**((-Am * np.sqrt(ionic_strength) * prod**2)/(1 + B*np.sqrt(ionic_strength))))
    
    return np.prod(product_gammas)/np.prod(reactant_gammas)

Thermodynamic Data

The Chemical Equations for the hydrolysis of ATP and the Creatine Kinase reaction:

$$ \begin{equation} K_{\text{ref}} = \frac {[\text{ADP}^{3-}][\text{HPO}^{2-}_4][\text{H}^{+}]} {[\text{ATP}^{4-}]} \end{equation} $$
$$ \begin{equation} K_{\text{ref}} = \frac {[\text{ATP}^{4-}][\text{Cr}]} {[\text{ADP}^{3-}][\text{PCr}^{2-}][\text{H}^{+}]} \end{equation} $$

The apparent equilibrium constant (K`) for the above chemical equations is related to the Reference Equilibrium Constant (Kref, which is measured under specific experimental conditions) through the following relationship:

$$ K'_{ATP} = \frac {K_{\text{ref ATP}}}{[\text{H}{^+}]} \frac{ \left\{1 + \frac {[\text{H}{^+}]} {K_{\text{a}_{\text{ADP}}}} + K_{\text{b}_{\text{MgADP}}}[\text{Mg}^{2+}] + \frac {K_{\text{b}_{\text{MgHADP}}} [\text{H}{^+}][\text{Mg}^{2+}]} {K_{\text{a}_{\text{ADP}}}} \right\} \left\{ 1 + \frac {[\text{H}{^+}]} {K_{\text{a}_{\text{HPO}{_4}}}} + K_{\text{b}_{\text{MgHPO}{_4}}}[\text{Mg}^{2+}] \right\} } { \left\{1 + \frac {[\text{H}{^+}]} {K_{\text{a}_{\text{ATP}}}} + K_{\text{b}_{\text{MgATP}}}[\text{Mg}^{2+}] + \frac {K_{\text{b}_{\text{MgHATP}}} [\text{H}{^+}][\text{Mg}^{2+}]} {K_{\text{a}_{\text{ATP}}}} \right\} } $$
$$ \begin{equation} K'_{CK} = K_{\text{ref CK}} \frac { [\text{H}{^+}]\left\{1 + \frac {[\text{H}{^+}]} {K_{\text{a}_{\text{ATP}}}} + K_{\text{b}_{\text{MgATP}}}[\text{Mg}^{2+}] + \frac {K_{\text{b}_{\text{MgHATP}}} [\text{H}{^+}] [\text{Mg}^{2+}]} {K_{\text{a}_{\text{ATP}}}} \right\} } { \left\{1 + \frac {[\text{H}{^+}]} {K_{\text{a}_{\text{ADP}}}} + K_{\text{b}_{\text{MgADP}}}[\text{Mg}^{2+}] + \frac {K_{\text{b}_{\text{MgHADP}}} [\text{H}{^+}] [\text{Mg}^{2+}]} {K_{\text{a}_{\text{ADP}}}} \right\} \left\{1 + \frac {[\text{H}{^+}]} {K_{\text{a}_{\text{PCr}}}} + K_{\text{b}_{\text{MgPCr}}}[\text{Mg}^{2+}] \right\} } \end{equation} $$

Each expression contained within $\{ \}$ represents one of the ions within the Kref expressed as a function of its its acid dissociation and magnesium binding properties. These are also equilibrium constants and must be adjusted for ionic strenght, pH, free magnesium, and temperature of the system. It is through their adjustment and the above equations that we will determine the apparent Equilbrium Constants (K`) for the Creatine Kinase reaction and hydrolysis of ATP.

Teague, Golding, and Dobson (1996) compiled the following table of reference constants. The values listed are at an ionic strength of 0 and temperature of 25°C. These constants will be used to solve the apparent Equilibrium Constants in the above equations.

Symbol Python Variable Reaction Equilibrium Constant $K_{\text{ref}}$ $\Delta H{^\circ} (kJ mol^{-1})$
$$K_{\text{a}_{\text{ATP}}}$$ Ka_atp $$\text{HATP}^{3-} \leftrightarrow \text{H}{^+} + \text{ATP}^{4-}$$ $$\frac{[\text{H}{^+}][\text{ATP}^{4-}]}{[\text{HATP}^{3-}]}$$ 2.512e-8 -6.30
$$K_{\text{b}_{\text{MgATP}}}$$ Kb_mg_atp $$\text{Mg}^{2+} + \text{ATP}^{4-} \leftrightarrow \text{MgATP}^{2-}$$ $$\frac{[\text{MgATP}^{2-}]}{[\text{Mg}^{2+}][\text{ATP}^{4-}]}$$ 1.514e6 22.90
$$K_{\text{b}_{\text{MgHATP}}}$$ Kb_mg_hatp $$\text{Mg}^{2+} + \text{HATP}^{3-} \leftrightarrow \text{MgHATP}^{1-}$$ $$\frac{[\text{MgHATP}^{1-}]}{[\text{Mg}^{2+}][\text{HATP}^{3-}]}$$ 4.266e3 16.90
$$K_{\text{a}_{\text{ADP}}}$$ Ka_adp $$\text{HADP}^{2-} \leftrightarrow \text{H}{^+} + \text{ADP}^{3-}$$ $$\frac{[\text{H}{^+}][\text{ADP}^{3-}]}{[\text{HADP}^{2-}]}$$ 6.607e-8 -5.60
$$K_{\text{b}_{\text{MgADP}}}$$ Kb_mg_adp $$\text{Mg}^{2+} + \text{ADP}^{3-} \leftrightarrow \text{MgADP}^{1-}$$ $$\frac{[\text{MgADP}^{1-}]}{[\text{Mg}^{2+}][\text{ADP}^{3-}]}$$ 4.466e4 19.0
$$K_{\text{b}_{\text{MgHADP}}}$$ Kb_mg_hadp $$\text{Mg}^{2+} + \text{HADP}^{2-} \leftrightarrow \text{MgHADP}$$ $$\frac{[\text{MgHADP}]}{[\text{Mg}^{2+}][\text{HADP}^{2-}]}$$ 3.163e2 12.50
$$K_{\text{a}_{\text{HPO}{_4}}}$$ Ka_pho $$\text{H}{_2}\text{PO}{_4}^{1-} \leftrightarrow \text{H}{^+} + \text{HPO}{_4}^{2-}$$ $$\frac {[\text{HPO}{_4}^{2-}][\text{H}^{+}]}{[\text{H}{_2}\text{PO}{_4}^{1-}]}$$ 6.026e-8 3.60
$$K_{\text{b}_{\text{MgHPO}{_4}}}$$ Kb_mg_pho $$\text{Mg}^{2+} + \text{HPO}{_4}^{2-} \leftrightarrow \text{MgHPO}{_4}$$ $$\frac{[\text{MgHPO}{_4}]}{[\text{Mg}^{2+}][\text{HPO}{_4}^{2-}]}$$ 5.128e2 12.20
$$K_{\text{a}_{\text{PCr}}}$$ Ka_pcr $$\text{HPCr}^{1-} \leftrightarrow \text{H}{^+} + \text{PCr}^{2-}$$ $$\frac{[\text{H}{^+}][\text{PCr}^{2-}]}{[\text{HPCr}^{1-}]}$$ 8.854e-6 2.66
$$K_{\text{b}_{\text{MgPCr}}}$$ Kb_mg_pcr $$\text{Mg}^{2+} + \text{PCr}^{2-} \leftrightarrow \text{MgPCr}$$ $$\frac{[\text{MgPCr}]}{[\text{Mg}^{2+}][\text{PCr}^{2-}]}$$ 2.320e2 8.19
$$K_{\text{ref ATP}}$$ Kref_ATP $$\text{ATP}^{4-} + \text{H}_2\text{O} \leftrightarrow \text{ADP}^{3-} + \text{HPO}{_4}^{2-} + \text{H}^+$$ $$\frac{[\text{ADP}^{3-}][\text{HPO}{_4}^{2-}][\text{H}^+]}{[\text{ATP}^{4-}]}$$ 2.946e-1 -20.50
$$K_{\text{ref CK}}$$ Kref_CK $$\text{PCr}^{2-} + \text{ADP}^{3-} + \text{H}^+ \leftrightarrow \text{ATP}^{4-} + \text{Cr} $$ $$\frac{[\text{ATP}^{4-}][\text{Cr}]}{[\text{PCr}^{2-}][\text{ADP}^{3-}][\text{H}^+]}$$ 2.58e8 -17.55
In [9]:
# Defining a class to hold the thermodynamic information
class equilibriumConstant:
    def __init__(self, kref, dH, product_charges, reactant_charges, new_name):
        self.kref  =  kref
        self.dH    =  dH
        self.prod  =  product_charges
        self.react =  reactant_charges
        self.name  =  new_name

# From  Acid and Mg-Binding Constants at T=25°C, I=0
# Tuple Positional Key
# [0] Kref 
# [1] ΔH° (kJ/mol)
# [2] list of product charges (all positive as they will be squared later)
# [3] list of reactant charges
# [4] dict. string for new_Ks

is0_Ka_atp      =  equilibriumConstant(2.512e-08,  -6.30,   [1, 4],    [3],      'Ka_atp')
is0_Kb_mg_atp   =  equilibriumConstant(1.514e+06,   22.90,  [2],       [4, 2],   'Kb_mg_atp')
is0_Kb_mg_hatp  =  equilibriumConstant(4.266e+03,   16.90,  [1],       [2, 3],   'Kb_mg_hatp')
is0_Ka_adp      =  equilibriumConstant(6.607e-08,  -5.60,   [1, 3],    [2],      'Ka_adp')
is0_Kb_mg_adp   =  equilibriumConstant(4.466e+04,   19,     [1],       [2, 3],   'Kb_mg_adp')
is0_Kb_mg_hadp  =  equilibriumConstant(3.163e+02,   12.50,  [None],    [2, 2],   'Kb_mg_hadp')
is0_Ka_pho      =  equilibriumConstant(6.026e-8,    12.2,   [2],       [None],   'Ka_pho')
is0_Kb_mg_pho   =  equilibriumConstant(5.128e+02,   8.19,   [None],    [2, 2],   'Kb_mg_pho')
is0_Ka_pcr      =  equilibriumConstant(8.854e-06,   2.66,   [2],       [None],   'Ka_pcr')
is0_Kb_mg_pcr   =  equilibriumConstant(2.320e+02,   8.19,   [None],    [2, 2],   'Kb_mg_pcr')

Kref_CK         =  equilibriumConstant(2.58e8,   -17.55,    [4],       [3, 2, 1], 'Kref_CK')
Kref_ATP        =  equilibriumConstant(2.946e-1, -20.50,    [3, 2, 1], [4] ,      'Kref_ATP')

# the temperature of the reference constants
temp25 = 273.15 + 25 

Adjusting the Creatine Kinase Equilibrium Constant

In section 1, we detailed the experimental conditions over the Creatine Kinase clamp.

In section 2, the necessary equations and constants were outlined.

In this section, we will combine that information to determine the apparent Creatine Kinase Equilibrium Constant.

Adjust the Kref of Creatine Kinase

Step 1. Use the Van't Hoff equation to adjust $K_{\text{ref}_{I=0, T=25°C}}$ to 37°C.

$$ K_{\text{ref}_{I=0, T=37°C}} = e^{\left\{-\frac{\Delta H ^\circ}{R}\left( \frac{1}{T_2} - \frac{1}{T_1} \right) + \ln \left(K_{\text{ref}_{I=0, T=25°C}}\right)\right\}} $$

(See above section Van't Hoff for more details)

In [10]:
# The temperature of the reference constant 
temp25 = 273.15 + 25
# The temperature to which we will adjust the constant
temp37 = 273.15 + 37

# We use the function vant_hoff (defined above) to solve the Van't Hoff equation
# and adjust the constant to 37°C

CK_k2 = vant_hoff(temp25, temp37, Kref_CK.kref, Kref_CK.dH)

print('Creatine Kinase Kref\n  -Ionic Strength 0\n  -Temp. 37°C\n')
print('{:.4e}'.format(CK_k2))
Creatine Kinase Kref
  -Ionic Strength 0
  -Temp. 37°C

1.9618e+08

Step. 2. Adjust the $K_{\text{ref}}$ from an Ionic Strength of 0 to the Ionic Strength at each step of the assay

$$ \begin{equation} \frac {K_{\text{ref}_{I=0\text{, }T=\text{37°C}}}}{\Gamma_{I=\text{CK Clamp}}} = K_{\text{ref}_{I=\text{CK Clamp, }T=\text{37°C}}} \end{equation} $$

(See above section Debye–Hückel for more details)

In [11]:
# CK Clamp temperature in Kelvin 
temp37 = 273.15 + 37

# List to hold the new CK_Kref at each steop of the CK Clamp titration
CK_kref_titration = []

# iterate through each step in the CK clamp and 
# adjust the constant to the appropriate ionic strength 
for ion_str in ionicStrengths:
    # We use our function solve_gamma (based on the extended Debye–Hückel equation, defined above)
    # to calculate Γ
    gamma = solve_gamma(Kref_CK.prod, Kref_CK.react, temp37, ion_str)
    
    # We divide the temperature-adjusted constant (from step 1) by gamma 
    # to adjust to the new ionic strength
    CK_k3 = CK_k2/gamma
    
    # Append the constant to the end of our holding list
    CK_kref_titration.append(CK_k3)


# Print the Results
print('{0: <8}{1: <16}'.format('Step', 'Creatine Kinase Krefs'))
print('{:-^29}'.format(''))

for idx, step in enumerate(CK_kref_titration):
    print('{0: <8}{1: <#12.6}'.format(idx+1, step))
Step    Creatine Kinase Krefs
-----------------------------
1       3.72103e+08 
2       3.73981e+08 
3       3.76729e+08 
4       3.79397e+08 
5       3.81990e+08 
6       3.84514e+08 
7       3.86971e+08 
8       3.89366e+08 
9       3.91701e+08 
10      3.93979e+08 
11      3.96204e+08 

Calculate the apparent equililbrium constants for Creatine Kinase

The following function accepts 5 arguments:

  1. A list containing the ionic strength of each step in the assay.
  2. The temperature of the assay in °C
  3. A list of the adjusted Creatine Kinase reference constants (calculated above)
  4. The pH of the assay
  5. A list containing the free magnesium concentration of each step in the assay

calc_CK_Keq_steps performs the same calculations (steps 1 and 2) to each of the equilibrium constants in the chemical equation of the Creatine Kinase reaction. It then uses those values (along with the experimental conditions) to solve the apparent equilibrium constant of CK (K`). This is repeated for each step in the assay and stored in a list.

In [12]:
def calc_CK_Keq_steps(ionicStrengths, tempK, CK_kref_titration, pH, freeMg):
    '''
    ionicStrengths =   list of ionic strength values over titration. (Molarity)
    temp           =   temperature of the assay in Kelvins
    pH             =   the pH of the assay
    freeMg         =   list of free Magnesium concentration over the titration. (Molarity)
    
    Returns a list of the apparent CK Eq. Constants (Keq_CK)
    '''
    # Convert input variables into necessary units
    proton = 10**-pH
    temp25 = 273.15 + 25
    
    # List to store CK Equilibrium Constants calculated for each step of the CK-Clamp titration
    Keq_CK = []
    
    # Make sure the 2 lists are equal
    if len(ionicStrengths) != len(freeMg):
        raise ValueError('Size mismatch: the length of ionicStrengths and freeMg are not equal')
        
    # A list of the constants contained in the Creatine Kinase reaction
    ck_Ks =  [is0_Ka_atp,
              is0_Kb_mg_atp,
              is0_Kb_mg_hatp,
              is0_Ka_adp,
              is0_Kb_mg_adp,
              is0_Kb_mg_hadp,
              is0_Ka_pcr,
              is0_Kb_mg_pcr]
    
    # iterate through each ionic strength change in the CK Clamp
    for index, ion_str in enumerate(ionicStrengths):
    
        # a dictionary to store the modified equilibrium constants at each step in the titration
        new_Kabs = {}
        
        # Free Magnesium at the specific ionic strength
        mg = freeMg[index]
        
        # iterate through the acid and Mg-binding Krefs in the CK Eq reaction
        for k1 in ck_Ks:
            
            # Use Van't Hoff 
            # new kref (k2) adjusted from I=0, T=25°C to I=0, T=tempK
            k2 = vant_hoff(temp25, tempK, k1.kref, k1.dH)
            
            # Use Debye–Hückel
            # new kref (k3) adjusted from I=0,T=25°C to new I, T=tempK
            # the k1 object contains the product and reactant charges
            k3 = k2/solve_gamma(k1.prod, k1.react, tempK, ion_str)
            
            # Store the new equilibrium constant 
            new_Kabs[k1.name] = k3
        
        # Modified Equilibrium Constant for the Creatine Kinase Reaction
        products = (1 + proton/new_Kabs['Ka_atp'] + new_Kabs['Kb_mg_atp']*mg 
                    + new_Kabs['Kb_mg_hatp']*proton*mg/new_Kabs['Ka_atp'])
        
        react_adp = (1 + proton/new_Kabs['Ka_adp'] + new_Kabs['Kb_mg_adp']*mg 
                     + new_Kabs['Kb_mg_hadp']*proton*mg/new_Kabs['Ka_adp'])
        
        react_pcr = (1 + proton/new_Kabs['Ka_pcr'] + new_Kabs['Kb_mg_pcr']*mg)
    
        Kf_CK = CK_kref_titration[index] * proton * products/(react_adp * react_pcr)
        
        # Append the apparent Keq to our holding list 
        Keq_CK.append(Kf_CK)

    
    return Keq_CK
In [13]:
# CK Clamp temperature in Kelvins 
temp37 = 273.15 + 37

Keq_CK = calc_CK_Keq_steps(ionicStrengths, temp37, CK_kref_titration, pH, freeMg)

# Print the Results
print('{0: <8}{1: <16}'.format('Step', 'Creatine Kinase K`'))
print('{:-^26}'.format(''))

for idx, step in enumerate(Keq_CK):
    print('{0: <8}{1: <#12.6}'.format(idx+1, step))
Step    Creatine Kinase K`
--------------------------
1       111.375     
2       107.882     
3       102.729     
4       98.6674     
5       94.3429     
6       90.8248     
7       87.1235     
8       83.6187     
9       80.7410     
10      78.4410     
11      75.7824     

Adjusting the ATP Hydrolysis Equilibrium Constant

This section has the same format as Section 3

Adjust the Kref of ATP Hydrolysis

Step 1. Use the Van't Hoff equation to adjust $K_{\text{ref}_{I=0, T=25°C}}$ to 37°C.

$$ K_{\text{ref}_{I=0, T=37°C}} = e^{\left\{-\frac{\Delta H ^\circ}{R}\left( \frac{1}{T_2} - \frac{1}{T_1} \right) + \ln \left(K_{\text{ref}_{I=0, T=25°C}}\right)\right\}} $$

(See above section Van't Hoff for more details)

In [14]:
# The temperature of the reference constant 
temp25 = 273.15 + 25
# The temperature to which we will adjust the constant
temp37 = 273.15 + 37

# We use the function vant_hoff (defined above) to solve the Van't Hoff equation
# and adjust the constant to 37°C

ATP_k2 = vant_hoff(temp25, temp37, Kref_ATP.kref, Kref_ATP.dH)

print('ATP Hydrolysis Kref\n  -Ionic Strength 0\n  -Temp. 37°C\n')
print('{:.4e}'.format(ATP_k2))
ATP Hydrolysis Kref
  -Ionic Strength 0
  -Temp. 37°C

2.1393e-01

Step. 2. Adjust the $K_{\text{ref}}$ from an Ionic Strength of 0 to the Ionic Strength at each step of the assay

$$ \begin{equation} \frac {K_{\text{ref}_{I=0\text{, }T=\text{37°C}}}}{\Gamma_{I=\text{CK Clamp}}} = K_{\text{ref}_{I=\text{CK Clamp, }T=\text{37°C}}} \end{equation} $$

(See above section Debye–Hückel for more details)

In [15]:
# Assay temperature in Kelvin 
temp37 = 273.15 + 37

# List to hold the new ATP_Kref at each steop of the assay
ATP_kref_titration = []

# iterate through each step in the assay and 
# adjust the constant to the appropriate ionic strength 
for ion_str in ionicStrengths:
    # We use our function solve_gamma (based on the extended Debye–HüATPel equation, defined above)
    # to calculate Γ
    gamma = solve_gamma(Kref_ATP.prod, Kref_ATP.react, temp37, ion_str)
    
    # We divide the temperature-adjusted constant (from step 1) by gamma 
    # to adjust to the new ionic strength
    ATP_k3 = ATP_k2/gamma
    
    # Append the constant to the end of our holding list
    ATP_kref_titration.append(ATP_k3)


# Print the Results
print('{0: <8}{1: <16}'.format('Step', 'ATP Hydrolysis Krefs'))
print('{:-^28}'.format(''))

for idx, step in enumerate(ATP_kref_titration):
    print('{0: <8}{1: <#12.6}'.format(idx+1, step))
Step    ATP Hydrolysis Krefs
----------------------------
1       0.112790    
2       0.112224    
3       0.111406    
4       0.110622    
5       0.109871    
6       0.109150    
7       0.108457    
8       0.107790    
9       0.107147    
10      0.106528    
11      0.105929    

Calculate the apparent equililbrium constants for ATP Hydrolysis

The following function accepts 5 arguments:

  1. A list containing the ionic strength of each step in the assay.
  2. The temperature of the assay in °C
  3. A list of the adjusted ATP Hydrolysis reference constants (calculated above)
  4. The pH of the assay
  5. A list containing the free magnesium concentration of each step in the assay

calc_ATP_Keq_steps performs the same calculations (steps 1 and 2) to each of the equilibrium constants in the chemical equation of ATP Hydrolysis. It then uses those values (along with the experimental conditions) to solve the apparent equilibrium constant of ATP Hydrolysis (K`). This is repeated for each step in the assay and stored in a list.

In [16]:
def calc_ATP_Keq_steps(ionicStrengths, tempK, ATP_kref_titration, pH, freeMg):
    '''
    ionicStrengths =   list of ionic strength values over titration. Unit = Molarity
    temp           =   temperature of the assay in Kelvin
    pH             =   the pH of the assay
    freeMg         =   list of free Magnesium concentration over the titration. Unit = Molarity.
    
    Returns a list of the apparent ATP Hydrolysis Eq. Constants (Keq_ATP)
    '''
    
    # Convert input variables into necessary units
    proton = 10**-pH
    
    # Temp. of all reference constants
    temp25 = 273.15 + 25
    
    # List to store ATP Equilibrium Constants calculated for each step of the ATP-Clamp titration
    Keq_ATP = []
    
    # Make sure the 2 lists are equal
    if len(ionicStrengths) != len(freeMg):
        raise ValueError('Size mismatch: the length of ionicStrengths and freeMg are not equal')
        
    # A list of the constants contained in the ATP Hydrolysis reaction
    atp_Ks = [is0_Ka_atp,
              is0_Kb_mg_atp,
              is0_Kb_mg_hatp,
              is0_Ka_adp,
              is0_Kb_mg_adp,
              is0_Kb_mg_hadp,
              is0_Ka_pho,
              is0_Kb_mg_pho]
    
    # iterate through each ionic strength change in the assay
    for index, ion_str in enumerate(ionicStrengths):
    
        # a dictionary to store the modified equilibrium constants at each step in the titration
        new_Kabs = {}
        
        # Free Magnesium at the specific ionic strength
        mg = freeMg[index]
        
        # iterate through the acid and Mg-binding Krefs in the ATP Eq reaction
        for k1 in atp_Ks:
            
            # Use Van't Hoff 
            # new kref (k2) adjusted from I=0, T=25°C to I=0, T=tempK
            k2 = vant_hoff(temp25, tempK, k1.kref, k1.dH)
            
            # Use Debye–Hückel
            # new kref (k3) adjusted from I=0,T=25°C to new I, T=tempK
            # the k1 object contains the product and reactant charges
            k3 = k2/solve_gamma(k1.prod, k1.react, tempK, ion_str)
            
            # Store the new equilibrium constant 
            new_Kabs[k1.name] = k3
        
        # Modified Equilibrium Constant for the ATP Hydrolysis Reaction
        react = (1 + proton/new_Kabs['Ka_atp'] + new_Kabs['Kb_mg_atp']*mg 
                 + new_Kabs['Kb_mg_hatp']*proton*mg/new_Kabs['Ka_atp'])
        
        prod_adp = (1 + proton/new_Kabs['Ka_adp'] + new_Kabs['Kb_mg_adp']*mg 
                    + new_Kabs['Kb_mg_hadp']*proton*mg/new_Kabs['Ka_adp'])
        
        prod_pho = (1 + proton/new_Kabs['Ka_pho'] + new_Kabs['Kb_mg_pho']*mg)

        Kf_ATP = (ATP_kref_titration[index] * prod_adp * prod_pho)/(react * proton)
        
        Keq_ATP.append(Kf_ATP)
    
    return Keq_ATP
In [17]:
# Assay temperature in Kelvin 
temp37 = 273.15 + 37

Keq_ATP = calc_ATP_Keq_steps(ionicStrengths, temp37, ATP_kref_titration, pH, freeMg)

# Print the Results
print('{0: <8}{1: <16}'.format('Step', 'ATP Hydrolysis K`'))
print('{:-^25}'.format(''))

for idx, step in enumerate(Keq_ATP):
    print('{0: <8}{1: <#12.6}'.format(idx+1, step))
Step    ATP Hydrolysis K`
-------------------------
1       4.92617e+05 
2       5.07268e+05 
3       5.30752e+05 
4       5.50702e+05 
5       5.74032e+05 
6       5.94406e+05 
7       6.17784e+05 
8       6.41812e+05 
9       6.62865e+05 
10      6.80531e+05 
11      7.02615e+05 

Calculating the Gibbs Energy

The ultimate goal of this endeavor is to determine the Gibbs energy of ATP hydrolysis ($\Delta G'_{ATP}$) within our Creatine Kinase Clamp.

The following equation relates the apparent Gibbs energy of ATP Hydrolysis ($\Delta G'_{ATP}$) with the apparent standard Gibbs energy of ATP hydrolysis ($\Delta G'{^\circ}_{ATP}$)

$$ \begin{equation} \Delta G'_{ATP} = \Delta G'{^\circ}_{ATP} + \mathbf{R}T \ln \frac {[\text{ADP}][\text{P}_i]}{[\text{ATP}]} \end{equation} $$

Calculate the apparent standard Gibbs Energy of ATP Hydrolysis

The apparent standard Gibbs energy under specified conditions of pH, Ionic Strength, Free Magnesium, and Pressure (which we are not considering in our equations):

$$ \Delta G'{^\circ}_\text{ATP} $$

Another way to express $\Delta G'{^\circ}_\text{ATP}$: $$ \begin{equation} \Delta G'{^\circ}_\text{ATP} = -\mathbf{R}T \ln K'_{\text{ATP}} \end{equation} $$

Where $K'_{\text{ATP}}$ is the apparent equilbrium constant of ATP hydrolysis. In section 4 we calculated this value at each step in the assay. We will now use those values to calculate $\Delta G'{^\circ}_\text{ATP}$ over the CK clamp.

In [18]:
# Temperature of the assay
t37 = 273.15 + 37

# A list to store the apparent standard Gibbs energy for each step
dG_std_ATP = []

# iterate through each step of the assay 
# and calculate the G`° of ATP Hyd.
for keq in Keq_ATP:
    
    # solve the equation and store the value in a temporary variable
    dG_std = -const.R * t37 * np.log(keq)
    
    # Store the value on our list
    dG_std_ATP.append(dG_std)

# Print the Results
print('{0: <8}{1: <16}'.format('Step', 'ΔG°` of ATP Hydrolysis (kJ/mol)'))
print('{:-^39}'.format(''))

for idx, step in enumerate(dG_std_ATP):
    print('{0: <8}{1: <#12.6}'.format(idx+1, step/1000))
Step    ΔG°` of ATP Hydrolysis (kJ/mol)
---------------------------------------
1       -33.8007    
2       -33.8762    
3       -33.9929    
4       -34.0881    
5       -34.1951    
6       -34.2850    
7       -34.3845    
8       -34.4829    
9       -34.5661    
10      -34.6340    
11      -34.7163    

Calculate the apparent Gibbs Energy of ATP Hydrolysis

Use the K'Creatine Kinase to determine the concentrations of ATP and ADP

In section 3, we adjusted the Creatine Kinase Equilibrium Constants to conditions of our assay. We will now use those values to determine the concentration of ATP and ADP at each step in the assay.

Below, we define 2 functions to solve for the concentrations of each species in the following Equilibrium Reaction:

$$ \begin{equation} K'_{CK} = \frac {[\text{ATP}][\text{Cr}]} {[\text{ADP}][\text{PCr}]} \end{equation} $$

Step 1 This solves the concentrations of ATP, ADP, Cr, and PCr after the first step in the titration. Prior to this step, the buffer contains Creatine Kinase, Creatine, and Phosphocreatine. After the ATP is added, the equilibrium produces ADP and PCr at the expense of ATP and Creatine.

The function solves the following equation for x:

$$ \begin{equation} K'_{CK} = \frac {[\text{ATP} - x][\text{Cr} - x]} {[\text{ADP} + x][\text{PCr} + x]} \end{equation} $$

Where

  • $K'_{CK}$ = the equilibirum constant of Creatine Kinase at the specific I and T
  • $[\text{ATP}]$ = the concentration of ATP added the instant before CK converts it
  • $[\text{Cr}]$ = the concentration of Creatine in the buffer before the addition of ATP
  • $[\text{PCr}]$ = the concentration of Phosphocreatine in the buffer before the addition of ATP
  • $[\text{ADP}]$ is assumed to be 0

This equilibrium can be rearranged to the following quadratic formula.

$$ \begin{equation} \left(K'_{CK} - 1 \right)x^2 + \left(K'_{CK} \times [\text{PCr}] + [\text{ATP}] + [\text{Cr}] \right) x - \left( [\text{ATP}] \times [\text{Cr}] \right) = 0 \end{equation} $$

We can use the quadratic equation to solve for x:

$$ x={\frac {-b\pm {\sqrt {b^{2}-4ac\ }}}{2a}} $$

Where

  • a = $K'_{CK} - 1$
  • b = $K'_{CK} \times [\text{PCr}] + [\text{ATP}] + [\text{Cr}]$
  • c = $[\text{ATP}] \times [\text{Cr}]$
In [19]:
# Defining a class to hold the concentration data
class CK_concentration:
    def __init__(self, atp, cr, adp, pcr):
        self.atp  =  atp
        self.cr   =  cr
        self.adp  =  adp
        self.pcr  =  pcr
In [20]:
def calc_step_one_conc(Keq_CK, ATP, Cr, PCr):
    a = (Keq_CK - 1)
    b = (Keq_CK*PCr + ATP + Cr)
    c = -ATP*Cr
    
    x = (-1*b + np.sqrt((b**2) - 4*(a*c))) / (2*a)
    
    atp = ATP-x
    cr  = Cr-x
    adp = x
    pcr = PCr+x
    
    concentrations = CK_concentration(atp, cr, adp, pcr)
    
    return concentrations

Step 2 This solves the concentrations of ATP, ADP, Cr, and PCr for all steps in the titration except the first (where ATP is added)

The function solves the following equation for x:

$$ \begin{equation} K'_{CK} = \frac {[\text{ATP} + x][\text{Cr} + x]} {[\text{ADP} - x][\text{PCr}_\text{pre} + \left( \text{PCr}_\text{addition} - x \right)]} \end{equation} $$

Where

  • $K'_{CK}$ = the equilibirum constant of Creatine Kinase at the specific I and T
  • $[\text{ATP}]$ = the concentration of ATP in the buffer before the addition of PCr
  • $[\text{Cr}]$ = the concentration of Creatine in the buffer before the addition of PCr
  • $[\text{ADP}]$ = the concentration of ADP in the buffer before the addition of PCr
  • $[\text{PCr}_\text{pre}]$ = the concentration of Phosphocreatine in the buffer before the addition of PCr_add
  • $[\text{PCr}_\text{addition}]$ = the concentration of Phosphocreatine added the instant before CK converts it

This equilibrium can be rearranged into the following quadratic formula

$$ \left(K'_{CK} - 1 \right)x^2 - \left( K'_{CK} \left([\text{ADP}] - [\text{PCr}_\text{pre}] - [\text{PCr}_\text{addition}]\right) - [\text{ATP}] - [\text{Cr}]\right)x + \left( K'_{CK} \times [\text{ADP}] \times [\text{PCr}_\text{pre}] + K'_{CK} \times [\text{ADP}] \times [\text{PCr}_\text{addition}] - [\text{ATP}] \times [\text{Cr}]\right) = 0 $$

Again, we can use the quadratic equation to solve for x:

$$ x={\frac {-b\pm {\sqrt {b^{2}-4ac\ }}}{2a}} $$

Where

  • a = $K'_{CK} - 1$

  • b = $ -\left( K'_{CK} \left([\text{ADP}] - [\text{PCr}_\text{pre}] - [\text{PCr}_\text{addition}]\right) - [\text{ATP}] -[\text{Cr}]\right)$

  • c = $ K'_{CK} \times [\text{ADP}] \times [\text{PCr}_\text{pre}] + K'_{CK} \times [\text{ADP}] \times [\text{PCr}_\text{addition}] - [\text{ATP}] \times [\text{Cr}]$
In [21]:
def calc_step_conc(Keq_CK, ATP, Cr, ADP, PCr_pre, PCr_add):
    
    a = (Keq_CK - 1)
    b = Keq_CK*(ADP - PCr_pre - PCr_add) - ATP - Cr
    c = Keq_CK*ADP*PCr_pre + Keq_CK*ADP*PCr_add - ATP*Cr
    
    x = (-1*b - np.sqrt((b**2) - 4*(a*c))) / (2*a)
    
    atp = ATP+x
    cr  = Cr+x
    adp = ADP-x
    pcr = PCr_pre + (PCr_add - x)
    
    concentrations = CK_concentration(atp, cr, adp, pcr)
    
    return concentrations
In [22]:
# Calculate the concentrations of ATP, Creatine, ADP, and PCr at each step in the CK Clamp

# Starting Concentrations [M]
ATP = 0.005
Cr  = 0.005
PCr = 0.001

# A list to store the concentrations
step_concentrations = []

# Calc. the first step with addition of ATP
# and add it to the list
step_concentrations.append(calc_step_one_conc(Keq_CK[0], ATP, Cr, PCr))

# Calc. second step (addition of 2mM PC)
# and add it to the list
PCr_add = 0.002

step_concentrations.append(calc_step_conc(Keq_CK[1],
                                          step_concentrations[0].atp, 
                                          step_concentrations[0].cr, 
                                          step_concentrations[0].adp, 
                                          step_concentrations[0].pcr, 
                                          PCr_add))

# Calc. remaining steps (each with addition of 3mM PCr)
# and add them to the list. 
PCr_add = 0.003

index = np.arange(2, len(Keq_CK))

for idx in index:
    step_concentrations.append(calc_step_conc(Keq_CK[idx],
                                              step_concentrations[idx-1].atp, 
                                              step_concentrations[idx-1].cr, 
                                              step_concentrations[idx-1].adp, 
                                              step_concentrations[idx-1].pcr, 
                                              PCr_add))

# Print the Results
print('{: ^60}'.format('Concentrations over the CK Clamp (mM)'))
print('{0: ^12}{1: ^12.6}{2: ^12.6}{3: ^12.6}{4: ^12.6}'.format('Step', 'ATP', 'ADP', 'PCr', 'Cr'))
print('{:-^60}'.format(''))

for idx, step in enumerate(step_concentrations):
    print('{0: ^12}{1: ^12.6}{2: ^12.6}{3: ^12.6}{4: ^12.6}'.format(idx+1, 
                                                                    step.atp*1000, 
                                                                    step.adp*1000, 
                                                                    step.pcr*1000, 
                                                                    step.cr*1000))
           Concentrations over the CK Clamp (mM)            
    Step        ATP         ADP         PCr          Cr     
------------------------------------------------------------
     1        4.82263     0.177366    1.17737     4.82263   
     2        4.93966    0.0603405    3.06034     4.93966   
     3        4.96076    0.0392447    6.03924     4.96076   
     4        4.97234    0.0276563    9.02766     4.97234   
     5        4.97818    0.0218237    12.0218     4.97818   
     6        4.98182    0.0181845    15.0182     4.98182   
     7        4.98418    0.0158222    18.0158     4.98418   
     8        4.98586    0.0141445    21.0141     4.98586   
     9        4.98717    0.0128268    24.0128     4.98717   
     10       4.98826    0.0117426    27.0117     4.98826   
     11       4.98906    0.0109437    30.0109     4.98906   

Use the concentrations of ATP and ADP to calculate the apparent Gibbs Energy of ATP Hydrolysis

Now, we will use the $\Delta G'{^\circ}_{ATP}$ along with the concentrations of ATP, ADP, and Phosphate to calculate the apparent Gibbs Energy of ATP Hydrolysis with the following equation

$$ \begin{equation} \Delta G'_{ATP} = \Delta G'{^\circ}_{ATP} + \mathbf{R}T \ln \frac {[\text{ADP}][\text{P}_i]}{[\text{ATP}]} \end{equation} $$
In [23]:
# List to store the  ΔG' of ATP Hydrolysis at each step of the titration
dG_ATP = []
temp37 = 273.13 + 37

for index, step in enumerate(step_concentrations):
    dG_ATP.append(dG_std_ATP[index] + const.R * temp37 * np.log(step.adp*phosphate/step.atp))


print('{0: <8}{1: <16}'.format('Step', 'ΔG` of ATP Hydrolysis (kJ/mol)'))
print('{:-^38}'.format(''))

for idx, step in enumerate(dG_ATP):
    print('{0: <8}{1: <#12.6}'.format(idx+1, step/1000))
Step    ΔG` of ATP Hydrolysis (kJ/mol)
--------------------------------------
1       -54.1920    
2       -57.1097    
3       -58.3466    
4       -59.3502    
5       -60.0710    
6       -60.6332    
7       -61.0927    
8       -61.4810    
9       -61.8171    
10      -62.1132    
11      -62.3776    
In [24]:
print('{0: <8}{1: <16}'.format('Step', 'ΔG` of ATP Hydrolysis (kCal/mol)'))
print('{:-^40}'.format(''))

for idx, step in enumerate(dG_ATP):
    print('{0: <8}{1: <#12.6}'.format(idx+1, step/1000*0.239006))
Step    ΔG` of ATP Hydrolysis (kCal/mol)
----------------------------------------
1       -12.9522    
2       -13.6496    
3       -13.9452    
4       -14.1851    
5       -14.3573    
6       -14.4917    
7       -14.6015    
8       -14.6943    
9       -14.7746    
10      -14.8454    
11      -14.9086    

Graphing the Changes over the CK Clamp

This section's purpose is to highlight the importance of correcting for assay conditions.

In [25]:
# Import necessary libraries 
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
%matplotlib inline

# Increase the matplotlib plot size for easier viewing
plt.rcParams['ytick.labelsize'] = 16
plt.rcParams['xtick.labelsize'] = 16
plt.rcParams['axes.titlesize'] = 24
plt.rcParams['legend.fontsize'] = 16
plt.rcParams['axes.labelsize'] = 20
plt.rcParams['figure.figsize'] = (8,6)
plt.rcParams['lines.linewidth'] = 3
plt.rcParams['figure.dpi'] = 120
In [26]:
# Generate lists to store the concentrations of each molecule
ADP = []
ATP = []
# A list of the ratio
ATP_ADP = []
for step in step_concentrations:
    ADP.append(step.adp*1000)
    ATP.append(step.atp*1000)
    ATP_ADP.append(step.atp/step.adp*1000)

Calculating ATP/ADP Concentrations without adjusting K`eq

In the next cell, we will repeat the calculations performed in section 5.2.1. Instead of using the adjusted K`CK for each step in the assay, we will use a value that is widely used in the literature: 166. This constant is specified at pH 7.0, free Mg2+ 1 mM, Ionic Strength 0.25 M, and temperature of 38°C (Golding, Teague, and Dobson 1995).

In [27]:
# Calculate the concentrations of ATP, Creatine, ADP, and PCr at each step in the CK Clamp
# Use a constant from the literature without adjusting it over the clamp 
iKeq_CK = [166]*11

# Starting Concentrations [M]
iATP = 0.005
iCr  = 0.005
iPCr = 0.001

# A list to store the concentrations
istep_concentrations = []

# Calc. the first step with addition of ATP
# and add it to the list
istep_concentrations.append(calc_step_one_conc(iKeq_CK[0], iATP, iCr, iPCr))

# Calc. second step (addition of 2mM PC)
# and add it to the list
iPCr_add = 0.002

istep_concentrations.append(calc_step_conc(iKeq_CK[1],
                                          istep_concentrations[0].atp, 
                                          istep_concentrations[0].cr, 
                                          istep_concentrations[0].adp, 
                                          istep_concentrations[0].pcr, 
                                          iPCr_add))

# Calc. remaining steps (each with addition of 3mM PCr)
# and add them to the list. 
iPCr_add = 0.003

index = np.arange(2, len(iKeq_CK))

for idx in index:
    istep_concentrations.append(calc_step_conc(iKeq_CK[idx],
                                              istep_concentrations[idx-1].atp, 
                                              istep_concentrations[idx-1].cr, 
                                              istep_concentrations[idx-1].adp, 
                                              istep_concentrations[idx-1].pcr, 
                                              iPCr_add))

# Print the Results
print('{: ^60}'.format('Concentrations over the CK Clamp (mM)'))
print('{0: ^12}{1: ^12.6}{2: ^12.6}{3: ^12.6}{4: ^12.6}'.format('Step', 'ATP', 'ADP', 'PCr', 'Cr'))
print('{:-^60}'.format(''))

for idx, step in enumerate(istep_concentrations):
    print('{0: ^12}{1: ^12.6}{2: ^12.6}{3: ^12.6}{4: ^12.6}'.format(idx+1, 
                                                                    step.atp*1000, 
                                                                    step.adp*1000, 
                                                                    step.pcr*1000, 
                                                                    step.cr*1000))
           Concentrations over the CK Clamp (mM)            
    Step        ATP         ADP         PCr          Cr     
------------------------------------------------------------
     1        4.87306     0.126939    1.12694     4.87306   
     2        4.95843     0.041569    3.04157     4.95843   
     3        4.97548    0.0245184    6.02452     4.97548   
     4        4.98345    0.0165492    9.01655     4.98345   
     5        4.98754    0.0124635    12.0125     4.98754   
     6        4.99001    0.00998932    15.01      4.99001   
     7        4.99167    0.00833324   18.0083     4.99167   
     8        4.99285    0.00714768   21.0071     4.99285   
     9        4.99374    0.00625724   24.0063     4.99374   
     10       4.99444    0.00556399   27.0056     4.99444   
     11       4.99499    0.00500898    30.005     4.99499   
In [28]:
# Generate lists to store the concentrations of each molecule
# Non-adjusted equilibrium values
iADP = []
iATP = []
# A list of the ratio
iATP_ADP = []
for step in istep_concentrations:
    iADP.append(step.adp*1000)
    iATP.append(step.atp*1000)
    iATP_ADP.append(step.atp/step.adp*1000)

Plotting and Comparing the Results

Failing to accurately adjust the equilibrium constants can result in significant errors.

In [30]:
# Plot the ATP, ADP, and ATP/ADP ratios for adjusted (solid lines) and unadjusted (dotted lines)
ax1 = plt.subplot2grid((2, 4), (0, 0), colspan=2)
ax2 = plt.subplot2grid((2, 4), (1, 0), colspan=2)
ax3 = plt.subplot2grid((2, 4), (0, 2), colspan=2, rowspan=2)

# Adjusted [ATP]
ax1.plot(np.arange(1,9), ATP[0:8], label='ATP', color='C0')
ax1.scatter(np.arange(1,9), ATP[0:8], color='C0')
# Unadjusted [ATP]
ax1.plot(np.arange(1,9), iATP[0:8], label='iATP', ls='dotted', color='C0')
ax1.scatter(np.arange(1,9), iATP[0:8])

ax1.set_ylabel('[mM]')
ax1.set_xticks(np.arange(1,9))
ax1.set_xticklabels([], fontsize=8)
ax1.legend(loc='center right', )

# Adjusted [ADP]
ax2.plot(np.arange(1,9), ADP[0:8], label='ADP', color='C2')
ax2.scatter(np.arange(1,9), ADP[0:8], color='C2')
# Unadjusted [ADP]
ax2.plot(np.arange(1,9), iADP[0:8], label='iADP', color='C2', ls='dotted')
ax2.scatter(np.arange(1,9), iADP[0:8], color='C2')


ax2.set_ylabel('[mM]')
ax2.legend(loc='center right', )
ax2.set_xticks(np.arange(1,9))
ax2.set_xticklabels(['+ATP', '+PCr', '+PCr', '+PCr', '+PCr', '+PCr', '+PCr', '+PCr'], fontsize=8)

# Adjusted Ratio
ax3.plot(np.arange(1,9), ATP_ADP[0:8], label='ATP/ADP', color='C3')
ax3.scatter(np.arange(1,9), ATP_ADP[0:8], color='C3')
# Unadjusted Ratio
ax3.plot(np.arange(1,9), iATP_ADP[0:8], label='iATP/ADP', color='C3', ls='dotted')
ax3.scatter(np.arange(1,9), iATP_ADP[0:8], color='C3')

ax3.set_xticks(np.arange(1,9))
ax3.set_xticklabels(['+ATP', '+PCr', '+PCr', '+PCr', '+PCr', '+PCr', '+PCr', '+PCr'], fontsize=8)
ax3.legend()


plt.tight_layout()

References

  1. Clarke, E. C. W. & Glew, D. N. Evaluation of Debye–Hückel limiting slopes for water between 0 and 150°C. J. Chem. Soc., Faraday Trans. 1 76, 1911–1916 (1980).
  2. Alberty, R. A. Calculation of transformed thermodynamic properties of biochemical reactants at specified pH and pMg. Biophysical Chemistry 43, 239–254 (1992).
  3. Golding, E. M., Teague, W. E. & Dobson, G. P. Adjustment of K’ to varying pH and pMg for the creatine kinase, adenylate kinase and ATP hydrolysis equilibria permitting quantitative bioenergetic assessment. Journal of Experimental Biology 198, 1775–1782 (1995).
  4. Teague, W. E., Golding, E. M. & Dobson, G. P. Adjustment of K’ for the creatine kinase, adenylate kinase and ATP hydrolysis equilibria to varying temperature and ionic strength. Journal of Experimental Biology 199, 509–512 (1996).
In [ ]: