Model for Bacterial Growth and Death Under Antibiotic and OneRing Treatment

We built a set of ordinary differential equations to model bacterial growth under normal conditions. Subsequently, we conducted a comparative analysis of the rate of killing of bacteria when antibiotics and our OneRing system are applied. To be as accurate as possible, we used various literature data relating to antibiotic efficiency, and some data (such as the conjugation efficiency) from our own wet lab results.

The detailed explanations of our graphs, differential equations, and our code can be found on the following document.

In conclusion, the model confirms that, as expected, the OneRing solution also kills resistant-bacteria, which is the main advantage of our system. In addition, the highly efficient conjugation rates (0.85) also makes OneRing a promising solution to AMR.

For an enhanced appearance of our Python code, and to reproduce our results, you can use the following code: Python Code Display

Graph 1 Code


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp

# Parameters
c = 0.72
N_max = 10**8.85
N_0 = 10**4.0
r = 0.898  # Updated r value
N_min = (1 - 1 / 10**6) * N_0

# Define the ODE
def dN_dt(t, N):
    return r * N * ((1 - N / N_max) * ((1 - N_min / N) ** c))

# Time span for the solution (from 0 to 48 time units)
t_span = (0, 48)
t_eval = np.linspace(t_span[0], t_span[1], 1000)

# Solve the ODE
sol = solve_ivp(dN_dt, t_span, [N_0], t_eval=t_eval, method='RK45')

# Plot the result with a logarithmic y-axis
plt.figure(figsize=(10, 6))
plt.plot(sol.t, sol.y[0], label='N(t)')
plt.xlabel('Time (hours)')
plt.ylabel('log N (CFU/ml)')
plt.yscale('log')  # Set y-axis to logarithmic scale
plt.title('Undisturbed growth of E. coli')
plt.legend()
plt.grid(True)
plt.show()
  

Graph 2 Code


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp

# Parameters
c = 0.72
N_max = 10**8.85
N_0 = 10**4.0
r = 0.898  # Updated r value
N_min = (1 - 1 / 10**6) * N_0
A_initial = 0.0  # A value before T
A_final = 117 * 0.0625  # A value after T
T = 15  # Time at which A changes
a = 7.5
MIC = 0.0625

# Define the ODE
def dN_dt(t, N):
    if t < T:
        A = A_initial
    else:
        A = A_final
    return (r - (A * a / (MIC + A))) * N * ((1 - N / N_max) * ((1 - N_min / N) ** c))

# Time span for the solution (from 0 to 48 time units)
t_span = (0, 48)
t_eval = np.linspace(t_span[0], t_span[1], 1000)

# Solve the ODE
sol = solve_ivp(dN_dt, t_span, [N_0], t_eval=t_eval, method='RK45')

# Plot the result with a logarithmic y-axis
plt.figure(figsize=(10, 6))
plt.plot(sol.t, sol.y[0], label='N(t)')
plt.axvline(x=T, color='red', linestyle='--', label=f'antibiotic added (t={T})')
plt.xlabel('Time (hours)')
plt.ylabel('log N (CFU/ml)')
plt.yscale('log')  # Set y-axis to logarithmic scale
plt.title('Growth of E. coli with moxifloxacin at t=15')
plt.legend()
plt.grid(True)
plt.show()
  

