Team:Manchester/Model




EXPERIMENTAL MODEL

We wanted a way to determine the number of our sensor bacteria required in the starter culture of a given cheese in order to ensure an accurate detection of Listeria contamination. To do this we modelled the rate of up-regulation of the agr operon in Listeria and predicted the responsiveness of our sensor.

This model is based on equations derived from https://link.springer.com/content/pdf/10.1007%2Fs00285-009-0291-6.pdf . We assumed that equations that govern the up-regulation of the agr operon in Staphylococcus would be similar to those applicable in Listeria, and so we used symbiology functions to create a step-by-step sequence of agr regulation based on the Staphylococcus template. Each step was defined as a reaction, and each reaction was governed by a kinetic law, i.e. a differential equation defining that step in the regulatory process.

Each reaction and its associated equation are shown below, see the end of this article for a table defining each variable AND IT'S UNITS.

Two compartments were generated in symbiology, one for Listeria (called cell), and one for our sensing bacteria (called sensor).

For our Listeria compartment we modelled the following reactions:

1. DNA -> mRNA -> AgrA, AgrB, AgrC, AgrD


The above image shows the equations used to model transcription and translation of the agr operon. Whilst transcription of the agr components was assumed to occur at an equal rate, given that they are all components of the same operon regulated by one upstream promoter, each component of the agr system was assigned a unique rate equation to define its translation rate, and these are given below;


Highlighted here, in blue, is the equation used to describe the agr operon transcription. The equation format is as follow:

Note: the comma in the highlighted section represents an equals sign, and this format is used for all subsequent equations. All terms are defined in an Abbreviation's table (see below).

agrB translation

agrD translation

agrA translation

agrC translation

2. Rate of AgrB integration into the membrane after AIP stimulus (TB)

3. Rate of AgrD association with transmembrane B after AIP stimulus

4.Rate of AgrC integration into the membrane after AIP stimulus

5. Rate of increase in the extracellular AIP concentration

6. AIP interaction with transmembrane AgrC

7. Rate of AgrA phosphorylation after AIP stimulus

8. Rate of interaction of Phosphorylated AgrA with the promoter for the agr operon (PII)

For the sensor, we used the following additional considerations

1. The movement of AIP through the cheese and subsequent sensor AgrC binding

Using a modified Stokes-Einstein equation, we aimed to estimate the rate of diffusion through cheese, depending on a number of important biophysical cheese properties. If we assume cheese can be represented as a porous matrix, in which the “pores” are fairly large (i.e. there is space for molecules to diffuse), then we can use Fick’s diffusion to describe mass transfer between these pores. This can be done by multiplying the diffusion coefficient (calculated using the Stokes-Einstein equation) by x/y (where x is equal to the tortuosity and y is equal to the porosity of the medium). The tortuosity of a medium (in our case cheese) can be described as the difficulty a molecule encounters when trying to move through the medium, whereas the porosity can be described as the ease a molecule encounters when moving through a medium. We, therefore, decided to assign the value of x (tortuosity) as a variable describing the total amount of fat, protein, and salt within the cheese (in other words, the dry mass of the cheese), as these are all the kind of molecules that AIP would encounter as obstacles to free diffusion, and thus they represent “difficulty”. For the value of y (porosity), we assigned a variable describing the water content in the cheese (in other words, the total weight of the cheese minus its dry mass), as we theorised AIP would encounter less difficulty moving through a cheese with a higher water content.

The resulting equation is as follows:

2. AgrA phosphorylation by our sensor AgrC upon AIP binding

3. Phosphorylated AgrA stimulated transcription of amilCP

Results and Discussion

Above is an image of the graph generated when our model is simulated in MatLab. Each line corresponds to an important component in the mechanism of agr upregulation in Listeria. For the proof-of-concept simulations random values were assigned to the parameters. However, so model was set up in such a way that we could have used an ensemble modelling approach by collecting possible values from sources like Bionumbers and creating a probability distribution for each parameter. These distributions could then have been used to conduct a Bayesian analysis for plausible predictions, including confidence intervals. We would have also liked to create a user input function, to allow a user to define the properties of their specific cheese. Most importantly, cheese types vary widely in water content, and our discussions with cheese makers had shown us that this is a very important consideration for Listeria detection. By exploring the effect of different biophysical condition, our model would thus allow us to determine an accurate prediction of the concentration of our sensor bacteria required for reliable Listeria detection in a user-specific starting culture. This again is an important feature of our project, requested by cheese makers in our stakeholder discussions with various companies (read more in our Human practices page).

