[1]:
from mimic.utilities.utilities import set_all_seeds
from mimic.utilities.utilities import plot_CRM
from mimic.model_infer import *
from mimic.model_simulate import *

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

import pymc as pm
import arviz as az
from pymc.ode import DifferentialEquation
from mimic.model_simulate.sim_CRM import sim_CRM
import pytensor.tensor as at

Simulate some time course data from the CRM

The McArthur Consumer Resource Model takes the form

\[dN_i/dt = 1/\tau_i N_i (\sum_a(c_{ia} w_a R_a - m_i))\]
\[dR_a/dt = 1/(r_a K_a) (K_a - R_a) R_a - \sum_i(N_i c_{ia} R_a)\]

where:

  • \(N_i\) is the concentration of a species

  • \(R_a\) is the concentration of a resource

  • \(c_{ia}\) is the preference of species \(i\) for resource \(a\)

  • \(w_a\) is the quality of resource \(a\)

  • \(m_i\) is the mortality rate of species \(i\)

  • \(K_a\) is the carrying capacity of resource \(a\)

  • \(\tau_i\) is the timescale of species \(i\)

  • \(r_a\) is the timescale of resource \(a\)

Generate parameters for model with two species

[3]:
set_all_seeds(123)

num_species = 2
num_resources = 2
times = np.arange(0, 10, 0.1)


tau = np.random.uniform(0.1, 0.9, num_species)      # species timescales
w = np.random.uniform(0.1, 0.9, num_resources)      # resource quality
c = np.random.uniform(0.1, 0.9, (num_species, num_resources))   # relative resource preferences
m = np.random.uniform(0.3, 0.7, num_species)        # mortality rates
r = np.random.uniform(0.1, 0.9, num_resources)      # resource timescales
K = np.random.uniform(1.0, 10.0, num_resources)     # resource carrying capacities


# write the parameters to a dictionary and pickle
params = {'num_species': num_species, 'num_resources': num_resources, 'tau': tau, 'w': w, 'c': c, 'm': m, 'r': r, 'K': K}
pd.to_pickle(params, 'params-s2-r2.pkl')

[4]:
print(params)
{'num_species': 2, 'num_resources': 2, 'tau': array([0.65717535, 0.32891147]), 'w': array([0.28148116, 0.54105182]), 'c': array([[0.67557518, 0.43848517],
       [0.88461136, 0.64786379]]), 'm': array([0.49237276, 0.45684701]), 'r': array([0.37454241, 0.68323977]), 'K': array([4.9471502 , 1.53710107])}

Simulate single time course

[5]:
# initial conditions
init_species = 10 * np.ones(num_species+num_resources)

# instantiate simulator

simulator = sim_CRM()

simulator.set_parameters(num_species = params['num_species'],
                         num_resources = params['num_resources'],
                         tau = params['tau'],
                         w = params['w'],
                         c = params['c'],
                         m = params['m'],
                         r = params['r'],
                         K = params['K'])

simulator.print_parameters()

observed_species, observed_resources = simulator.simulate(times, init_species)
observed_data = np.hstack((observed_species, observed_resources))

# add Guassian noise to the data
observed_species = observed_species + np.random.normal(loc=0, scale=0.1, size=observed_species.shape)
observed_resources = observed_resources + np.random.normal(loc=0, scale=0.1, size=observed_resources.shape)

# Replace negative values with 0
observed_species = np.maximum(observed_species, 0.0001)
observed_resources = np.maximum(observed_resources, 0.0001)

# plot simulated species and resouce dynamics
plot_CRM(observed_species, observed_resources, times)


# Write the data to a csv file
df_species = pd.DataFrame(observed_species, columns=[f'species_{i + 1}' for i in range(observed_species.shape[1])])
df_resources = pd.DataFrame(observed_resources, columns=[f'resource_{i + 1}' for i in range(observed_resources.shape[1])])

# Add the time column to ensure combination matches up
df_species['time'] = times
df_resources['time'] = times

# Combine the species and resources into one DataFrame
df_combined = pd.concat([df_species.drop(columns=['time']), df_resources], axis=1)

# Ensure time is the first column
cols = df_combined.columns.tolist()
cols = cols[-1:] + cols[:-1]
df_combined = df_combined[cols]

# Write the combined data to a CSV file
df_combined.to_csv('data-s2-r2.csv', index=False)


../../_images/notebooks_CRM_examples-sim-CRM_6_0.png
[ ]: