You are on page 1of 24

Patrick Holec

Due: December 16th, 2016


A modular DNA-based platform for evaluation of soil fertility
Introduction
Human population growth continues to motivate the need for technological improvement
in food production. Despite how ubiquitous crop harvesting is as a source of food, a majority of
farms do not characterize the soil quality beyond the nitrogen content (for which, a common
solution is the addition of manure). Soil is a multifaceted material, hosting a unique microbiome
specific to every acre and a chemical composition composed of essential elements and small
molecules. Recent studies have suggested proper control of the microbiome1 and nutrient profiles2
can dramatically improve plant growth and crop yield. To this end, we need tools to measure these
two components, with the capability to be deployed rapidly in the field.
Riboswitches and DNA aptamers represent technologies that are well-suited for these purposes.
Studies have shown potential for small molecule detection via an aptamer annealing shift3 and species-
specific mRNA detection via antisense riboswitches4. By designing modular circuits that input arbitrary
metrics into a readable output, we can create a novel platform for agricultural soil evaluation. Additionally,
DNA/RNA can be produced cheaply, has great shelf life when dehydrated, and is largely nonvolatile. In
this study, we describe this DNA aptamer system, and attempt to extract principles of design in the small
molecule DNA aptamers to optimize performance. In these parts, certain regions of the aptamer benefit
from particular ranges of % GC content in improving the digital nature of the circuit. Furthermore,
increasing the overlap of strand displacement parts improves the distinct logic gating observed in the output
fluorescent signal.

Methods
DNA Aptamers for small-molecule triggered displacement cascades
The novel circuit element in my model is the used of the Hiedelberg JAWS DNA aptamer
as a mechanism for soil compound detection. This tool has only been exposed through the
International Genetically Engineered Machine (iGEM) competition, and was used for an ELISA-
like assay system. However, my proposed application attempts to utilize the nucleotide shift
induced by the presence of a small molecule to trigger a cascade down a synthetic circuit. In order
to engineer this logic gate, we must focus on the thermodynamics of this interaction and select
bases that achieve the best digital signal as possible. We will describe our model in the context of
the mechanism in Fig. 1B (small molecule detector), but these principles are easily applied to the
RNA detection scheme seen in Fig. 1A.
The aptamer is an extension of the hairpin that can be produced via computational design
and SELEX selection from the tools output by Heidelberg3 (termed MAWS/JAWS aptamer
design). Since sequences will vary based on the target molecule, we will model the published
sequence from the group that is logged on the Registry for Standard Biological Parts (ID:
BBa_K1614024). This aptamer binds the small molecule hemin. Although this is not a relevant
soil small molecule, it can serve as a model aptamer to build a framework for analysis around. The
sequence for this part is:
ACGTCCTTTGAGGGACCAAAAAGGGTAGGGCGGGTTGGG
The colors here are labeled in accordance with the structure shown in Fig. 1B.
While the aptamer is unbound to a small molecule, two nucleotides at the 5 end will remain
exposed, which can bind the soluble strand. However, while the aptamer is bound to a small
molecule, the strand base matching will shift the 5 end to reveal three additional nucleotides. The
goal of the subsequent model is to promote strand displacement in the latter case, and dissuade
displacement in the former. The system will be modeled as a finite Markov chain, in which
adjacent nucleotides will anneal based on their free energy changes between subsequent states.
These barriers involve the creation and removal of nucleic acid bonds, as well as the dissociation
of the small molecule.
There are two main degrees of freedom that will modified in this model: small molecule
affinity and support DNA sequence composition. Firstly, DNA affinity to the aptamer can be
controlled throughout SELEX. There are theoretical limits for DNA small molecule binding,
which are loosely defined as about = 1 5. Therefore, we shall consider aptamers with
affinity between 1 and 1. With a higher aptamer affinity also comes a higher energy barrier
the soluble strand must pass through in order to displace the 5 signal strand. Therefore, we will
consider the energy barrier of dissociation to be:
= ( )
This classic equation of thermodynamics will be included in the system as the soluble strand begins
annealing to the -region (see Fig. A1). Although the blue region is fixed (representing the aptamer
that directly binds hemin), the surrounding sequence can be changed to help promote competition
between the soluble strand and existing nucleic acid bonds. Manipulations of these sequences
result in various values of binding6. An outline of available states of the Markov model and
their energetic profile can be found in Fig. A2.
With these two control mechanisms, we will now consider the action of strand
displacement. When a soluble strand binds to the DNA aptamer, it is not guaranteed to strand
displace the secondary oligo. The probability this happens can be modelled through a Markov
chain, with each state corresponding to a different number of nucleotides being bound between the
soluble strand and the DNA aptamer. For a soluble strand of n bases, the system unbinds when 0
bases are bound (0 ) and the system displaces the secondary oligo when n bases are bound ( ).
At each time step, there is a number of bases bound, i, which may increase or decrease by 1
depending on the free energy difference bet nitrogen conc. = 108 ween the two adjacent states.
Therefore, we arrive at the core relationship:
1 +1

(+ = 1) = 1 +1 (+ = + 1) = 1 +1

+ +
This is derived from the Gibbs free energy state relationship. Using the energies described by
single nucleotide and the energy of small molecule binding, we can determine these probabilities
depending on whether or not a small molecule has shifted the DNA aptamer.
Reaction Kinetics
The probabilities calculated above primarily serve to help adjust the kinetics of the
molecular system shown in Fig. A3 to account for varying concentrations of RNA or small
molecules. In the case of the DNA aptamer, we will have an aptamer, , a small molecule,
, a soluble strand, , and a displaced strand, :

