%% For reasons of simplicity, this functions produces % a figure based on the input argument as: % allen_simulation_supplement(FigureNumber) % where FigureNumber is an integer between 2 and 6. %This is the main funtion. It takes an integer argument and %runs the simulations for and displays the figure of that number function acNet = allen_simulation_supplement(input) if nargin() == 0 input=2; %Tf there was no argument provided, default to this input %To generate figure X by default, change this parameter to X end switch input case 1 %Error message; no or invalid argument provided disp('Format: "allen_simulation_supplement([integer between 2-6])"'); case 2 %run figure function runs the simulation and constructs the appropriate figure data. %the acNet struct is returned by runFigure2 which includes %the full results of the simualtion acNet=runFigure2(); case 3 %run figure function runs the simulation and constructs the appropriate figure data. %the acNet struct is returned by runFigure3 which includes %the full results of the simualtion acNet=runFigure3(); case 4 %run figure function runs the simulation and constructs the appropriate figure data. %the acNet struct is returned by runFigure4 which includes %the full results of the simualtion acNet=runFigure4(); case 5 %run figure function runs the simulation and constructs the appropriate figure data. %Figure 5 requires two acNet variables; only the second is returned acNet=runFigure5(); case 6 %run figure function runs the simulation and constructs the appropriate figure data. %Figure 6 runFigure6(); case 7 %run figure function runs the simulation and constructs the appropriate figure data. %Figure 7 requires two internal acNet variables; only the second is returned acNet=runFigure7(); case 8 %run figure function runs the simulation and constructs the appropriate figure data. %Figure 7 requires two internal acNet variables; only the second is returned acNet=runFigure8(); end end %% Figure 2 % Set up a 1-D simulation and show the effects of complementary % stationary phase DNA on a diffusing oligonucleotide % show the change in a sharp peak due to diffusion then show % that the result is altered by the DNA-DNA interaction function acNet = runFigure2() %ac1Test_DoubleDiffTest() runs a diffusion simulation with two separate %diffusing species. One diffuses freely (Species 1) and the other %interacts with the fixed gel (Species 2). %In this simulation, the duration is 100 sec divided into 100 time steps %the simulation size 100 um divided into 100 units and the diffusion %coefficients are 0.1e-8 cm^2/sec as 0.1 units^2/sec acNet = ac1Test_DoubleDiffTest(); %Run the simulation figure; %Generate a plot of several time points with Species 1. View = ac1ExtractReagent( acNet, 1, true ); %Extract Species 1 simLength = length(View(:,end)); %note the number of time points simWidth= round(length(View(end,:))/2); %we only need to plot half simWidthTicks=0:(5/(simWidth-1)):5; %Set the scale in mm subplot(1,2,1); %start with Fig 2A %Plot four time points in different colors: plot(simWidthTicks,View(round(simLength*1/4),1:simWidth),'Color',[1 0 0]); hold on; plot(simWidthTicks,View(round(simLength*2/4),1:simWidth),'Color',[1 0.6 0]); plot(simWidthTicks,View(round(simLength*3/4),1:simWidth),'Color',[0 0.498 0]); plot(simWidthTicks,View(simLength,1:simWidth),'Color',[0.07843 0.1686 0.549]); %For Fig 1B, we need to compare Species 1 with total Species 2. View = ac1ExtractReagent( acNet, 1, true ); %first, extract Species 1 %Plot Species 1 subplot(1,2,2);plot(0:(10/(length(View(end,:))-1)):10,View(end,:),'Color','red'); hold on; %Species 2 equilibrates between a free state (Species 2) and a bound %state (Species 4). We sum these. View = ac1ExtractReagent( acNet, 2, true ); View = View + ac1ExtractReagent( acNet, 4, true ); %Plot the sum of Species 2 and 4 subplot(1,2,2);plot(0:(10/(length(View(end,:))-1)):10,View(end,:)); hold off; end function acNet = ac1Test_DoubleDiffTest() %This function sets up and runs the Fig 2 simulation width = 100; %The spatial width of the simulation is (100) 1 um units %Initialize the simulation and the struct (acNet) and pass the function %handle for the reaction system (ac1_SpecificAssociation_DY)v acNet = ac1Create( width, @ac1_SpecificAssociation_DY ); %Set up initial conditions as zeros, then add spots to Species 1 & 2 %note that all concentrations are in micromolar acNet = ac1CreateICs( acNet, 'zeros' ); %Species R1 2 uM spot at 25% of the width acNet = ac1CreateICs( acNet, 'add-spot', 1, 2.0, round(width/4) ); %Species R2 2 uM spot at 75% of the width acNet = ac1CreateICs( acNet, 'add-spot', 2, 2.0, round((3*width)/4)); %Species 3 is the immobile species that binds to 2; it is uniformly %distributed across the whole region %Species R2 2 uM spot at 75% of the width acNet = ac1CreateICs( acNet, 'add-spot', 3, 2.0, [1:width] ); %Now we set up the diffusion constants for the DNA %Species 1 and 2 are equal and positive (diffusive species, D = 0.1) %Diffusion constants are .1 unit^2 per sec where units are 100 um %Species 3 is the bound, evenly distributed DNA and species 4 is the %conjugate between species 2 and 3 and is thus also immobile (D = 0) acNet.diff = [ 0.1; 0.1; 0 ; 0]; acNet.bounded = 0; %Note that the boundary conditions are Neumann duration = 100; %100 sec duration of the simulation acNet = ac1RunODE45( acNet, duration ); end function dy = ac1_SpecificAssociation_DY( acNet, y ) %ac1_SpecificAssociation_DY is the reaction system specification for %the solver. If no arguments are passed in, it returns the number of %nodes in the system. If argements are passed in, it acts on y to %produce dy and returns the change in the ocncentrations due to the %inter-reactivity. if nargin == 0 dy = [4 0]; return; end dy = [ 0 0 0 0 ]; %reaction system: %R1 just diffuses (unreactive) %R2 + *R3 <-> *R4 (* denotes immobile) %rates are Kf for the forward and Kr for the reverse reaction %Derived from 50% bound at 2 uM concentration (all in uM): %Keq=(R3 / (R2 * R1)) = 1 %Since Keq=(R3 / (R2 * R1)) = Kf/Kr Kf=1; %(1x10^-6 M^-1) inverse micromolar (fast relative to diffusion but not faster than ODE45 can handle Kr=1/Kf; dy(2)=-(y(2)*y(3)*Kf)+(y(4)*Kr); dy(3)=-(y(2)*y(3)*Kf)+(y(4)*Kr); dy(4)=(y(2)*y(3)*Kf)-(y(4)*Kr); end %% Figure 3 function acNet = runFigure3() %ac1Test_OuchterlonyTest(K1, K2) runs a simulation where two species %(left and right) diffuse toward each other and react to form a %product in between. Figure 3 shows this simulation in %several ways including a time-course of the simulation for different %reagents (left, right, and product) and product eveolved at different %locations depending on the speed of the reagents. %Run the first simulation with a slow right side, fast left to generate %a product at left. %Fig 3A: %In this simulation, the duration is 5000 sec divided into 5000 time steps %the simulation size 70 um divided into (70) 1 um units and the diffusion %coefficients are 0.4e-8 cm^2/sec as 0.4 units^2/sec %this runs the simulation, with two different binding strengths as arguments acNet = ac1Test_OuchterlonyTest(.1, .5); figure; which=1; %Pull Species 1 for i=[ 1000 4000 7000 9990 ] %Pull the date at four time points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(1,4,1); plot(View(i,:),'LineWidth',2,'Color',hsv2rgb([abs(sin(1+.2*i)), 1, 1])); hold on; end xlim([0 length(View(which,:))]); hold off; %Fig 3B which=2; %Pull Species 2 for i=[1000 4000 7000 9990 ] %Pull the date at four time points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(1,4,2); plot(View(i,:),'LineWidth',2,'Color',hsv2rgb([abs(sin(1+.2*i)), 1, 1])); hold on; end xlim([0 length(View(which,:))]); hold off; %Fig 3C which=6; %Pull Species 6 for i=[1000 4000 7000 9990 ] %Pull the date at four time points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(1,4,3); plot(View(i,:),'LineWidth',2,'Color',hsv2rgb([abs(sin(1+.2*i)), 1, 1])); hold on; end xlim([0 length(View(which,:))]); hold off; %in the Fig 3D , show the final time point for Species 6 which=6; % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); subplot(1,4,4); plot(View(end,:),'LineWidth',1,'Color',[1, 0, 0]); xlim([0 length(View(which,:))]); hold on; %Re-run the simulation with equal effective diffusion coefficients acNet = ac1Test_OuchterlonyTest(.25, .25); %in the fourth plot, overlay the final time point for Species 6 which=6; % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); subplot(1,4,4); plot(View(end,:),'LineWidth',1,'Color',[1, 0, 0]); xlim([0 length(View(which,:))]); hold on; %Re-run the simulation with fast left and slow right diffusion by adjusting binding equilibrium acNet = ac1Test_OuchterlonyTest(.5, .1); %in the fourth plot, overlay the final time point for Species 6 which=6; % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); subplot(1,4,4); plot(View(end,:),'LineWidth',1,'Color',[1, 0, 0]); xlim([0 length(View(which,:))]); hold on; end function acNet = ac1Test_OuchterlonyTest(lk1, rk1) %ac1Test_OuchterlonyTest(LeftK, RightK) runs a simulation where two species %diffuse toward each other at different rates as determined by %equilibrium with an immobile species. Those equilibria is defined by %equilibrium coefficients, LeftK and RightK, which are passed as arguments %the simulation size 70 um divided into (70) 1 um units and the diffusion width = 70; %The dY function includes all of the reaction network, and relies on %the equilibrium constants which must be added to the acNet struct acNet = ac1Create( width, @ac1_Ouchterlony_DY ); acNet.rk1=rk1; acNet.lk1=lk1; %create initial conditions with two initial spots of Species 1 (at %left) and Species 2 (at right) and Species 3 (everywhere, fixed) with %which the others can equilibrate. acNet = ac1CreateICs( acNet, 'zeros' ); acNet = ac1CreateICs( acNet, 'add-spot', 1, 2.0, 1 ); acNet = ac1CreateICs( acNet, 'add-spot', 2, 2.0, width); acNet = ac1CreateICs( acNet, 'add-spot', 3, 2.0, [1:width] ); acNet.bounded=1; %Dirchlet (constant) boundary conditions %Set up diffusion coefficients which are equal for Species 1 and 2 %and are 0.4e-8 cm^2/sec as 0.4 units^2/sec and %zero for all other, fixed species. acNet.diff = [ 0.4; 0.4; 0 ; 0 ; 0 ; 0 ]; duration = 5000; %5000 sec divided into 5000 time steps acNet = ac1RunODE45( acNet, duration ); end function dy = ac1_Ouchterlony_DY( acNet, y ) %ac1_Ouchterlony_DY is the reaction system specification for %the solver. If argements are passed in, it acts on y to %produce dy and returns the change in the ocncentrations due to the %inter-reactivity. if nargin == 0 dy = [6 0]; return; end %Pulls lk1 and rk1, the kinetic rate constants for the itneractions %between the mobile Species 1 and 3 and Species 2 and 3 respectively. lk1=acNet.lk1; rk1=acNet.rk1; pk=2; dy = [ 0 0 0 0 0 0 ]; %1+2->6 and 1+3<->5 dy(1)=-(y(1)*y(2)*pk)-(y(1)*y(3)*lk1)+(y(5)*.1); %1+2->6 and 2+3<->4 dy(2)=-(y(1)*y(2)*pk)-(y(2)*y(3)*rk1)+(y(4)*.1); %2+3<->4 and 1+3<->5 dy(3)=-(y(2)*y(3)*rk1)+(y(4)*.1)-(y(1)*y(3)*lk1)+(y(5)*.1); %2+3<->4 dy(4)=(y(2)*y(3)*rk1)-(y(4)*.1); %1+3<->5 dy(5)=(y(1)*y(3)*lk1)-(y(5)*.1); %1+2->6 dy(6)=(y(1)*y(2)*pk); end %% Figure 4 function acNet = runFigure4 () %Figure 4 shows a series through time in which a product is deveoped by %diffusion of reactive species into the gel. %In this simulation, the duration is 30 min divided into 30 time steps %the simulation size 100 um divided into (30) 3.3 um units and the diffusion %coefficients are 0.15e-8 cm^2/sec as 1 units^2/sec %Rrun the simulation with ac2Test_Ouchterlony, passing a set of %diffusion coefficients, all equal at 1 units^2/sec . The second input variable %determines the number of points in the simulation (30x30 units) acNet = ac2Test_Ouchterlony([1;1;1;1;1;1;0;0;0], 30); which=9; View = ac2ExtractReagent( acNet, which, false ); numFrames = size(View,1); figure; subPlotNum=1; for t=round(3*numFrames/8):(round(numFrames/8)):numFrames subplot(5,1,subPlotNum); V = reshape( View(t,:), acNet.dim, acNet.dim ); imagesc( V ); caxis( [ 0 2e-002 ] ); colormap('hot'); subPlotNum=subPlotNum+1; end end function acNet = ac2Test_Ouchterlony(diff, dim) %ac2Test_Ouchterlony(diff, dim) runs a simulation where four species %("north", "south", "east", "west") diffuse into the gel and produce a %product in a central region. Input variable "diff" sets the diffusion %coefficients for the different species. Input variable dim sets the %size of the simulation. acNet = ac2Create( dim, @ac2_Ouchterlony_DY ); acNet.diff =diff; %Set up initial conditions. Each edge gets a reagent. %North edge gets an initial conditions of 1 on species 1 image=zeros(dim); image(1:3,:)=image(1:3,:)+1; acNet = ac2CreateICs( acNet, 'add-mat', 1, image ); %South edge gets an initial conditions of 1 on species 2 image=zeros(dim); image(end-2:end,:)=image(end-2:end,:)+1; acNet = ac2CreateICs( acNet, 'add-mat', 2, image ); %East edge gets an initial conditions of 1 on species 4 image=zeros(dim); image(:,1:3)=image(:,1:3)+1; acNet = ac2CreateICs( acNet, 'add-mat', 4, image ); %West edge gets an initial conditions of 1 on species 5 image=zeros(dim); image(:,end-2:end)=image(:,end-2:end)+1; acNet = ac2CreateICs( acNet, 'add-mat', 5, image ); %A universal substrate that reacts with initial products to form final %product. All concentrations are equal. image=ones(dim); acNet = ac2CreateICs( acNet, 'add-mat', 7, image ); duration = 30; %(30) 1 min time steps acNet.bounded = 1; %Note that the boundary conditions are Neumann acNet = ac2Run( acNet, duration ); end function dy = ac2_Ouchterlony_DY( acNet, y ) %ac2_Ouchterlony_DY is the reaction system specification for %the solver. If argements are passed in, it acts on y to %produce dy and returns the change in the ocncentrations due to the %inter-reactivity. if nargin == 0 dy = [9 0]; return; end dy = [ 0 0 0 0 0 0 0 0 0]; %rate constants for product formation k1=10; k2=10; kn1=0.1; kn2=0.1; k3=10; %1+2<->3 North (1) and South (2) react to form intermediate (3) dy(1)=-(y(1)*y(2)*k1)+(y(3)*kn1); dy(2)=-(y(1)*y(2)*k1)+(y(3)*kn1); %1+2<->3 and 3+7->8 %Intermediate product (3) reacts with fixed species (7) to form (8) dy(3)= (y(1)*y(2)*k1)-(y(3)*kn1)-(y(3)*y(7)*k3); %4+5<->6 East (1) and West (2) react to form intermediate (6) dy(4)=-(y(4)*y(5)*k2)+(y(6)*kn2); dy(5)=-(y(4)*y(5)*k2)+(y(6)*kn2); %Intermediate product (6) reacts with fixed species (8) to form final (9) dy(6)= (y(4)*y(5)*k2)-(y(6)*kn2)-(y(6)*y(8)*k3); %Intermediate product (3) reacts with fixed species (7) to form (8) %3+7->8 dy(7)=-(y(3)*y(7)*k3); %Intermediate product (6) reacts with fixed species (8) to form final (9) %3+7->8 and 6+8->9 dy(8)= (y(3)*y(7)*k3)-(y(6)*y(8)*k3); %Intermediate products form final (9) %6+8->9 dy(9)= (y(6)*y(8)*k3); end %% Figure 5 function acNet = runFigure5() %Figure 5 uses the same reaction as Fig 4, ac2Test_Ouchterlony, calling %this with five different sets of diffusion constants to simulate five %different orthogonal reaction systems that would run in parallel in %the gel. %set up the array of different diffusion conditions to use. Each set of diffusion %coefficients represents a "pixel". The first three coefficients control the north-south %species, while coefficients 4-6 control the east-west species. Last three are the %immobile products. %In this simulation, the duration is 30 min divided into 30 time steps %the simulation size 100 um or 150 divided into (30) or (45) 3.3 um units %and the diffusion coefficients are ~0.15e-8 cm^2/sec as ~1 units^2/sec %Here we set up all the diffusion cases we are interested in as units^2/sec diffarray{1}=[.22; 1.1; 1; .6; .6; 1; 0; 0; 0]; %1,2 left middle diffarray{2}=[.22; 1.1; 1; .22; 1.1; 1; 0; 0; 0]; %1,1 left top diffarray{3}=[.65; .65; 1.2; .2; 1; 1; 0; 0; 0]; %2,1 top middle diffarray{4}=[1.1; .22; 1; .22; 1.1; 1; 0; 0; 0]; %3,1 right top diffarray{5}=[1.1; .22; 1; .6; .6; 1; 0; 0; 0]; %3,2 right middle %Figure 5 B: 30 unit square; note that units are (3.3 um) %run the simulation 5 times for the five diffusion conditions %put the output from species 9 from each simulation into an array for i=1:5 acNet= ac2Test_Ouchterlony(diffarray{i}, 30); figure; which = 9; View = ac2ExtractReagent( acNet, which, false ); t=length(acNet.T); V = reshape( View(t,:), acNet.dim, acNet.dim ); arrayofV{i}=V; end % add up the arrays we generated and display them V=zeros(acNet.dim,acNet.dim); for i= 1:length(arrayofV) V=V+arrayofV{i}; end %generate the plot subplot(1,2,1) imagesc( V ); colormap('hot'); caxis( [ 0 max(V(:)) ] ); axis equal; xlim([1,acNet.dim]); ylim([1,acNet.dim]); %Figure 5 C: 45 unit square; note that units are (3.3 um) %to show tha the results scale, run the simulation again but %with a larger simulated space, 45 units instead of 30 %run the simulation 5 times for the same five diffusion conditions %put the output from species 9 from each simulation into an array for i=1:5 acNet= ac2Test_Ouchterlony(diffarray{i}, 45); figure; which = 9; View = ac2ExtractReagent( acNet, which, false ); t=length(acNet.T); V = reshape( View(t,:), acNet.dim, acNet.dim ); arrayofV{i}=V; end % add up the arrays we generated and display them V=zeros(acNet.dim,acNet.dim); for i= 1:length(arrayofV) V=V+arrayofV{i}; end %generate the plot subplot(1,2,2) imagesc( V ); colormap('hot'); caxis( [ 0 max(V(:)) ] ); axis equal; xlim([1,acNet.dim]); ylim([1,acNet.dim]); end %% Figure 6 function y1 = runFigure6() % show the relationship between rate and feature width % We experimentally measured 1mm of diffusion in 15 h in 5% acrylamide % 1 mm = 100 (10 um) units = 2 squareroot(D T) % solve('2*sqrt(x*54000)-100') % D=.0463 units^2/sec where *1 unit is 10 um* % so, multiply by 10^-6 to get cm^2sec^-1 or 4.6e-8 cm^2sec^-1 %In this simulation, the duration is 5000 sec divided into 5000 time steps %the simulation size 150-600 um or 15-60 (10 um) units %and the diffusion coefficients are ~4.6e-8 cm^2/sec as ~.046 units^2/sec nativeDiffusion = .046; %units^2 per sec; units are 10 um diffs1=[ .2:.1:1 ]*nativeDiffusion; %larger fractions native diffusion width=60; %600 um gel, contrasted with smaller below y1=[]; count=1; figure; for diffout= diffs1 %for each of the cases we want toe xamine, set up a simulation with a rate %coefficient scaled to 10^6/mol/sec. Unfortunately, the ODE45 solver won't %handle concentrations at the micromolar (10^-6) level so it was necessary %to work at micromolar scale and reduce the rate constant to 1 acNet = ac1Test_WidthTest(diffout, 1, width); %diff, rate, width %rate units are 10^6/mol/sec which=6 ; %examine Species 6 View = ac1ExtractReagent( acNet, which, true ); numFrames=size(View,1); fwhmvar=fwhm(1:width, View(numFrames,:)); y1=[y1 fwhmvar]; count=count+1; end subplot(2,1,1); plot(diffs1, y1); diffs2=[ .01:.01:.09 ]*nativeDiffusion; %slower diffusions for a smaller gel width=15; %contrast with 150 um at a different range of slower diffusions y2=[]; count=1; for diffout=diffs2 acNet = ac1Test_WidthTest(diffout, 1, width); %diff, rate, width %rate is in %10^6/mol/sec which=6 ; %Pull Species 6 View = ac1ExtractReagent( acNet, which, true ); numFrames=size(View,1); fwhmvar=fwhm(1:width, View(numFrames,:)); y2=[y2 fwhmvar]; count=count+1; end subplot(2,1,2); plot(diffs2, y2); end function acNet = ac1Test_WidthTest(diffin, ratein, width) %ac1Test_OuchterlonyTest(LeftK, RightK) runs a simulation where two species %diffuse toward each other at different rates as determined by %equilibrium with an immobile species. Those equilibria is defined by %equilibrium coefficients, LeftK and RightK, which are passed as arguments %The dY function includes all of the reaction network, and relies on %the equilibrium constants which must be added to the acNet struct acNet = ac1Create( width, @ac1_WidthTest_DY ); acNet.pk=ratein; %create initial conditions with two initial spots of Species 1 (at %left) and Species 2 (at right) and Species 3 (everywhere, fixed) with %which the others can equilibrate. acNet = ac1CreateICs( acNet, 'zeros' ); %add initial conditions: 'add-spot', species, concentration, location %concentrations are in micromolar (10^-6) units acNet = ac1CreateICs( acNet, 'add-spot', 1, 2, 1 ); acNet = ac1CreateICs( acNet, 'add-spot', 2, 2, width); acNet = ac1CreateICs( acNet, 'add-spot', 3, 2, 1:width ); acNet.bounded=1; %Dirchlet (constant) boundary conditions %Set up diffusion coefficients which are equal for Species 1 and 2 and %zero for all other, fixed species. acNet.diff = [ diffin; diffin; 0 ; 0 ; 0 ; 0 ]; duration = 5000; %5000 sec in 1 sec units acNet = ac1RunODE45( acNet, duration ); %reaction rate is given as 10^6/mol/sec and spots are in 10 %micromolar units so time step is seconds %(reaction proceeds over 5000 seconds) end function dy = ac1_WidthTest_DY( acNet, y ) %ac1_Ouchterlony_DY is the reaction system specification for %the solver. If argements are passed in, it acts on y to %produce dy and returns the change in the ocncentrations due to the %inter-reactivity. if nargin == 0 dy = [6 0]; return; end %simplified verstion: only product is evolved. Diffusion is set. pk=acNet.pk; dy = [ 0 0 0 0 0 0 ]; %1+2->6 dy(1)=-(y(1)*y(2)*pk); %1+2->6 dy(2)=-(y(1)*y(2)*pk); %1+2->6 dy(6)=(y(1)*y(2)*pk); end function width = fwhm(x,y) % Full width, half max calculation function by Patrick Egan % published at mathworks.com 31 Mar 2006, last Updated 05 Apr 2006 % http://www.mathworks.com/matlabcentral/fileexchange/10590-fwhm % % function width = fwhm(x,y) % % Full-Width at Half-Maximum (FWHM) of the waveform y(x) % and its polarity. % The FWHM result in 'width' will be in units of 'x' % % % Rev 1.2, April 2006 (Patrick Egan) % Copyright (c) 2009, Patrick Egan % All rights reserved. % % Redistribution and use in source and binary forms, with or without % modification, are permitted provided that the following conditions are % met: % % * Redistributions of source code must retain the above copyright % notice, this list of conditions and the following disclaimer. % * Redistributions in binary form must reproduce the above copyright % notice, this list of conditions and the following disclaimer in % the documentation and/or other materials provided with the distribution % % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE % IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE % ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE % LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE % POSSIBILITY OF SUCH DAMAGE. y = y / max(y); N = length(y); lev50 = 0.5; if y(1) < lev50 % find index of center (max or min) of pulse [garbage,centerindex]=max(y); Pol = +1; disp('Pulse Polarity = Positive') else [garbage,centerindex]=min(y); Pol = -1; disp('Pulse Polarity = Negative') end i = 2; while sign(y(i)-lev50) == sign(y(i-1)-lev50) i = i+1; end %first crossing is between v(i-1) & v(i) interp = (lev50-y(i-1)) / (y(i)-y(i-1)); tlead = x(i-1) + interp*(x(i)-x(i-1)); i = centerindex+1; %start search for next crossing at center while ((sign(y(i)-lev50) == sign(y(i-1)-lev50)) & (i <= N-1)) i = i+1; end if i ~= N Ptype = 1; disp('Pulse is Impulse or Rectangular with 2 edges') interp = (lev50-y(i-1)) / (y(i)-y(i-1)); ttrail = x(i-1) + interp*(x(i)-x(i-1)); width = ttrail - tlead; else Ptype = 2; disp('Step-Like Pulse, no second edge') ttrail = NaN; width = NaN; end end %% Figure 7 function acNet2 = runFigure7() %Figure 7 uses two simulations to show the perioduc structures that can be %developed with ereaction-diffusion sytems. Figure 7A uses the full %Soloveichik 15-element simulation in 1D to show periodicity in time. %Figure 7B shows the idealized 2-element simulator in 2-D to show %periodicity in space. %Call the 1D simulation with full 15-element simulation acNet=ac1Test_SoloveichikTest; figure; %Plot the time-trace through the center point for two species (1 and 5) in %red and green, respectively subplot(2,3,3); View = ac1ExtractReagent( acNet, 1, true );plot(View(:,25),'Color','red'); hold on; View = ac1ExtractReagent( acNet, 5, true );plot(View(:,25),'Color','green'); hold off; %Plot species 1 across its one dimension through time with grayscale values subplot(2,3,1); View = ac1ExtractReagent( acNet, 1, true ); imagesc( View ); colormap('gray'); %Plot species 5 across its one dimension through time with grayscale values subplot(2,3,2); View = ac1ExtractReagent( acNet, 5, true ); imagesc( View ); colormap('gray'); %Call the 2D simulation with idealized 2-element simulation acNet2=ac2Test_SoloveichikTest; %Plot species 1 across at one time point with grayscale intensity map subplot(2,3,4); View = ac2ExtractReagent( acNet2, 1, false ); numFrames = size(View,1); t=numFrames; V = reshape( View(t,:), acNet2.dim, acNet2.dim ); imagesc( V ); %Plot species 5 across at one time point with grayscale intensity map subplot(2,3,5); View = ac2ExtractReagent( acNet2, 2, false ); numFrames = size(View,1); t=numFrames; V = reshape( View(t,:), acNet2.dim, acNet2.dim ); imagesc( V ); end function acNet = ac1Test_SoloveichikTest() %In this simulation, the duration is 7200 sec divided into 7200 steps %the simulation size 500 um divided into (50) 10 um units %and the diffusion coefficients are ~0.1e-8 cm^2/sec as ~.001 units^2/sec width = 50; %50 (10 um) units acNet = ac1Create( width, @ac1_Soloveichik_DY ); acNet = ac1CreateICs( acNet, 'zeros' ); acNet = ac1CreateICs( acNet, 'add-spot', 1, 20e-9, 25); acNet = ac1CreateICs( acNet, 'add-spot', 5, 10e-9, 25); % X1 L1 H1 B1 X2 O1 LS2 HS2 BS2 T1 G2 O2 T2 G3 O3 % 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 % 10 10 10 10 10 10 10 10 e-6 acNet = ac1CreateICs( acNet, 'add-spot', 2, 10*1e-6, [1:width]); acNet = ac1CreateICs( acNet, 'add-spot', 3, 20e-9, 25); acNet = ac1CreateICs( acNet, 'add-spot', 4, 10*1e-6, [1:width]); acNet = ac1CreateICs( acNet, 'add-spot', 7, 10*1e-6, [1:width]); acNet = ac1CreateICs( acNet, 'add-spot', 8, 10e-9, 25); acNet = ac1CreateICs( acNet, 'add-spot', 9, 10*1e-6, [1:width]); acNet = ac1CreateICs( acNet, 'add-spot', 10, 10*1e-6, [1:width]); acNet = ac1CreateICs( acNet, 'add-spot', 11, 10*1e-6, [1:width]); acNet = ac1CreateICs( acNet, 'add-spot', 13, 10*1e-6, [1:width]); acNet = ac1CreateICs( acNet, 'add-spot', 14, 10*1e-6, [1:width]); acNet.bounded=1; acNet.diff = zeros(15, 1)*0; acNet.diff(1)=.001; %0.001 units^2/sec where units are 10um acNet.diff(5)=.001; %0.001 units^2/sec where units are 10um duration = 7200; %time in seconds acNet = ac1RunEuler( acNet, duration ); %use an euler method solver %ode45 fails to converge end function dy = ac1_Soloveichik_DY( acNet, y ) if nargin == 0 dy = [15 0]; return; end tscale=300; cscale=1e-8; k1=(1.5/tscale)/(cscale); k2=(1/tscale); k3=(1/tscale); cmax=1e-5; gmma=.5; q1=(k1/gmma); %module 1 constants qmax1=1e6; s=k1; s2=0; qs2=(s-s2)/gmma; q2=k2/gmma/cmax; %module 2 constants qmax2=1e6; q3=k3/gmma/cmax; %module 3 constants %key dy=y*0; %dy = [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]; % X1 L1 H1 B1 X2 O1 LS2 HS2 BS2 T1 G2 O2 T2 G3 O3 % 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 %Module 1: X1(1) + X2(5) -> X2(5) + X2(5) %X1(1) + L1(2) <-> H1(3) +B1(4) fwd=(y(1)*y(2)*q1); bak=(y(3)*y(4)*qmax1); dy(1)=dy(1)-fwd+bak; dy(2)=dy(2)-fwd+bak; dy(3)=dy(3)+fwd-bak; dy(4)=dy(4)+fwd-bak; %X2(5) + H1(3) -> O1(6) fwd=(y(3)*y(5)*qmax1); dy(5)=dy(5)-fwd; dy(3)=dy(3)-fwd; dy(6)=dy(6)+fwd; %X2(5)+LS2(7) <-> HS2(8) + BS2(9) fwd=(y(5)*y(7)*qs2); bak=(y(8)*y(9)*qmax1); dy(5)=dy(5)-fwd+bak; dy(7)=dy(7)-fwd+bak; dy(8)=dy(8)+fwd-bak; dy(9)=dy(9)+fwd-bak; %O1(6)+ T1(10) -> 2 X2(5) fwd=(y(6)*y(10)*qmax1); dy(6) =dy(6) -fwd; dy(10)=dy(10)-fwd; dy(5) =dy(5) +2*fwd; %Module 2: X1(1) + G2(11) -> X1(5) + X1(5) %X1(1) + G2(11) -> O2(12) fwd=(y(1)*y(11)*q2); dy(1) =dy(1) -fwd; dy(11)=dy(11)-fwd; dy(12)=dy(12)+fwd; %O2(12) + T2(13) -> 2X1(1) fwd=(y(12)*y(13)*qmax2); dy(12)=dy(12)-fwd; dy(13)=dy(13)-fwd; dy(1) =dy(1) +2*fwd; %Module 3: X2(5) -> NULL %X2(5) + G3(14) -> O3(15) fwd=(y(5)*y(14)*q3); dy(5) =dy(5) -fwd; dy(14)=dy(14)-fwd; dy(15)=dy(15)+fwd; end function acNet = ac2Test_SoloveichikTest() %In this 2D simulation, the duration is 28 min is divided into 28 steps %the simulation size 100 um divided into (30) 3.3 um units %and the diffusion coefficients are ~0.15e-8 cm^2/sec as ~.2 units^2/sec dim = 30; %30 (3.3 um) units acNet = ac2Create( dim, @ac2Test_SoloveichikDy ); acNet.diff =[0.2;0.2;0]; %0.2 units^2/sec image=(importdata('ispotsouth.bmp')); image=10*image.cdata; acNet = ac2CreateICs( acNet, 'add-mat', 1, image ); image=(importdata('ispotsouth.bmp')); image=10*image.cdata; acNet = ac2CreateICs( acNet, 'add-mat', 2, image ); image=(importdata('iconst30.bmp')); image=5*image.cdata; acNet = ac2CreateICs( acNet, 'add-mat', 3, image ); duration = 28; %time steps in min acNet.bounded = 1; acNet = ac2Run( acNet, duration ); end function dy = ac2Test_SoloveichikDy( acNet, y ) % Test pulse if nargin == 0 dy = [3 0]; return; end %rate constants for product formation dy = [ 0 0 0 ]; k1=1.5; k2=1; k3=1; %1+2-> 2+2 dy(1)=dy(1)-(y(1)*y(2)*k1); dy(2)=dy(2)+(y(1)*y(2)*k1); %1 -> 1+1 dy(1)=dy(1)+(y(1)*k2); %2 -> X(sink) dy(2)=dy(2)-(y(2)*k3); end %% Figure 8 function acNet = runFigure8() acNet = ac1Test_OuchterlonyTestFig8(); %run the simulation figure; timepoints=[1000:4000:length(acNet.T)]; colors=colormap(hot(length(acNet.T)*1.5)); which=5; %Pull Species A for i=timepoints %Pull the date at four points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(2,3,1); % plot(View(i,:),'LineWidth',2,'Color',hsv2rgb([i/(6*length(acNet.T)), 1, 1])); plot(View(i,:),'LineWidth',2,'Color',colors(i,:)); hold on; end xlim([0 length(View(which,:))]); ylim([0 .05]); hold off; which=6; %Pull Species B for i=timepoints %Pull the date at four points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(2,3,2); plot(View(i,:),'LineWidth',2,'Color',colors(i,:)); hold on; end xlim([0 length(View(which,:))]); ylim([0 .05]); hold off; which=7; %Pull Species D for i=timepoints %Pull the date at four points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(2,3,3); plot(View(i,:),'LineWidth',2,'Color',colors(i,:)); hold on; end xlim([0 length(View(which,:))]); ylim([0 .05]); hold off; which=8; %Pull Species DA for i=timepoints %Pull the date at four points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(2,3,4); plot(View(i,:),'LineWidth',2,'Color',colors(i,:)); hold on; end xlim([0 length(View(which,:))]); ylim([0 .05]); hold off; which=10; %Pull Species DAB for i=timepoints %Pull the date at four points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(2,3,5); plot(View(i,:),'LineWidth',2,'Color',colors(i,:)); hold on; end xlim([0 length(View(which,:))]); ylim([0 .05]); hold off; which=11; %Pull Species DBA for i=timepoints %Pull the date at four points % SPLICE out a view of one reagent View = ac1ExtractReagent( acNet, which, true ); % overlay plots of each reagent at different times subplot(2,3,6); plot(View(i,:),'LineWidth',2,'Color',colors(i,:)); hold on; end xlim([0 length(View(which,:))]); ylim([0 .05]); hold off; end function acNet = ac1Test_OuchterlonyTestFig8() %ac1Test_OuchterlonyTest(LeftK, RightK) runs a simulation where two species %diffuse toward each other at different rates as determined by %equilibrium with an immobile species. Those equilibria is defined by %equilibrium coefficients, LeftK and RightK, which are passed as arguments %In this 2D simulation, the duration of 15000 sec is divided into 15000 steps %the simulation size 70 um divided into (70) 1 um units %and the diffusion coefficients are ~0.6e-8 cm^2/sec as ~.6 units^2/sec width = 70; %(70) 1 um units %The dY function includes all of the reaction network, and relies on %the equilibrium constants which must be added to the acNet struct acNet = ac1Create( width, @ac1_Ouchterlony_DYFig8 ); %create the initial conditions acNet = ac1CreateICs( acNet, 'zeros' ); acNet = ac1CreateICs( acNet, 'add-spot', 1, 2.0, 1 ); %1 is A0 acNet = ac1CreateICs( acNet, 'add-spot', 2, 2.0, width); %2 is A1 acNet = ac1CreateICs( acNet, 'add-spot', 3, 2.0, 1); %3 is B0 acNet = ac1CreateICs( acNet, 'add-spot', 4, 2.0, width ); %4 is B1 %5 is A %6 is B acNet = ac1CreateICs( acNet, 'add-spot', 7, 2.0, 1 ); %7 is D %8 is DA %9 is DB %10 is DAB %11 is DBA acNet.bounded=1; %(d/dx=0) boundary conditions %Set up diffusion coefficients which are equal for Species 1 and 2 and %zero for all other, fixed species. % [ 1 2; 3; 4; 5; 6; 7; 8; 9; 10; 11 ]; DD=.04;% ~.04 units^2/sec where units are um acNet.diff = [ .1; .6; .6; .1; 0; 0; DD; DD; DD; DD; DD ];% ~.6 units^2/sec where units are um duration = 15000; %time steps are seconds acNet = ac1RunODE45( acNet, duration ); end function dy = ac1_Ouchterlony_DYFig8( acNet, y ) %ac1_Ouchterlony_DY is the reaction system specification for %the solver. If argements are passed in, it acts on y to %produce dy and returns the change in the ocncentrations due to the %inter-reactivity. if nargin == 0 dy = [11 0]; return; end %pk is product kinetic constant pk=.6; %1 is A0 %2 is A1 %3 is B0 %4 is B1 %5 is A %6 is B %7 is D %8 is DA %9 is DB %10 is DAB %11 is DBA dy = [ 0 0 0 0 0 0 0 0 0 0 0 ]; dyt=0; %1+2->5 dyt=(y(1)*y(2)*pk); dy(1)=dy(1)-dyt; dy(2)=dy(2)-dyt; dy(5)=dy(5)+dyt; %3+4->6 dyt=(y(3)*y(4)*pk); dy(3)=dy(3)-dyt; dy(4)=dy(4)-dyt; dy(6)=dy(6)+dyt; %7+5->8 dyt=(y(7)*y(5)*pk); dy(7)=dy(7)-dyt; dy(5)=dy(5)-dyt; dy(8)=dy(8)+dyt; %7+6->9 dyt=(y(7)*y(6)*pk); dy(7)=dy(7)-dyt; dy(6)=dy(6)-dyt; dy(9)=dy(9)+dyt; %8+6->10 dyt=(y(8)*y(6)*pk); dy(8)=dy(8)-dyt; dy(6)=dy(6)-dyt; dy(10)=dy(10)+dyt; %9+5->11 dyt=(y(9)*y(5)*pk); dy(9)=dy(9)-dyt; dy(5)=dy(5)-dyt; dy(11)=dy(11)+dyt; end %% global functions function acNet = ac1RunODE45( acNet, duration ) icRowVec = reshape( acNet.ICs, 1, size(acNet.ICs,1)*size(acNet.ICs,2) ); [acNet.T,acNet.Y] = ode45( @ac1Dy, [0 duration], icRowVec, [], acNet ); end function acNet = ac1RunEuler( acNet, duration ) icRowVec = reshape( acNet.ICs, 1, size(acNet.ICs,1)*size(acNet.ICs,2) ); tstep=.01; tseries=0:duration; result=zeros(length(tseries), length(icRowVec)); result(1,:)=icRowVec; lastresult=icRowVec; currentresult=0*icRowVec; for i=1+tstep:tstep:length(tseries) currentresult= lastresult+(tstep*ac1Dy(i, lastresult,acNet))'; if (rem(i,1000/tstep)==0) [i length(tseries)] end result(round(i),:)=currentresult; lastresult=currentresult; end acNet.T=tseries; acNet.Y=result; end function acNet = ac2Run( acNet, duration ) % The initial conditions are stored in a list of spatial matricies dim = acNet.dim; nc = acNet.nodeCount; icRowVec = zeros( 1, dim * dim * nc ); for y=0:dim-1 for x=0:dim-1 for i=0:nc-1 icRowVec(y*dim*nc+x*nc+i+1) = acNet.ICs{i+1}(y+1,x+1); end end end [acNet.T,acNet.Y] = ode45( @ac2Dy, [0 duration], icRowVec, [], acNet ); end function acNet = ac1Create( xDim, dyFunc ) nc_gc = dyFunc(); acNet.nodeCount = nc_gc(1); acNet.gateCount = nc_gc(2); acNet.xDim = xDim; acNet.diff = ones( acNet.nodeCount, 1 ); acNet.ICs = zeros( acNet.nodeCount, xDim ); acNet.capacitance = 1; acNet.dyFunc = dyFunc; acNet.gateConc = ones( 1, acNet.gateCount ); acNet.pullDown = 1; end function acNet = ac2Create( dim, dyFunc ) nodeCount_gateCount = dyFunc(); acNet.nodeCount = nodeCount_gateCount(1); acNet.gateCount = nodeCount_gateCount(2); acNet.dim = dim; % This is the dimension of one side of the square acNet.diff = ones( acNet.nodeCount, 1 ); for i=1:acNet.nodeCount acNet.ICs{i} = zeros( dim, dim ); end acNet.capacitance = 1; acNet.dyFunc = dyFunc; acNet.gateConc = ones( 1, acNet.gateCount ); acNet.pullDown = 1; end function acNet = ac2CreateICs( acNet, method, parameter1, parameter2, parameter3, parameter4 ) nc = acNet.nodeCount; dim = acNet.dim; for i=1:nc ICs = acNet.ICs{i}; switch method case 'add-mat', % parameter1 is which node to add to % parameter2 is matrix that will be added if i == parameter1 ICs = ICs + parameter2; end case 'add-spot', % parameter1 is which node to add to % parameter2 is how much % parameter3,parameter4 are x,y if i == parameter1 ICs(parameter3,parameter4) = ICs(parameter3,parameter4) + parameter2; end case 'add-const', % parameter1 is which node to add to % parameter2 is how much if i == parameter1 ICs = ICs + parameter2; end end acNet.ICs{i} = ICs; end end function acNet = ac1CreateICs( acNet, method, parameter1, parameter2, parameter3, parameter4 ) nc = acNet.nodeCount; xd = acNet.xDim; ICs = zeros( nc, xd ); switch method case 'zeros', ICs = zeros( nc, xd ); case 'ones', ICs = ones( nc, xd ); case 'minus-ones', ICs = -ones( nc, xd ); case 'test', ICs = [ ones( 1, xd ); -ones( 1, xd ) ]; case 'noise-strong', ICs = rand( nc, xd ) - 0.5; case 'noise-weak', ICs = (rand( nc, xd )-0.5) / 30; case 'gaussian-one', ICs = zeros( nc, xd ); for( x=0:xd-1 ) xf = x / xd; ICs(1,x+1) = ICs(1,x+1) + parameter2 * exp( -(xf-0.5)*parameter1 .* (xf-0.5)*parameter1 ); end case 'gaussian-one-plus-noise', ICs = (rand( nc, xd )-0.5) / 50; for( x=0:xd-1 ) xf = x / xd; ICs(1,x+1) = ICs(1,x+1) + parameter2 * exp( -(xf-0.5)*parameter1 .* (xf-0.5)*parameter1 ); end case 'uniform-specified', ICs = repmat( parameter1', 1, xd ); case 'gaussian-add', % parameter1 is the width of the Gaussian % parameter2 is the size of the Gaussian % parameter3 is the normalized x position % parameter4 is which reagent to add to ICs = acNet.ICs; for( x=0:xd-1 ) xf = x / xd; ICs(parameter4,x+1) = acNet.ICs(parameter4,x+1) + parameter2 * exp( -(xf-parameter3)*parameter1 .* (xf-parameter3)*parameter1 ); end case 'add-spot', % parameter1 is which node to add to % parameter2 is how much % parameter3 is where in space ICs = acNet.ICs; ICs(parameter1,parameter3) = acNet.ICs(parameter1,parameter3) + parameter2; end acNet.ICs = ICs; end function dy = ac2Dy( t, y, acNet ) nodeCount = acNet.nodeCount; dim = acNet.dim; % COMPUTE the force on each node by calling the function pointer that % defines the network and then apply diffusion dy = zeros( nodeCount * dim * dim, 1 ); for( yc = 0:dim-1 ) for( xc = 0:dim-1 ) i = yc*nodeCount*dim + xc*nodeCount; j = i + nodeCount; acNet.currentX = xc / dim; acNet.currentY = yc / dim; % CALL the DY function that describes the specific network dy(i+1:j) = acNet.dyFunc( acNet, y(i+1:j) ); % DIFFUSE circular and apply capacitance correction if(acNet.bounded==1) %gradient=0 boundary conditions for( k = 1:nodeCount ) if yc == 0 top = y((yc )*nodeCount*dim + nodeCount*xc +k ); else top = y((yc-1)*nodeCount*dim + nodeCount*xc +k ); end if yc == dim-1 bot = y((yc )*nodeCount*dim + nodeCount*xc +k ); else bot = y((yc+1)*nodeCount*dim + nodeCount*xc +k ); end if xc == 0 lft = y(yc*nodeCount*dim + nodeCount*(xc ) +k ); else lft = y(yc*nodeCount*dim + nodeCount*(xc-1) +k ); end if xc == dim-1 rgt = y(yc*nodeCount*dim + nodeCount*(xc ) +k ); else rgt = y(yc*nodeCount*dim + nodeCount*(xc+1) +k ); end dy(i+k) = dy(i+k) + acNet.diff(k) * ( lft - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( rgt - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( top - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( bot - y(i+k) ); dy(i+k) = dy(i+k) / acNet.capacitance; end elseif(acNet.bounded==2) %constant boundary conditions for( k = 1:nodeCount ) if (yc == 0 || yc == dim-1 || xc == 0 || xc == dim-1) dy(i+k) = 0; else top = y((yc-1)*nodeCount*dim + nodeCount*xc +k ); bot = y((yc+1)*nodeCount*dim + nodeCount*xc +k ); lft = y(yc*nodeCount*dim + nodeCount*(xc-1) +k ); rgt = y(yc*nodeCount*dim + nodeCount*(xc+1) +k ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( top - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( bot - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( lft - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( rgt - y(i+k) ); dy(i+k) = dy(i+k) / acNet.capacitance; end end else %toroidal boundary conditions xm = mod( xc-1+dim, dim ); xp = mod( xc+1+dim, dim ); ym = mod( yc-1+dim, dim ); yp = mod( yc+1+dim, dim ); for( k = 1:nodeCount ) dy(i+k) = dy(i+k) + acNet.diff(k) * ( y(yc*nodeCount*dim + nodeCount*xm +k ) - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( y(yc*nodeCount*dim + nodeCount*xp +k ) - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( y(ym*nodeCount*dim + nodeCount*xc +k ) - y(i+k) ); dy(i+k) = dy(i+k) + acNet.diff(k) * ( y(yp*nodeCount*dim + nodeCount*xc +k ) - y(i+k) ); dy(i+k) = dy(i+k) / acNet.capacitance; end end end end end function dy = ac1Dy( t, y, acNet ) nodeCount = acNet.nodeCount; xDim = acNet.xDim; % COMPUTE the force on each node by calling the function pointer that % defines the network and then apply diffusion dy = zeros( nodeCount * xDim, 1 ); for( x = 0:xDim-1 ) i = x*nodeCount+1; j = i+nodeCount-1; % CALL the DY function that describes the specific network dy(i:j) = acNet.dyFunc( acNet, y(i:j) ); %DIFFUSE if(acNet.bounded==1) %do bounded conditions if x == 0 lft = 0; else lft = x-1; end if x == xDim-1 rgt = x; else rgt = x+1; end idx = x*nodeCount; lft = lft*nodeCount; rgt = rgt*nodeCount; for( k = 1:nodeCount ) dy(idx+k) = dy(idx+k) + acNet.diff(k) * ( y(lft+k) - y(idx+k) ); dy(idx+k) = dy(idx+k) + acNet.diff(k) * ( y(rgt+k) - y(idx+k) ); dy(idx+k) = dy(idx+k) / acNet.capacitance; end else % circular and apply capacitance correction xm = mod( x-1+xDim, xDim ); xp = mod( x+1+xDim, xDim ); idx = x*nodeCount; for( k = 1:nodeCount ) dy(idx+k) = dy(idx+k) + acNet.diff(k) * ( y(xm*nodeCount+k) - y(idx+k) ); dy(idx+k) = dy(idx+k) + acNet.diff(k) * ( y(xp*nodeCount+k) - y(idx+k) ); dy(idx+k) = dy(idx+k) / acNet.capacitance; end end end end function Y = ac1ExtractReagent( acNet, which, withExtraCol ) % EXTRACTS a given reagents all all positions in space % So the returned matrix has time count rows and xDim cols Y = acNet.Y( :, [which:acNet.nodeCount:acNet.xDim*acNet.nodeCount] ); if( withExtraCol ) % When viewing, the extra column makes it so that the pcolor % will correctly draw the last column Y(:,size(Y,2)+1) = zeros(size(Y,1),1); end end function Y = ac2ExtractReagent( acNet, which, withExtraCol ) % EXTRACTS a given reagents at all positions in space % So the returned matrix has time count rows and dim*dim cols Y = acNet.Y( :, [which:acNet.nodeCount:acNet.dim*acNet.dim*acNet.nodeCount] ); if( withExtraCol ) % When viewing, the extra column makes it so that the pcolor % will correctly draw the last column Y(:,size(Y,2)+1) = zeros(size(Y,1),1); end end