None
This notebook contains material from cbe30338-2021; content is available on Github.
Chemotaxis is a behavior exhibited by single organisms in response to gradients of certain chemicals. In the presence of gradient of an attractant or repellant, the normally random motion of cells changes causing a net movement towards or away from the source of the chemical. This behavior is contributes to foraging for feed, fleeing from poisons, or to serve the needs of a large organism in development, injury, infection, and reproduction.
By <a href="//commons.wikimedia.org/w/index.php?title=User:Fortinda&action=edit&redlink=1" class="new" title="User:Fortinda (page does not exist)">Fortinda</a> - <span class="int-own-work" lang="en">Own work</span>, CC BY-SA 4.0, Link
For many organisms such as E. coli, the movement consists of alternating tumbling and swimming phases. The tumbling results in a new random direction. If cell senses that it is moving in the 'right' direction (i.e., towards an attractant or away from a repellant), the swimming phase will last somewhat longer. The biochemical mechanisms for this behavior is part of a signal transduction pathways for chemotactic organisms.
Here we create a simulation of chemotaxis using Simpy. This is an exercise to demonstrate the utility of discrete-event simulation, so no attempt has been made to reproduce results from the current literature on the topic. See, for example.
Motivated by Brown and Berg (1974), we assume:
Followning a
$$\tau = \begin{cases} \tau_0 & \text{for} & \nabla_{\|}C \leq 0 \\ \tau_0\left(1 + \frac{\nabla_{\|}C}{\nabla C_0}\right) & \text{for} & 0 < \nabla_{\|}C \leq \nabla C_0 \\ 2\tau_0 & \text{for} & \nabla_{\|}C > \nabla C_0 \end{cases}$$where $\nabla C_0$ is the threshold gradient at which the maximum run time is reached, and $\nabla_{\|}C$ is a projection of the concentration gradient in the direction of swimming. We will assume E. coli swim at an average speed of 25$\mu$/s, and $\tau_0$ is one second.
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import simpy
# dimension in mm
x_max = 10.0
y_max = 10.0
tau = 1.0
V = 0.025
# dictionary to store tracks of each bacteria
tracks = {}
# concentration gradient
def C(x, y):
return 1.0*x
# agent model
def swimmer(id, x_pos, y_pos):
# store initial position of particle n
tracks[id] = {0: (x_pos, y_pos)}
# variable to track distance traveled
s = 0
# angle traveliing
a = np.random.uniform(0, 2*np.pi)
# velocity
vx, vy = v*np.cos(a), v*np.sin(a)
while True:
yield env.timeout(dt)
dx = vx*dt
dy = vy*dt
x += dx
y += dy
track[n][env.now] = (x, y)
p = np.random.uniform()
if p <= 1.0*c(x,y)/(1 + c(x,y)):
s = 0
else:
s += np.sqrt(dx**2 + dy**2)
if s >= 2.0:
s = 0
a = np.random.uniform(0, 2*np.pi)
vx, vy = v*np.cos(a), v*np.sin(a)
env = simpy.Environment()
for n in range(1000):
env.process(agent(n, np.random.uniform(0, x_max), np.random.uniform(0, y_max)))
env.run(until=1000)
fig, ax = plt.subplots(1, 1, figsize=(10, 10))
for n in track.keys():
pos = track[n].values()
ax.plot([x for x,y in pos], [y for x,y in pos], lw=0.6, alpha=0.6)
ax.axis('equal')
ax.axis('square')
(-53.345298544605306, 157.7309369739553, -108.16799315508639, 102.9082423634742)
plt.hist([x for x,y in pos], bins = 100);