Graph 3 Code


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# Parameters
c = 0.72
N_max = 10**8.85
N_0 = 10**4.0
r = 0.898 # Updated r value
N_min = (1 - 1 / 10**6) * N_0
A_initial = 0.0 # A value before T
A_final = 117 * 0.0625 # A value after T
T = 15 # Time at which A changes
a = 7.5
MIC = 0.0625
# Initial conditions
S_0 = 0.735 * N_0 # Initial value for S (sensitive cells)
R_0 = 0.265 * N_0 # Initial value for R (resistant cells)
# Define the system of ODEs
def dSR_dt(t, SR):
S, R = SR
# Change A based on the time t
if t < T:
A = A_initial
else:
A = A_final
# Total population N = S + R
N = S + R
# Define dS/dt and dR/dt
dS_dt = (r - (A * a / (MIC + A))) * S * (1 - N / N_max) * ((1 - N_min / N) ** c)
dR_dt = r * R * (1 - N/ N_max) * ((1 - N_min / N) ** c)
return [dS_dt, dR_dt]
# Time span for the solution (from 0 to 48 time units)
t_span = (0, 48)
t_eval = np.linspace(t_span[0], t_span[1], 1000)
# Solve the system of ODEs
sol = solve_ivp(dSR_dt, t_span, [S_0, R_0], t_eval=t_eval, method='RK45')
# Extract S(t), R(t), and compute N(t) = S(t) + R(t)
S_t = sol.y[0]
R_t = sol.y[1]
N_t = S_t + R_t # Total population
# Plot the results with a logarithmic y-axis
plt.figure(figsize=(10, 6))
plt.plot(sol.t, S_t, label='S(t) (Sensitive)', color='blue')
plt.plot(sol.t, R_t, label='R(t) (Resistant)', color='green')
plt.plot(sol.t, N_t, label='N(t) = S(t) + R(t) (Total)', color='black', linestyle='--')
# Add a vertical line at t = T (time of disturbance)
plt.axvline(x=T, color='red', linestyle='--', label=f'moxifloxacin added (t={T})')
# Label the plot
plt.xlabel('Time (hours)')
plt.ylabel('log Population (CFU/ml)')
plt.yscale('log') # Set y-axis to logarithmic scale
plt.title('Growth of E. coli: Sensitive and Resistant Populations with moxifloxacin added at t=15')
plt.legend()
plt.grid(True)
plt.show()
  

Graph 4 Code


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# Parameters
c = 0.72
N_max = 10**8.85
N_0 = 10**4.0
r = 0.898 # Updated r value
N_min = (1 - 1 / 10**6) * N_0
A_initial = 0.0 # A value before T
A_final = 117 * 0.0625 # A value after T
T = 15 # Time at which A changes
a = 2
MIC = 0.0625
decay_rate = 0.85 # Decay rate after t = T
# Initial conditions
S_0 = 0.735 * N_0 # Initial value for S (sensitive cells)
R_0 = 0.265 * N_0 # Initial value for R (resistant cells)
# Define the system of ODEs
def dSR_dt(t, SR):
S, R = SR
# Total population N = S + R
N = S + R
if t < T:
# Before time T, use the original equations
A = A_initial
dS_dt = r * S * (1 - N / N_max) * ((1 - N_min / N) ** c)
dR_dt = (r - (A * a / (MIC + A))) * R * (1 - N / N_max) * ((1 - N_min / N) ** c)
else:
# After time T, switch to exponential decay
dS_dt = -decay_rate * S * ((1 - 1 / S) ** c)
dR_dt = -decay_rate * R * ((1 - 1 / R) ** c)
return [dS_dt, dR_dt]
# Time span for the solution (from 0 to 48 time units)
t_span = (0, 48)
t_eval = np.linspace(t_span[0], t_span[1], 1000)
# Solve the system of ODEs
sol = solve_ivp(dSR_dt, t_span, [S_0, R_0], t_eval=t_eval, method='RK45')
# Extract S(t), R(t), and compute N(t) = S(t) + R(t)
S_t = sol.y[0]
R_t = sol.y[1]
N_t = S_t + R_t # Total population
# Plot the results with a logarithmic y-axis
plt.figure(figsize=(10, 6))
plt.plot(sol.t, S_t, label='S(t) (Sensitive)', color='blue')
plt.plot(sol.t, R_t, label='R(t) (Resistant)', color='red')
#plt.plot(sol.t, N_t, label='N(t) = S(t) + R(t) (Total)', color='green', linestyle='--')
# Add a vertical line at t = T (time of disturbance)
plt.axvline(x=T, color='black', linestyle='--', label=f'OneRing added (t={T})')
# Label the plot
plt.xlabel('Time (hours)')
plt.ylabel('log Population (CFU/ml)')
plt.yscale('log') # Set y-axis to logarithmic scale
plt.title('Growth of E. coli: Sensitive and Resistant Populations with OneRing added at t=15')
plt.legend()
plt.grid(True)
plt.show()