+ +

This reaction occurs at a rate:


[]


= +
+ [] + []
where and corresponds to the probability a strand will displace in the Markov
model when a small molecule is bound and unbound, respectively, and is the affinity of the
small molecule for the DNA aptamer. This reaction feeds into the multiple strand displacement
reactions that occur downstream. These each will carry classic binding kinetics that do not
significantly differ from the examples observed in the notes. Since strand displacement reactions
operating from DNA/RNA inputs have high fidelity, we can treat these reactions as binding limited
reactions, with one or two inputs (AND gate) behaving respectively as:
[ ] [] [ ] [1 ] [2 ]
= [1 ][2 ] ( ) and = [1 ][2 ] ( ]
) ( )
+[] +[1 +[2 ]

Where 1,2 are the soluble strand and aptamer strands, respectively, and 1 ,2 are the binding
materials (either small molecules or DNA/RNA strands). If both 1 and 2 are bound to the
aptamer in the second system, the reaction can strand displace its intended output. In our
simulation, we link such equations together to estimate fluorescent output in various
concentrations of input small molecules.
Computational Implementation
Scripts to simulate individual small molecule and RNA detecting logic gates were written
in Python from scratch using the numpy module for matrix operations. Markov models were solved
for steady state probabilities at absorbing states (strand is displaced, strand in not displaced) from
initial condition (-region binding). Additionally, stochastic simulations of single species
evolutions were made in Python to output sequences of actions representing binding events
between soluble strands and DNA aptamers. This information was visualized using an animation
script developed in MATLAB using the VideoWriter toolbox. Lastly, the kinetic systems were
simulated in MATLAB to observe overall fluorescent output.
Results
The purpose of this study was not to design a perfect circuit representing ideal conditions
for a certain crop, but rather demonstrate a means to adopt strand displacement cascades to fit
arbitrary criterion for soil content. Along the way, we aimed to extract engineering principles that
could be applied to future circuits as well. The first step in this process was identifying methods
to improve the small molecule sensor to obtain the greatest difference in strand displacement rates.
Since the -region that initiates binding between the soluble strand and DNA aptamer is present
while the ligand is both bound and unbound, there is always a positive rate at which output strands
are released. However, while ligand is bound, this region grows substantially, increasing both the
rate at which the soluble strand binds to the aptamer as well as the probability the strand will
complete its competition with the secondary strand and output the desired soluble strand. We do
not have control over the size of these regions (as they are previously determined by aptamer
selection), but we do have control over the GC content. Nucleotides G and C bind with
significantly stronger free energy of binding over A and T, and therefore can be selected to help
increase the probability of strand displacement while ligand is bound over the unbound
alternative7. Visualizations of our simulations can be found in the video presentation, which we
highly encourage readers to watch.

In our simulations, we varied the GC content of the -, -, and -regions to observe the
effect on the ratio of displacement probability difference (Fig. 2). We observe that the ratio of
probabilities shifts from a 3-fold difference to 7-fold difference by changing the GC content in the
- and - regions. Changes in the -region GC content have no significant effect on displacement
probabilities. We can justify these results by considering the effect each change makes on the
Markov chain simulation. The largest energy barrier to overcome is at the
transition between - and -regions, where latent energy must cause the ligand to dissociate.
Therefore, energy barriers introduced by GC content distal to this region should have little effect
(-region). As for the importance of the -region, increased GC content benefits the probability
the bound aptamer state more than the unbound state, but quickly plateaus around 50% GC content
here. Additional GC content only continues to benefit the unbound state, resulting in a decreased
probability difference at higher values. Lastly, passing through the -region is fairly symmetric
(since a nucleotide bond is both broken and made at each state change), which indicates there will
be little effect on overall reaction probability, although easing this transition with lower energy
bonds (little GC contend) is marginally better.
With ideal displacement probabilities set for our model system, we considered a full circuit
simulation of a simple two branch system. Each species was held to 1 M initial concentrations,
and the kinetic parameters for each logic gate were determined through estimations by literature8
for a specific -region size (toehold sequence is an alternative name). As the toeholds linearly
get larger, the values also increase exponentially. Also, since strand displacements have a high
fidelity relative to the small molecule reaction, we do not need to treat each gate with the Markov
model above and instead assume binding of an input strand (with necessary co-strands if needed)
will always lead to a strand displacement. In Fig. 3, we shown the rates of strand production in our
small molecule transducers in their optimized form, and the results of a simulated fluorescent
output for an exemplary set of ligand and RNA concentrations. Since we are primarily interested
in determining how to trigger strand cascades using small molecules, we tested the sensitivity of
our output fluorescence for ranges of ligand concentrations (Fig. A4). We found the behavior
provided the best distinct digital logical operation when the overlap toehold regions was over 10
nucleotides. Although the AND gate behavior only improves as more nucleotides are added, the
system largely plateaus its benefit at this point. Therefore, on the timescale we are interested in,
future implementations of this circuit should use an overlap of approximately 10 nucleotides to
improve digital performance in interpreting conditions.
As stated before, we built this model to try and understand some of the basic design
elements of an in vitro strand displacement circuit. The two primary conclusions we arrived at
were guidelines for the GC content in the small molecule sensor, and a general rule for the toehold
size on downstream logic gates. There is still a considerable amount of work necessary for this
model before implementation. Research defining ideal microbiome characteristics and small
molecule concentrations are an important step to making an applicable system. Additionally, we
would likely prefer to have a further optimized logical performance of the logical sensor.
Modifying the system to include multiple ligand binding sites could be a means to improve
cooperativity of binding. Regardless, what we have observed here is a positive step towards a
realistic system for real-time, portable soil testing.
Appendix A. Additional Figures
Appendix B. MATLAB Code

% Animation function

function SynBioAnimation(order,order2,fname)

%% Short Binding

close all;

figure('units','normalized','outerposition',[0 0 1 0.6]);
a = 4; b = 5; c = 10; bc = 5; d = 10; e = 2;
ylimits = [-2,8];
xlimits = [0,a+b+c+bc+d+3];
bind = 4.5; release = 4.1;

x2 = 1:a+b+c+bc+d;
y2 = (bind+1)*ones(1,a+b+c+bc+d);

parameters = {a,b,c,bc,d,e,bind,release};

v = VideoWriter(horzcat(fname,'.avi')); open(v);

for i = 1:length(order)

[x,y] = Positions(order(i)-1,parameters);
[xr,yr] = PositionsRev(order(i)-1,parameters);

xa = x(1:a); xb = x(a+1:a+b); xc = x(a+b+1:a+b+c); xbc =


x(a+b+c+1:a+b+c+bc); xd = x(a+b+c+bc+1:a+b+c+bc+d);
ya = y(1:a); yb = y(a+1:a+b); yc = y(a+b+1:a+b+c); ybc =
y(a+b+c+1:a+b+c+bc); yd = y(a+b+c+bc+1:a+b+c+bc+d);
xa2 = x2(1:a); xb2 = x2(a+1:a+b); xc2 = x2(a+b+1:a+b+c); xbc2 =
x2(a+b+c+1:a+b+c+bc); xd2 = x2(a+b+c+bc+1:a+b+c+bc+d);
ya2 = y2(1:a); yb2 = y2(a+1:a+b); yc2 = y2(a+b+1:a+b+c); ybc2 =
y2(a+b+c+1:a+b+c+bc); yd2 = y2(a+b+c+bc+1:a+b+c+bc+d);

% plot scaffold
h = plot(xa,ya,'o',xb,yb,'o',xc,yc,'o', ...
xbc,ybc,'o',xd,yd,'o','MarkerSize', 30); hold on;

set(h(1),'MarkerEdgeColor','k','MarkerFaceColor','r')
set(h(2),'MarkerEdgeColor','k','MarkerFaceColor','b')
set(h(3),'MarkerEdgeColor','k','MarkerFaceColor','y')
set(h(4),'MarkerEdgeColor','k','MarkerFaceColor','c')
set(h(5),'MarkerEdgeColor','k','MarkerFaceColor','m')

% plot soluble
h2 = plot(xa2,ya2,'o',xb2,yb2,'o',xc2,yc2,'o', ...
xbc2,ybc2,'o',xd2,yd2,'o','MarkerSize',30);

set(h2(1),'MarkerEdgeColor','k','MarkerFaceColor','r')
set(h2(2),'MarkerEdgeColor','k','MarkerFaceColor','b')
set(h2(3),'MarkerEdgeColor','k','MarkerFaceColor','y')
set(h2(4),'MarkerEdgeColor','k','MarkerFaceColor','c')
set(h2(5),'MarkerEdgeColor','k','MarkerFaceColor','m')

% plot displace
hr = plot(xr,yr,'o','MarkerSize',30);

set(hr(1),'MarkerEdgeColor','k','MarkerFaceColor','m')

% remove ticks and labels


set(gca,'XTick',[]); set(gca,'YTick',[]); set(h,'LineWidth',5);
set(h2,'LineWidth',5); set(hr,'LineWidth',5);

% plot ligand
h3 = plot(a+b+c/2 + 0.5,7,'pk','MarkerSize',24); hold off;

set(h3(1),'MarkerEdgeColor','k','MarkerFaceColor','k')

buf = 2.0;

line([a+b+.5-
0.08,a+b+c+.5+0.08],[release+buf+0.3,release+buf+0.3],'LineWidth',5,'Color',[
0,0,0]);

line([a+b+.5,a+b+.5],[release+buf+.15,release+buf+0.3],'LineWidth',5,'Color',
[0,0,0]);

line([a+b+c+.5,a+b+c+.5],[release+buf+.15,release+buf+0.3],'LineWidth',5,'Col
or',[0,0,0]);

xlim(xlimits);
ylim(ylimits);

if i <= 15
for j = 0:16-i; frame = getframe; writeVideo(v,frame); end;
elseif length(order) - i <= 15
for j = 0:16 - (length(order) - i); frame = getframe;
writeVideo(v,frame); end;
else
for j = 1:2; frame = getframe; writeVideo(v,frame); end;
end

end

%% Molecule release
if length(order2) > 0
hold on;

for i = 1:10; frame = getframe; writeVideo(v,frame); end;

for i = 0:25
buf = 2.0;
line([a+b+.5-
0.08,a+b+c+.5+0.08],[release+buf+0.3,release+buf+0.3],'LineWidth',5,'Color',(
i/25)*[1,1,1]);

line([a+b+.5,a+b+.5],[release+buf+.15,release+buf+0.3],'LineWidth',5,'Color',
(i/25)*[1,1,1]);

line([a+b+c+.5,a+b+c+.5],[release+buf+.15,release+buf+0.3],'LineWidth',5,'Col
or',(i/25)*[1,1,1]);

h3 = plot(a+b+c/2 + 0.5,7,'pk','MarkerSize',24);

set(h3(1),'MarkerEdgeColor',(i/25)*[1,1,1],'MarkerFaceColor',(i/25)*[1,1,1]);

for j = 1:2; frame = getframe; writeVideo(v,frame); end;

end
end
for i = 1:10; frame = getframe; writeVideo(v,frame); end;

%% Subsequent binding

for i = 1:length(order2)

[x,y] = Positions(order2(i),parameters);
[xr,yr] = PositionsRev(order2(i)-1,parameters);

xa = x(1:a); xb = x(a+1:a+b); xc = x(a+b+1:a+b+c); xbc =


x(a+b+c+1:a+b+c+bc); xd = x(a+b+c+bc+1:a+b+c+bc+d);
ya = y(1:a); yb = y(a+1:a+b); yc = y(a+b+1:a+b+c); ybc =
y(a+b+c+1:a+b+c+bc); yd = y(a+b+c+bc+1:a+b+c+bc+d);
xa2 = x2(1:a); xb2 = x2(a+1:a+b); xc2 = x2(a+b+1:a+b+c); xbc2 =
x2(a+b+c+1:a+b+c+bc); xd2 = x2(a+b+c+bc+1:a+b+c+bc+d);
ya2 = y2(1:a); yb2 = y2(a+1:a+b); yc2 = y2(a+b+1:a+b+c); ybc2 =
y2(a+b+c+1:a+b+c+bc); yd2 = y2(a+b+c+bc+1:a+b+c+bc+d);

% plot scaffold
h = plot(xa,ya,'o',xb,yb,'o',xc,yc,'o', ...
xbc,ybc,'o',xd,yd,'o','MarkerSize', 30); hold on;

set(h(1),'MarkerEdgeColor','k','MarkerFaceColor','r')
set(h(2),'MarkerEdgeColor','k','MarkerFaceColor','b')
set(h(3),'MarkerEdgeColor','k','MarkerFaceColor','y')
set(h(4),'MarkerEdgeColor','k','MarkerFaceColor','c')
set(h(5),'MarkerEdgeColor','k','MarkerFaceColor','m')

% plot soluble
h2 = plot(xa2,ya2,'o',xb2,yb2,'o',xc2,yc2,'o', ...
xbc2,ybc2,'o',xd2,yd2,'o','MarkerSize',30);

set(h2(1),'MarkerEdgeColor','k','MarkerFaceColor','r')
set(h2(2),'MarkerEdgeColor','k','MarkerFaceColor','b')
set(h2(3),'MarkerEdgeColor','k','MarkerFaceColor','y')
set(h2(4),'MarkerEdgeColor','k','MarkerFaceColor','c')
set(h2(5),'MarkerEdgeColor','k','MarkerFaceColor','m')

% plot displace
hr = plot(xr,yr,'o','MarkerSize',30); hold off;

set(hr(1),'MarkerEdgeColor','k','MarkerFaceColor','m')

% remove ticks and labels


set(gca,'XTick',[]); set(gca,'YTick',[]); set(h,'LineWidth',5);
set(h2,'LineWidth',5); set(hr,'LineWidth',5);

xlim(xlimits);
ylim(ylimits);

if i <= 15
for j = 0:16-i; frame = getframe; writeVideo(v,frame); end;
elseif length(order2) - i <= 10
for j = 0:11 - (length(order2) - i); frame = getframe;
writeVideo(v,frame); end;
else
for j = 1:2; frame = getframe; writeVideo(v,frame); end;
end

end

for i = 1:30; frame = getframe; writeVideo(v,frame); end;

close(v);

end

function [x2,y2] = Positions(o,parameters)

[a,b,c,bc,d,e,bind,release] = parameters{:};

total = a + b + c + bc + d;

x2 = zeros(1,total); y2 = zeros(1,total);

x = 1;

for i = 1:total
lim = max([a+b+c+1,o+1]);
if i >= lim
x2(i) = x - 1 - (i - lim);
if o > a+b+c-1
y2(i) = bind - 1.0 - 0.3*(i - lim);
else
y2(i) = release - 1.0 - 0.3*(i - lim);
end
else
x2(i) = x;
x = x + 1;
if i > o
y2(i) = release;
else
y2(i) = bind;
end
end
end

end

function [x2,y2] = PositionsRev(o,parameters)

[a,b,c,bc,d,e,bind,release] = parameters{:};

subtotal = a + b + c + bc;
total = a + b + c + bc + d;

x2 = zeros(1,total-subtotal); y2 = zeros(1,total-subtotal);

x = total;

for i = 1:total-subtotal
lim = o-subtotal+1; ir = total-subtotal-i;
if lim >= ir
x2(i) = x + 1 + (lim-ir);
y2(i) = bind - 1.0 - 0.3*(lim-ir);
else
x2(i) = x;
x = x - 1;
y2(i) = bind;
end
end

end

%% Heatmap

set(0,'defaultAxesFontName', 'Times New Roman')

data = [[2.9467710664871709, 6.4419091223269183, 6.4330972530787083,


6.4246352700892126, 6.4165114372937797, 6.4087142291274368,
6.4012323437568854, 6.3940547143664395, 6.3871705186325478,
6.3805691865184091, 6.3742404065164884], [6.6935377154725293,
6.68080554769345, 6.6685875593941386, 6.6568657654600383, 6.6456225725473734,
6.6348407923285322, 6.624503652178511, 6.6145948035035493, 6.605098327905595,
6.5959987413680192, 6.5872809966392776], [6.8759411970499835,
6.8597876302497536, 6.8443006928039525, 6.8294558347735919,
6.8152291557765992, 6.8015974108853623, 6.7885380138462086,
6.7760290378717816, 6.7640492142432791, 6.7525779289460255,
6.7415952175479052], [6.9931418783385242, 6.9739003992842248,
6.9554683982987671, 6.9378147259938823, 6.9209091802700655,
6.9047225001264296, 6.8892263570839267, 6.8743933444947043,
6.8601969649916672, 6.8466116163141155, 6.8336125757277086],
[7.0451547769381238, 7.0233069417944849, 7.0023936121443286,
6.9823774846287021, 6.9632225126983638, 6.9448938850672866,
6.9273580024398944, 6.9105824527742241, 6.8945359853218555,
6.879188483664894, 6.8645109379508513], [7.03646537244017,
7.0125752718103875, 6.9897213911716278, 6.9678611074118235,
6.9469533475094769, 6.9269585502997222, 6.9078386274287062,
6.8895569237193452, 6.8720781771496284, 6.8553684786244711,
6.8393952317032767], [6.9747125276612678, 6.9493614165984363,
6.9251225787920569, 6.9019491461588514, 6.8797960557474722,
6.8586199953487252, 6.8383793493191432, 6.8190341447819733,
6.8005459983501639, 6.7828780634980665, 6.7659949786920102],
[6.8691917585426747, 6.8429258400796895, 6.8178230259184609,
6.7938333616411946, 6.7709089017114206, 6.7490036408599927,
6.7280734466884367, 6.7080759935865242, 6.6889706980451527,
6.6707186554314521, 6.6532825782800531], [6.7295390196593425,
6.7028360704111014, 6.6773242569692091, 6.6529516526274657,
6.6296684877811494, 6.6074270698126361, 6.5861817050845657,
6.5658886230711646, 6.5465059026471533, 6.5279934005436759,
6.5103126819716204], [6.5647845161295404, 6.5380386692138091,
6.5124926985827338, 6.4880936909462807, 6.4647909853249166,
6.4425360844002446, 6.4212825687000494, 6.4009860135897831,
6.3816039090354799, 6.3630955820973609, 6.3454221221081397],
[6.3828060167157474, 6.3563264252671097, 6.3310400014031414,
6.3068936625572061, 6.283836627285714, 6.2618203208974492,
6.2407982844681538, 6.2207260871640049, 6.2015612417949422,
6.1832631235162436, 6.1657928915951912]];
data = reshape(data,11,11);
databind = [[0.2962017729534519, 0.65060565351838062, 0.65268008273617972,
0.65467217807338696, 0.65658469806315645, 0.65842035209029393,
0.66018179724304416, 0.66187163562536344, 0.66349241209785859,
0.66504661241629415, 0.66653666173746928], [0.70162940961471665,
0.70361160265562761, 0.70551377157734763, 0.70733871314465713,
0.70908916343899742, 0.71076779577060401, 0.71237721899092832,
0.71391997617390079, 0.71539854363579525, 0.71681533026471667,
0.71817267713209287], [0.75146030531679064, 0.75322788536886853,
0.75492253867210013, 0.75654694922825827, 0.758103730189715,
0.7595954231946872, 0.761024497997003, 0.76239335236284966,
0.76370431220846324, 0.76495963195423655, 0.7661614950722111],
[0.79666498559279053, 0.7981974112958774, 0.79966538209649118,
0.80107137705166875, 0.80241779994575646, 0.80370697976846961,
0.80494117138421584, 0.80612255637086772, 0.80725324400767828,
0.80833527239347791, 0.80937060967770247], [0.83642632960718444,
0.83772013600891371, 0.83895861191001841, 0.84014396507513767,
0.84127832897177457, 0.84236376403471003, 0.84340225903359278,
0.84439573252810107, 0.84534603439634959, 0.84625494742344165,
0.84712418893820929], [0.87041476508681737, 0.87148104298556384,
0.87250107911404085, 0.87347677487341358, 0.87440996257896453,
0.87530240715766006, 0.8761558078826891, 0.87697180013496401,
0.87775195718255161, 0.87849779196990152, 0.87921075890959288],
[0.89873103972845181, 0.89959119824072153, 0.90041362310312911,
0.90119990380330961, 0.90195156865602688, 0.90267008664175774,
0.90335686923862024, 0.90401327224203742, 0.90464059756718507,
0.90524009502988245, 0.90581296410215617], [0.92179499574708301,
0.92247615182238474, 0.9231271491946309, 0.9237492827814836,
0.9243437954607735, 0.92491187984463985, 0.92545468002255293,
0.92597329327067457, 0.92646877172541353, 0.92694212401941467,
0.92739431687855123], [0.94021919076891747, 0.94075018896668183,
0.94125750409192976, 0.9417421683119187, 0.94220517094176337,
0.9426474600335697, 0.94306994392400889, 0.94347349273969272,
0.94385893985993663, 0.94422708333670202, 0.94457868727168171],
[0.95469658981317296, 0.95510513398309649, 0.95549535229723503,
0.95586805269924102, 0.95622400876055147, 0.95656396103151875,
0.956888618349509, 0.95719865910437685, 0.95749473246182892,
0.95777745954527838, 0.95804743457687824], [0.96591693582713434,
0.96622787478449168, 0.96652480458367129, 0.96680834832124252,
0.96707910209646319, 0.96733763611718993, 0.96758449576623917,
0.96782020262907709, 0.96804525548374865, 0.96826013125399213,
0.96846528592650327]];
databind = reshape(databind,11,11);
dataunbind = [[0.10051740236018822, 0.10099578264205188, 0.101456585694212,
0.10190028702816871, 0.10232736347152478, 0.10273829173062372,
0.10313354707190385, 0.10351360211826802, 0.10387892575629999,
0.1042299821497869, 0.10456722985472247], [0.10482191024230081,
0.10531837779630478, 0.10579658215381454, 0.10625701915378413,
0.10670018582881877, 0.10712657892144482, 0.10753669352369644,
0.10793102183610086, 0.10831005204166891, 0.108674267290119,
0.10902414478727912], [0.109288355409321, 0.10980338254894995,
0.11029944073991667, 0.11077704688800277, 0.11123671895128355,
0.11167897440960282, 0.11210432886208828, 0.11251329474855712,
0.11290638019018344, 0.1132840879444149, 0.11364691446884052],
[0.11392089556490842, 0.1144549485360877, 0.11496930706953981,
0.1154645098910321, 0.11594109661679519, 0.11639960617588227,
0.11684057536540743, 0.11726453753427474, 0.11767202139051977,
0.11806354992699973, 0.11843963945988158], [0.1187236272431053,
0.11927716429760261, 0.11981026180176493, 0.12032348106711013,
0.12081738411167983, 0.12129253203507352, 0.12174948353131697,
0.12218879353492439, 0.1226110119950134, 0.12301668277194791,
0.1234063426506954], [0.12370056825632711, 0.12427403759768552,
0.12482630283605493, 0.12535794864571606, 0.12586956019971626,
0.12636172149749425, 0.12683501383540849, 0.12729001441525625,
0.12772729508537428, 0.12814742120852007, 0.12855095065044736],
[0.12885563901940639, 0.12944947662270992, 0.13002132638931388,
0.13057179714296435, 0.13110149797282503, 0.1316110365137472,
0.13210101737461555, 0.1325720407095779, 0.13302470092646296,
0.13345958552629972, 0.13387727406757052], [0.13419264276626416,
0.134807270074352, 0.13539910697084603, 0.13596878722358482,
0.13651694460504935, 0.13704421112547849, 0.1375512154193356,
0.13803858127963692, 0.13850692633414785, 0.1389568608570648,
0.1393889867095188], [0.13971524468796565, 0.14035106618816404,
0.14096327628683408, 0.14155253449647334, 0.14211950004412743,
0.14266483005771563, 0.14318917791107313, 0.14369319172191308,
0.14417751299640266, 0.1446427754136613, 0.14508960374321378],
[0.14542695003430853, 0.14608435072133746, 0.14671730111961162,
0.14732648729057252, 0.14791259468885865, 0.14847630630237568,
0.14901830095653701, 0.14953925177654986, 0.15003982480112046,
0.15052067774056321, 0.15098245887203263], [0.15133108123567005,
0.15201042396810013, 0.15266446024183411, 0.15329390347279748,
0.15389946611552668, 0.15448185775770557, 0.15504178338439881,
0.1555799418055234, 0.15609702423958705, 0.15659371304635189,
0.15707068060081167]];
dataunbind = reshape(dataunbind,11,11);

figure;
subplot(1,3,1);
colormap('jet');
imagesc(0:10:100,0:10:100,databind);
c = colorbar; c.Label.String = 'Probability';
caxis([0.5,0.9]);
title('Strand displacement w/ ligand bound');
xlabel('% GC Content in alpha region');
ylabel('% GC Content in beta region');

subplot(1,3,2);
colormap('jet');
imagesc(0:10:100,0:10:100,dataunbind);
c = colorbar; c.Label.String = 'Probability';
title('Strand displacement w/o ligand bound');
xlabel('% GC Content in alpha region');
ylabel('% GC Content in beta region');

subplot(1,3,3);
colormap('jet');
imagesc(0:10:100,0:10:100,data);
c = colorbar; c.Label.String = 'Ratio (P_{ligand}/P_{no ligand})';
caxis([6,7]);
title('Comparison of w & w/o ligand');
xlabel('% GC Content in alpha region');
ylabel('% GC Content in beta region');

%% Important graph

close all;

set(0,'defaultAxesFontName', 'Times New Roman')

Kd = 1e-6;
k_0 = 7.67e4;
ratio = 7;
overlaps = [1,4];
prob = [.12,.85];

k_on_unbound = k_0*exp(overlaps(1)/2.14);
k_on_bound = k_0*exp(overlaps(2)/2.14);

conc = logspace(-12,-3,25);

rate = prob(2)*k_on_bound*conc./(Kd + conc) + prob(1)*k_on_unbound*Kd./(Kd +


conc);
rate_bad = .3*k_on_bound*conc./(Kd + conc) + .3*k_on_unbound*Kd./(Kd + conc);
rate_classic = k_on_bound*conc./(Kd + conc);

semilogx(conc,rate,'LineWidth',6); hold on;


semilogx(conc,rate_bad,'LineWidth',6);

xlabel('Ligand Concentration (M)');


ylabel('Rate of strand displacement (1/s)');
legend({'Optimized GC Concent','Unoptimized GC
Concent'},'Location','northwest');
title('Strand Displacement Rates');

xlim([1e-12,1e-3]);

%% Rate calculator

close all;

time_total = 60; res = 100000;


time = linspace(0,time_total,res);
overlap = [1,6,12];
data = zeros(7,7);

for aa = 1:3

for i = -9:-3
for j = -9:-3

rate1 = 1e-12*(prob(2)*k_on_bound*10^i./(Kd + 10^i) +


prob(1)*k_on_unbound*Kd./(Kd + 10^i));
rate2 = 1e-12*(prob(2)*k_on_bound*10^j./(Kd + 10^j) +
prob(1)*k_on_unbound*Kd./(Kd + 10^j));

k3 = 1e-12*k_0*exp(overlap(aa)/4.14);

s1 = zeros(1,res); s2 = zeros(1,res); s3 = zeros(1,res);

for k = 2:res

s1(k) = s1(k-1) + (time_total/res)*(rate1 - k3*s1(k-1)*s2(k-


1)/((Kd + s1(k-1))*(Kd + s2(k-1))));
s2(k) = s2(k-1) + (time_total/res)*(rate2 - k3*s1(k-1)*s2(k-
1)/((Kd + s1(k-1))*(Kd + s2(k-1))));
s3(k) = s3(k-1) + (time_total/res)*(k3*s1(k-1)*s2(k-1)/((Kd +
s1(k-1))*(Kd + s2(k-1))));

end

if i == -9 && j == -8
figure;

plot(time,s1,'LineWidth',6); hold on;


plot(time,s2,'LineWidth',6);
plot(time,s3,'LineWidth',6);
xlabel('Time (seconds)');
ylabel('Concentration');
legend({'Intermediate (1)','Intermediate (2)','Product (3)'});
end
data(i+10,j+10) = s3(end);

end
end

figure;

subplot(1,3,aa);
colormap('jet');
imagesc(-9:-3,-9:-3,data);
c = colorbar; c.Label.String = 'Flourescence Concentration [M]';
title('Output Flourescence');
xlabel('Ligand 1 [10^{n} M]');
ylabel('Ligand 2 [10^{n} M]');

end

Appendix C. Python Code

'''

This code was designed for a riboswitch network simulation


Course: Principles of Synthetic Biology
Creation Date: 12/5/16

'''

# standard libraries
import math
import random

# non-standard libraries
import numpy as np

global RT
global kJ_to_kcal
RT = 2.14
kJ_to_kcal = 4.184

def main():
sim = Simulation()
sim.simulation()

class Simulation:
def __init__(self):
# simulation declarations
seq = 'AAGGTGGGAAAAAGGGTAGGGCGGGTTGGG'
self.a_length,self.b_length,self.c_length,self.bc_length,self.d_length = 4,5,10,5,10
self.ligand_affinity = 1e-6
self.nt_E = -1
self.nt_E1 = -1
self.nt_E2 = -1
def transitions(self,size = 'small'):

a,b,c,bc,d = self.a_length,self.b_length,self.c_length,self.bc_length,self.d_length
nt_E = self.nt_E
nt_E1,nt_E2 = self.nt_E1,self.nt_E2

ligand_E = RT*math.log(self.ligand_affinity)/kJ_to_kcal
self.substates = a + b + 2
self.states = a + b + c + bc + d + 2

if size == 'small':
# secondary calculations
transitions = np.zeros((self.substates,self.substates))
transitions[0][0],transitions[self.substates-1][self.substates-1] = 1,1

# alpha region
for i in xrange(1,a):
transitions[i][i-1] = math.exp(nt_E1/RT)/(math.exp(-nt_E1/RT) + math.exp(nt_E1/RT))
transitions[i][i+1] = math.exp(-nt_E1/RT)/(math.exp(-nt_E1/RT) + math.exp(nt_E1/RT))

transitions[a][a-1] = math.exp(nt_E1/RT)/(math.exp(nt_E1/RT) + 1)
transitions[a][a+1] = 1./(math.exp(nt_E1/RT) + 1)

# beta region
for i in xrange(a+1,a+b):
transitions[i][i-1] = 0.5
transitions[i][i+1] = 0.5

transitions[a+b][a+b-1] = 1./(1+math.exp((ligand_E-nt_E2)/RT))
transitions[a+b][a+b+1] = math.exp((ligand_E-nt_E2)/RT)/(1+math.exp((ligand_E-nt_E2)/RT))

self.starting_condition = np.zeros((self.substates,1))
self.starting_condition[a][0] = 1
self.transition = np.transpose(transitions)

if size == 'large':
# secondary calculations
transitions = np.zeros((self.states,self.states))
transitions[0][0],transitions[self.states-1][self.states-1] = 1,1

# alpha region
for i in xrange(1,a):
transitions[i][i-1] = math.exp(nt_E1/RT)/(math.exp(-nt_E1/RT) + math.exp(nt_E1/RT))
transitions[i][i+1] = math.exp(-nt_E1/RT)/(math.exp(-nt_E1/RT) + math.exp(nt_E1/RT))

transitions[a][a-1] = math.exp(nt_E1/RT)/(math.exp(nt_E1/RT) + 1)
transitions[a][a+1] = 1./(math.exp(nt_E1/RT) + 1)

# beta region
for i in xrange(a+1,a+b):
transitions[i][i-1] = 0.5
transitions[i][i+1] = 0.5

transitions[a+b][a+b-1] = 1./(1+math.exp((-nt_E2)/RT))
transitions[a+b][a+b+1] = math.exp((-nt_E2)/RT)/(1+math.exp((-nt_E2)/RT))
# gamma/betaC region
for i in xrange(a+b+1,a+b+c+bc):
transitions[i][i-1] = math.exp(nt_E/RT)/(math.exp(-nt_E/RT) + math.exp(nt_E/RT))
transitions[i][i+1] = math.exp(-nt_E/RT)/(math.exp(-nt_E/RT) + math.exp(nt_E/RT))

transitions[a+b+c+bc][a+b+c+bc-1] = math.exp(nt_E2/RT)/(math.exp(nt_E2/RT) + 1)
transitions[a+b+c+bc][a+b+c+bc+1] = 1./(math.exp(nt_E2/RT) + 1)

# delta region
for i in xrange(a+b+c+bc+1,a+b+c+bc+d):
transitions[i][i-1] = 0.5
transitions[i][i+1] = 0.5

transitions[a+b+c+bc+d][a+b+c+bc+d-1] = 0.5
transitions[a+b+c+bc+d][a+b+c+bc+d+1] = 0.5

self.starting_condition = np.zeros((self.states,1))
self.starting_condition[a+b+1][0] = 1
self.transition = np.transpose(transitions)

def simulation(self,size = 'small'):


if size == 'small':
self.transitions('small')
result = np.matmul(np.linalg.matrix_power(self.transition, 2000),self.starting_condition)
return result[-1][0]/(result[0][0] + result[-1][0])

if size == 'large':
self.transitions('large')
result = np.matmul(np.linalg.matrix_power(self.transition, 2000),self.starting_condition)
return result[-1][0]/(result[0][0] + result[-1][0])

def series(self, size = 'small'):


if size == 'small':
self.transitions('small')
series = [self.a_length + 2]
while series[-1] != 0 and series[-1] != len(self.transition):
if random.random() < self.transition[series[-1]-1][series[-1]]:
series.append(series[-1]-1)
else:
series.append(series[-1]+1)
print 'Small (pre-ligand release) series:\n',series

elif size == 'large':


self.transitions('large')
series = [self.a_length + self.b_length + 2]
while series[-1] != 0 and series[-1] != len(self.transition):
if random.random() < self.transition[series[-1]-1][series[-1]]:
series.append(series[-1]-1)
else:
series.append(series[-1]+1)
print 'Large (post-ligand release) series:\n',series
sim = Simulation()

data = []
databind = []
dataunbind = []

for i in xrange(0,11):

data.append([])
databind.append([])
dataunbind.append([])

for j in xrange(0,11):

sim.nt_E1,sim.nt_E2 = -0.5 - 1.*float(i)/10.,-0.5 - 1.*float(j)/10.

sim.a_length = 4
sim.b_length = 5
sim.c_length = 10
sim.bc_length = 5
sim.d_length = 10

bind = sim.simulation('small')*sim.simulation('large')

sim.a_length = 1
sim.b_length = 10
sim.c_length = 3
sim.bc_length = 10
sim.ligand_affinity = 1

unbind = sim.simulation('small')*sim.simulation('large')

data[-1].append(bind/unbind)
databind[-1].append(bind)
dataunbind[-1].append(unbind)

print data
print databind
print dataunbind

1
Chaparro, Jacqueline M., et al. "Manipulating the soil microbiome to increase soil health and
plant fertility." Biology and Fertility of Soils 48.5 (2012): 489-499.
2
Gil-Sotres, F., et al. "Different approaches to evaluating soil quality using biochemical
properties." Soil Biology and Biochemistry 37.5 (2005): 877-887.
3
"Heidelberg IGEM 2015." Team Hiedelberg. N.p., n.d. Web. 16 Nov. 2016.
4
Andre, Gaelle, et al. "S-box and T-box riboswitches and antisense RNA control a sulfur
metabolic operon of Clostridium acetobutylicum." Nucleic acids research 36.18 (2008): 5955-
5969.
5
Ahmad, Kareem M., et al. "Probing the limits of aptamer affinity with a microfluidic SELEX
platform." PloS one 6.11 (2011): e27051.
6
Protozanova E, Yakovchuk P, Frank-Kamenetskii MD (2004). "StackedUnstacked
Equilibrium at the Nick Site of DNA". J Mol Biol. 342 (3): 775
785. doi:10.1016/j.jmb.2004.07.075. PMID 15342236.
7
J. SantaLucia, D. Hicks, The Thermodynamics of Dna Structural Motifs. Annual Review of
Biophysics and Biomolecular Structure. 33, 415440 (2004).
8
Ouldridge, Thomas E. et al. DNA Hybridization Kinetics: Zippering, Internal Displacement
and Sequence Dependence. Nucleic Acids Research 41.19 (2013): 88868895. PMC. Web. 14
Dec. 2016.

You might also like