Simple example: simulating competition¶
An example of a simple simulation can be found in the Competition_Example directory of NutMEG-Implementations, in which we explore how different environmental and microbial parameters can affect competition between some (entirely fictional) methanogens and sulfate reducers. In this guide we’ll go in-depth into how this code works for users who may not be used to object-oriented programming in Python.
setup_methanogenesis()
and setup_sulfatereduction()
¶
These methods generate reaction
objects to represent the two metabolisms we’re looking at. Each method initialises several reagent
objects to be included in the overall reaction. Note how the reactor
is passed here, this is to ensure that all the reagent
s and reaction
s point to the same environment
object. You could also simply pass the environment
object.
Note how the rate constant at RTP (room temperature and pressure) is passed as an optional argument. This is one parameter (or alternatively, the rate constant at the current environment, rate_constant_env
) which is necessary for the kinetic calculations (see respirator). You could not pass a value, and the default k_RTP will be that for an optimally growing methanogen at 300 K.
initial_conditions()
¶
This method sets up the reactor
by populating it with reagent
s. You may notice some of these are the same reagents defined in the two methods discussed above but as they’re being initialised in separate functions they are completely different objects. You may also notice that these reagents are being initialised with more information than the others too, including their activities and concentrations. That;s becaus these are the key ones we’ll be using in the simulation. We’ll see how everything is unified in the next section.
Some of the reagents added have nothing to do with the metabolisms in setup_methanogenesis()
and setup_sulfatereduction()
like NH_3. This is because NutMEG also monitors nutrient availability when it predicts microbial behaviour. The majority of biomass is made up of so-called CHNOPS elements, and nothing will grow in NutMEG without some of each (unless you built your own organism with a different biomolecular structure to the defaults in NutMEG).
simulate_competition()
¶
This method sets up and runs a growth prediction simulation. First, a reactor is created:
R = nm.reactor('reactor1', workoutID=False, pH=7.0, dbpath=dbpath, **reactor_changes)
here 'reactor1'
is its name, which tells the database to have a specific table for this reactor type. Passing workoutID=False
means it doesn’t save parameters to the database yet. We’ll do so once its fully populated. **reactorchanges
passes the dictionary reactorchanges
as keyword arguments to the reactor.__init__
method. Next, we set up the reactor’s composition using initial_conditions
. Then we set up the organisms, as horde
objects:
H = nm.horde('Methanogen', R, setup_methanogenesis(R, k_RTP=k[0]), 10,
Tdef='None', dbpath=dbpath, **methanogen_changes)
H2 = nm.horde('SulfateReducer', R, setup_sulfatereduction(R, k_RTP=k[1]), 10,
Tdef='None', dbpath=dbpath, **SR_changes)
They have separate names, so they’ll also have their own tables in the database. They are both put into the same reactor R
and have a unique metabolic reaction. When they’re added to R
, the reagents are unified to those already populating R
to avoid accidentally ‘doubling-up’ your reagents. Tdef
shows which adaptations against temperature to use, here we’ll ignore it and put in our own maintenance powers.
Now that R
is fully populated, we can give it an entry in the database:
R.dbh.workoutID()
ecosystem
requires organisms and hordes to be in culture
objects for easier analysis of them. Then, the culture and reactor just need to be put in an ecosystem together, and a growth prediction can be performed with predict_growth
:
Cu = nm.culture(hordes=[H2, H])
ES = nm.ecosystem(R, Cu, dbpath=dbpath)
ES.predict_growth(tmax=2e8)
orgcurves()
and compcurves()
¶
These methods extract the simulation data from the database and plot them using the NutMEG.plotter
module which specifically uses matplotlib as a basis, but you could easily use another python plotting package.
Using a SimID returned by simulate_competition()
, orgcurve()
extracts and plots the parameter 'param'
passed from the database with time. For a list of possible values of 'param'
check out the guide on database structure.
Similarly, compcurve()
plots the concentration of select reagents with time.