Abbreviation's Table

Experimental model code

% PLEASE CHECK THAT ALL SPECIES AND PARAMETERS ARE LISTED IN THE CORRECT % ORDER, also add in a section about initial production, not upregulation Mobj = sbiomodel('listnot'); % Generates a new simbiology model with the name listnot compObj = addcompartment(Mobj,'cell'); % generated a compartment named cell compObj.CapacityUnits = 'liter'; % defines the units of the above compartment Robj1 = addreaction(Mobj,'DNA -> DNA + M'); % Robj1 defines the reaction for the production of agr operon mRNA Mobj.Species; Mobj.Species(1).InitialAmount = 500; % Here we input the initial DNA concentration within the compartment 'cell' Mobj.Species(1).InitialAmountUnits = 'molecule/milliliter'; Mobj.Species(2).InitialAmount = 0; % Here we set the initial concntration of mRNA Mobj.Species(2).InitialAmountUnits = 'molecule/milliliter'; Kobj1 = addkineticlaw(Robj1,'AIP-mRNA2'); % adds a forward rate kinetic law (Kobj1)to define Robj1 to tell you the rate of change of mRNA (for the agr operon) % The equation I have used is as follows, AIP-mRNA2(standing for AIP % induced mRNA production) = (N*O*m)+(N*O*v*P)-(d*M) Pobj1 = addparameter(Kobj1,'N');% N stands for number of listeria cells Pobj1.Value = 20; Pobj1.ValueUnits = 'mole/milliliter'; Pobj2 = addparameter(Kobj1,'m'); % m stands for basal rate of mRNA production Pobj2.Value = 10; Pobj2.ValueUnits = 'molecule/mole/second'; Pobj3 = addparameter(Kobj1,'v'); % v stands for mRNA transcription rate Pobj3.Value = 5; Pobj3.ValueUnits = 'molecule/mole/second'; Pobj4 = addparameter(Kobj1,'P'); % P stands for the proportion of up-regulated cells (we could maybe try to figure this out) Pobj4.Value = 15; Pobj4.ValueUnits = 'dimensionless'; Pobj5 = addparameter(Kobj1,'d'); % d stands for mRNA degradation rate Pobj5.Value = 50; Pobj5.ValueUnits = '1/second'; Pobj6 = addparameter(Kobj1,'O'); % O is the plasmid copy number (ie - the number of times the gene is going to appear in the cell) Pobj6.Value = 1; Pobj6.ValueUnits = 'dimensionless'; set(Kobj1,'ParameterVariableNames',{'m','v','P','d','O','N'}); % This is a list of things in the equation that are not present in the overall reaction (the parameters) set(Kobj1,'SpeciesVariableNames',{'M'}); % This is a list of the things in the equation that do appear in the overall reaction Robj2 = addreaction(Mobj,'M -> M + B'); % Ok well I just realised this makes every thing more fucking hard work because M is going to be in all 4 agr equations so any value for M has to be multiplied by fucking 4 Mobj.Species(3).InitialAmountUnits = 'molecule/milliliter'; Kobj2 = addkineticlaw(Robj2,'BTranslate1'); Pobj7 = addparameter(Kobj2,'K'); Pobj7.Value = 76; Pobj7.ValueUnits = '1/second'; Pobj8 = addparameter(Kobj2,'tB'); Pobj8.Value = 49; Pobj8.ValueUnits = '1/second'; Pobj9 = addparameter(Kobj2,'dB'); Pobj9.Value = 200000000000000000000000000000000; Pobj9.ValueUnits = '1/second'; set(Kobj2,'ParameterVariableNames',{'K','tB','dB'}); set(Kobj2,'SpeciesVariableNames',{'M','B'}); Robj3 = addreaction(Mobj,'M -> M + D'); Mobj.Species(4).InitialAmountUnits = 'molecule/milliliter'; Kobj3 = addkineticlaw(Robj3,'DTranslate1'); Pobj10 = addparameter(Kobj3,'K'); Pobj10.Value = 76; Pobj10.ValueUnits = '1/second'; Pobj11 = addparameter(Kobj3,'BD'); Pobj11.Value = 30; Pobj11.ValueUnits = '1/second'; Pobj12 = addparameter(Kobj3,'dD'); Pobj12.Value = 20; Pobj12.ValueUnits = '1/second'; set(Kobj3,'ParameterVariableNames',{'K','BD','dD'}); set(Kobj3,'SpeciesVariableNames',{'M','D'}); Robj4 = addreaction(Mobj,'M -> M + A'); Mobj.Species(5).InitialAmountUnits = 'molecule/milliliter'; Kobj4 = addkineticlaw(Robj4,'ATranslate2'); Pobj13 = addparameter(Kobj4,'K'); Pobj13.Value = 76; Pobj13.ValueUnits = '1/second'; Pobj14 = addparameter(Kobj4,'AIPcA'); Pobj14.Value = 50; Pobj14.ValueUnits = 'mlms'; Pobj15 = addparameter(Kobj4,'AIPCB'); Pobj15.Value = 50; Pobj15.ValueUnits = 'molecule/milliliter'; Pobj16 = addparameter(Kobj4,'dAP'); Pobj16.Value = 20; Pobj16.ValueUnits = '1/second'; Pobj17 = addparameter(Kobj4,'AP'); Pobj17.Value = 70; Pobj17.ValueUnits = 'molecule/milliliter'; Pobj18 = addparameter(Kobj4,'dA'); Pobj18.Value = 9; Pobj18.ValueUnits = '1/second'; set(Kobj4,'ParameterVariableNames',{'K','AIPcA','AIPCB','dAP','AP','dA'}); set(Kobj4,'SpeciesVariableNames',{'M','A'}); Robj5 = addreaction(Mobj,'M -> M + C'); Mobj.Species(6).InitialAmountUnits = 'molecule/milliliter'; Kobj5 = addkineticlaw(Robj5,'CTranslate3'); Pobj19 = addparameter(Kobj5,'K'); Pobj19.Value = 76; Pobj19.ValueUnits = '1/second'; Pobj20 = addparameter(Kobj5,'tC'); Pobj20.Value = 49; Pobj20.ValueUnits = '1/second'; Pobj21 = addparameter(Kobj5,'dC'); Pobj21.Value = 20; Pobj21.ValueUnits = '1/second'; set(Kobj5,'ParameterVariableNames',{'K','tC','dC'}); set(Kobj5,'SpeciesVariableNames',{'M','C'}); Robj6 = addreaction(Mobj,'D + TB -> tD'); Mobj.Species(7).InitialAmount = 3000; Mobj.Species(7).InitialAmountUnits = 'molecule/milliliter'; Mobj.Species(8).InitialAmountUnits = 'molecule/milliliter'; Kobj6 = addkineticlaw(Robj6,'AnchorD1'); Pobj22 = addparameter(Kobj6,'BD'); Pobj22.Value = 3; Pobj22.ValueUnits = '1/second'; Pobj23 = addparameter(Kobj6,'dtD'); Pobj23.Value = 6; Pobj23.ValueUnits = '1/second'; Pobj24 = addparameter(Kobj6,'DBAIP'); Pobj24.Value = 7; Pobj24.ValueUnits = 'mlms'; set(Kobj6,'ParameterVariableNames',{'BD','dtD','DBAIP'}); set(Kobj6,'SpeciesVariableNames',{'D','TB','tD'}); Robj7 = addreaction(Mobj,'B -> TB'); Kobj7 = addkineticlaw(Robj7,'TransB'); Pobj25 = addparameter(Kobj7,'tB'); Pobj25.Value = 34; Pobj25.ValueUnits = '1/second'; Pobj26 = addparameter(Kobj7,'dTB'); Pobj26.Value = 50; Pobj26.ValueUnits = '1/second'; set(Kobj7,'ParameterVariableNames',{'tB','dTB'}); set(Kobj7,'SpeciesVariableNames',{'B','TB'}); Robj8 = addreaction(Mobj,'tD + TB -> AIP'); Mobj.Species(9).InitialAmountUnits = 'molecule/milliliter'; Kobj8 = addkineticlaw(Robj8,'AIPup'); Pobj27 = addparameter(Kobj8,'DBAIP'); Pobj27.Value = 67; Pobj27.ValueUnits = 'mlms'; Pobj28 = addparameter(Kobj8,'AIPC'); Pobj28.Value = 20; Pobj28.ValueUnits = 'mlms'; Pobj29 = addparameter(Kobj8,'TC'); Pobj29.Value = 30; Pobj29.ValueUnits = 'molecule/milliliter'; Pobj30 = addparameter(Kobj8,'AIPnoC'); Pobj30.Value = 10; Pobj30.ValueUnits = '1/second'; Pobj31 = addparameter(Kobj8,'AIPCB'); Pobj31.Value = 50; Pobj31.ValueUnits = 'molecule/milliliter'; Pobj32 = addparameter(Kobj8,'dAIP'); Pobj32.Value = 2; Pobj32.ValueUnits = '1/second'; set(Kobj8,'ParameterVariableNames',{'DBAIP','AIPC','TC','AIPnoC','AIPCB','dAIP'}); set(Kobj8,'SpeciesVariableNames',{'tD','TB','AIP'}); Robj9 = addreaction(Mobj,'C -> TC'); Mobj.Species(10).InitialAmountUnits = 'molecule/milliliter'; Kobj9 = addkineticlaw(Robj9,'TransC'); Pobj33 = addparameter(Kobj9,'tC'); Pobj33.Value = 60; Pobj33.ValueUnits = '1/second'; Pobj34 = addparameter(Kobj9,'AIPC'); Pobj34.Value = 23; Pobj34.ValueUnits = 'mlms'; Pobj35 = addparameter(Kobj9,'AIP'); Pobj35.ValueUnits ='molecule/milliliter'; Pobj36 = addparameter(Kobj9,'AIPnoC'); Pobj36.Value = 6; Pobj36.ValueUnits = '1/second'; Pobj37 = addparameter(Kobj9,'AIPCB'); Pobj37.Value = 30; Pobj37.ValueUnits = 'molecule/milliliter'; Pobj38 = addparameter(Kobj9,'dTC'); Pobj38.Value = 7; Pobj38.ValueUnits = '1/second'; set(Kobj9,'ParameterVariableNames',{'tC','AIPC','AIP','AIPnoC','AIPCB','dTC'}); set(Kobj9,'SpeciesVariableNames',{'C','TC'}); Robj10 = addreaction(Mobj,'AIP + TC -> AIPCB'); Mobj.Species(11).InitialAmountUnits = 'molecule/milliliter'; Kobj10 = addkineticlaw(Robj10,'AIPboundreceptor5'); Pobj39 = addparameter(Kobj10,'AIPC'); Pobj.Value = 23; Pobj39.ValueUnits ='mlms'; Pobj40 = addparameter(Kobj10,'AIPnoC'); Pobj40.Value = 30; Pobj40.ValueUnits = '1/second'; Pobj41 = addparameter(Kobj10,'dAIPCB'); Pobj41.Value = 1; Pobj41.ValueUnits = '1/second'; set(Kobj10,'ParameterVariableNames',{'AIPC','AIPnoC','dAIPCB'}); set(Kobj10,'SpeciesVariableNames',{'AIP','TC','AIPCB'}); Robj11 = addreaction(Mobj,'AIPCB + A -> AP'); Mobj.Species(12).InitialAmountUnits = 'molecule/milliliter'; Kobj11 = addkineticlaw(Robj11,'Aphosphorylation1'); Pobj42 = addparameter(Kobj11,'CAP'); Pobj42.Value = 2; Pobj42.ValueUnits = 'mlms'; Pobj43 = addparameter(Kobj11,'noAP'); Pobj43.Value = 2; Pobj43.ValueUnits = '1/second'; Pobj44 = addparameter(Kobj11,'dAP'); Pobj44.Value = 30; Pobj44.ValueUnits = '1/second'; set(Kobj11,'ParameterVariableNames',{'CAP','noAP','dAP'}); set(Kobj11,'SpeciesVariableNames',{'AIPCB','A','AP'}); Robj12 = addreaction(Mobj,'AP + DNA -> M'); Kobj12 = addkineticlaw(Robj12,'ListeriaUP5'); Pobj45 = addparameter(Kobj12,'bPII'); Pobj45.Value = 5; Pobj45.ValueUnits = 'prombinding'; Pobj46 = addparameter(Kobj12,'N'); Pobj46.Value = 20; Pobj46.ValueUnits = 'mole/milliliter'; Pobj47 = addparameter(Kobj12,'O'); Pobj47.Value = 1; Pobj47.ValueUnits = 'dimensionless'; Pobj48 = addparameter(Kobj12,'P'); Pobj48.Value = 0.5; Pobj48.ValueUnits = 'dimensionless'; Pobj49 = addparameter(Kobj12,'dPII'); Pobj49.Value = 13; Pobj49.ValueUnits = '1/second'; set(Kobj12,'ParameterVariableNames',{'bPII','N','O','P','dPII'}); set(Kobj12,'SpeciesVariableNames',{'AP','M'}); compObj2 = addcompartment(Mobj,'sensor'); compObj.CapacityUnits = 'liter'; Robj13 = addreaction(Mobj,'cell.AIP + sensor.Cs -> sensor.AIPSENSOR'); Mobj.Species(13).InitialAmountUnits = 'molecule/milliliter'; Mobj.Species(14).InitialAmountUnits = 'molecule/milliliter'; Kobj13 = addkineticlaw(Robj13,'AIPDIFFUSE4'); Pobj50 = addparameter(Kobj13,'Kb'); Pobj50.Value = 1.38064852*10-23; Pobj50.ValueUnits = 'dimensionless'; % all parameters involved in the diffusion constant will be dimensionless but the input is not, see the equation for the units Pobj51 = addparameter(Kobj13,'T'); Pobj51.Value = 37; % going to be variable the input must be kelvin Pobj51.ValueUnits = 'dimensionless'; Pobj52 = addparameter(Kobj13,'vis'); Pobj52.Value = 20; Pobj52.ValueUnits = 'dimensionless'; Pobj53 = addparameter(Kobj13,'radi'); Pobj53.Value = 2; Pobj53.ValueUnits = 'dimensionless'; Pobj54 = addparameter(Kobj13,'fps'); Pobj54.Value = 100; Pobj54.ValueUnits = 'dimensionless'; % need to decide a unit Pobj55 = addparameter(Kobj13,'hho'); Pobj55.Value = 200; Pobj55.ValueUnits = 'dimensionless'; Pobj56 = addparameter(Kobj13,'AIPCs'); Pobj56.Value = 5; Pobj56.ValueUnits = 'mlms'; set(Kobj13,'ParameterVariableNames',{'Kb','T','vis','radi','fps','hho','AIPCs'}); set(Kobj13,'SpeciesVariableNames',{'AIP','Cs'}); Robj14 = addreaction(Mobj,'sensor.AIPSENSOR + sensor.As -> sensor.APs'); % need to add a degradation rate for this Kobj14 = addkineticlaw(Robj14,'APCONCsense1'); Pobj57 = addparameter(Kobj14,'CAP'); Pobj57.Value = 23; Pobj57.ValueUnits = 'mlms'; set(Kobj14,'ParameterVariableNames',{'CAP'}); set(Kobj14,'SpeciesVariableNames',{'AIPSENSOR','As'}); Robj15 = addreaction(Mobj,'sensor.APs -> sensor.ACP'); Kobj15 = addkineticlaw(Robj15,'ACPprod4'); Pobj58 = addparameter(Kobj15,'BU'); % this is binding divided by unbinding Pobj58.Value = 30; Pobj58.ValueUnits = '1/second'; Pobj59 = addparameter(Kobj15,'DNAs'); Pobj59.Value = 1; Pobj59.ValueUnits = 'dimensionless'; set(Kobj15,'ParameterVariableNames',{'BU','DNAs'}); set(Kobj15,'SpeciesVariableNames',{'APs'}); csObj = getconfigset(Mobj); % Gets data set from above...I hope optionsObj = get(csObj,'CompileOptions'); set(optionsObj,'UnitConversion',false); % Hope this is ok set(csObj, 'MaximumNumberOfLogs', 50); % This is only here because it lets my model run even though I get negative species values (just for now as I am using random data) unitlessObjects = sbioselect(Mobj,'*Units', ''); csObj.SolverType = 'ode15s'; csObj.StopTime = 500; % 500 second long csObj.RuntimeOptions.StatesToLog = 'all'; [t,x,names] = sbiosimulate(Mobj); plot(t,x); legend(names); xlabel('Time'); ylabel('Amount');