Skip to content

Commit

Permalink
Change 'states' --> 'initial_states' when initializing model (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
twallema authored Oct 9, 2024
1 parent d64ecd1 commit e3d32aa
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 29 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Does other simulation software exist in Python? Sure, but most of them hold your
- Version 0.2.4 (2023-12-04, PR #62)
> Validated the use of Python 3.11. Efficiency gains in simulation of jump processes. Ommitted dependency on Numba. All changes related to publishing our software manuscript in Journal of Computational Science. Improved nomenclature in model defenition.
- IN PROGRESS: 0.2.5
> Validated the use of Python 3.12. Validated pySODM on macOS Sonoma 14.5. 'draw functions' only have 'parameters' as mandatory input, followed by an arbitrary number of additional parameters (PR #75). Tutorial environment can now be found in `tutorial_env.yml` and was renamed `PYSODM-TUTORIALS` (PR #76). Users can choose when the simulation starts when calibrating a model (PR #92). Initial model states can now be a function returning a dictionary of states. This initial condition function can have arguments, which become part of the model's parameters, and can therefore be optimised (PR #99). Deprecation of legacy 'warmup' parameter (PR #100).
> Validated the use of Python 3.12. Validated pySODM on macOS Sonoma 14.5. 'draw functions' only have 'parameters' as mandatory input, followed by an arbitrary number of additional parameters (PR #75). Tutorial environment can now be found in `tutorial_env.yml` and was renamed `PYSODM-TUTORIALS` (PR #76). Users can choose when the simulation starts when calibrating a model (PR #92). Initial model states can now be a function returning a dictionary of states. This initial condition function can have arguments, which become part of the model's parameters, and can therefore be optimised (PR #99). Deprecation of legacy 'warmup' parameter (PR #100). Change 'states' --> 'initial_states' as input needed to initialize a model (PR #102).
- Version 0.1 (2022-12-23, PR #14)
> Application pySODM to three use cases. Documentation website. Unit tests for ODE, JumpProcess and calibration.
- Version 0.1.1 (2023-01-09, PR #20)
Expand Down
12 changes: 6 additions & 6 deletions docs/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ To intialize this model, the following arguments must be provided.

**Parameters:**

* **states** (dict or callable) - Initial states. If a dictionary. Keys: names of model states. Values: initial values of model states. The dictionary does not need to contain all model states, missing states are filled with zeros upon initialization. If a callable (*initial condition function*): a function that creates such a dictionary.
* **initial_states** (dict or callable) - Initial condition. If a dictionary. Keys: names of model states. Values: initial values of model states. The dictionary does not need to contain all model states, missing states are filled with zeros upon initialization. If a callable (*initial condition function*): a function that creates such a dictionary.

* **parameters** (dict) - Model parameters. Keys: names of parameters. Values: values of parameters. A key,value pair must be provided for all parameter names listed in `parameters` and `stratified_parameters` of the model declaration. If *time dependent parameter functions* with additional parameters are used, these parameters must be included as well. If an *initial condition function* with parameters is used, these parameters must be included as well.

Expand All @@ -59,7 +59,7 @@ To intialize this model, the following arguments must be provided.
For our example,

```python
model = MY_MODEL(states={'Y1': 1000, 'Y2': 0}, parameters={'alpha': 1})
model = MY_MODEL(initial_states={'Y1': 1000, 'Y2': 0}, parameters={'alpha': 1})
```

Or using an *initial condition function*,
Expand All @@ -68,7 +68,7 @@ Or using an *initial condition function*,
def initial_condition_function(Y1_0):
return {'Y1': Y1_0, 'Y2': 0}

model = MY_MODEL(states=initial_condition_function, parameters={'alpha': 1, 'Y1_0': 1000})
model = MY_MODEL(initial_states=initial_condition_function, parameters={'alpha': 1, 'Y1_0': 1000})
```
The parameters of the initial condition function become a part of the model's parameters and can therefore be optimised.

Expand Down Expand Up @@ -157,7 +157,7 @@ To intialize the user-defined model class, the following arguments must be provi

**Parameters:**

* **states** (dict or callable) - Initial states. If a dictionary. Keys: names of model states. Values: initial values of model states. The dictionary does not need to contain all model states, missing states are filled with zeros upon initialization. If a callable (*initial condition function*): a function that creates such a dictionary.
* **initial_states** (dict or callable) - Initial condition. If a dictionary. Keys: names of model states. Values: initial values of model states. The dictionary does not need to contain all model states, missing states are filled with zeros upon initialization. If a callable (*initial condition function*): a function that creates such a dictionary.

* **parameters** (dict) - Model parameters. Keys: names of parameters. Values: values of parameters. A key,value pair must be provided for all parameter names listed in `parameters` and `stratified_parameters` of the model declaration. If *time dependent parameter functions* with additional parameters are used, these parameters must be included as well.

Expand All @@ -168,7 +168,7 @@ To intialize the user-defined model class, the following arguments must be provi
For our example,

```python
model = MY_MODEL(states={'Y1': 1000, 'Y2': 0}, parameters={'alpha': 1})
model = MY_MODEL(initial_states={'Y1': 1000, 'Y2': 0}, parameters={'alpha': 1})
```

Or using an *initial condition function*,
Expand All @@ -177,7 +177,7 @@ Or using an *initial condition function*,
def initial_condition_function(Y1_0):
return {'Y1': Y1_0, 'Y2': 0}

model = MY_MODEL(states=initial_condition_function, parameters={'alpha': 1, 'Y1_0': 1000})
model = MY_MODEL(initial_states=initial_condition_function, parameters={'alpha': 1, 'Y1_0': 1000})
```
The parameters of the initial condition function become a part of the model's parameters and can therefore be optimised.

Expand Down
12 changes: 6 additions & 6 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ class SIR(ODE):
return dS, dI, dR
```

To initialize the model, provide a dictionary containing the initial values of the model states and a dictionary containing all model parameters. Undefined initial states are automatically filled with zeros.
To initialize the model, provide a dictionary containing the initial condition and a dictionary containing all model parameters. Undefined initial states are automatically filled with zeros.

```python
model = SIR(states={'S': 1000, 'I': 1}, parameters={'beta': 0.35, 'gamma': 5})
model = SIR(initial_states={'S': 1000, 'I': 1}, parameters={'beta': 0.35, 'gamma': 5})
```

Alternatively, use an *initial condition function* to define the initial states,
Expand All @@ -55,7 +55,7 @@ def initial_condition_function(S0):
return {'S': S0, 'I': 1}

# that become part of the model's parameters and can be optimised..
model = SIR(states=initial_condition_function, parameters={'beta': 0.35, 'gamma': 5, 'S0': 1000})
model = SIR(initial_states=initial_condition_function, parameters={'beta': 0.35, 'gamma': 5, 'S0': 1000})
```

Simulate the model using its `sim()` method. pySODM supports the use of dates to index simulations, string representations of dates with the format `'yyyy-mm-dd'` as well as `datetime.datetime()` can be used.
Expand Down Expand Up @@ -128,7 +128,7 @@ class stratified_SIR(ODE):
When initializing your model, provide a dictionary containing coordinates for every dimension declared previously. In the example below, we'll declare four age groups: 0-5, 5-15, 15-65 and 65-120 year olds. **All** model states are now 1D vectors of shape `(4,)`.

```python
model = stratified_SIR(states={'S': 1000*np.ones(4), 'I': np.ones(4)},
model = stratified_SIR(initial_states={'S': 1000*np.ones(4), 'I': np.ones(4)},
parameters={'beta': 0.35, 'gamma': 5},
coordinates={'age_groups': ['0-5','5-15', '15-65','65-120']})
out = model.sim(121)
Expand Down Expand Up @@ -192,7 +192,7 @@ params={'alpha': np.array([0.05, 0.1, 0.2, 0.15]), 'gamma': 5, 'beta': 7}
init_states = {'S': [606938, 1328733, 7352492, 2204478], 'S_v': 1e6, 'I_v': 2}
coordinates={'age_group': ['0-5','5-15', '15-65','65-120']}
# Initialize model
model = ODE_SIR_SI(states=init_states, parameters=params, coordinates=coordinates)
model = ODE_SIR_SI(initial_states=init_states, parameters=params, coordinates=coordinates)
# Simulate the model
out = model.sim(120)
print(out)
Expand Down Expand Up @@ -321,7 +321,7 @@ def vary_my_parameter(t, states, param, an_additional_parameter):
When initialising the model, all we need to do is use the `time_dependent_parameters` keyword to declare what parameter our TDPF should be applied to. Additional parameters introduced in TDPFs, in this example `an_additional_parameter`, should be added to the parameters dictionary.

```python
model = SIR(states={'S': 1000, 'I': 1},
model = SIR(initial_states={'S': 1000, 'I': 1},
parameters={'beta': 0.35, 'gamma': 5, 'an_additional_parameter': any_datatype_you_want},
time_dependent_parameters={'beta': vary_my_parameter})
```
4 changes: 2 additions & 2 deletions docs/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class ODE_SIR(ODE):
After defining our model, we'll initialize it by supplying a dictionary of initial states and a dictionary of model parameters. In this example, we'll assume the disease spreads in a relatively small population of 1000 individuals. At the start of the simulation we'll assume there is one "patient zero". There's no need to define the number of recovered individuals as undefined states are automatically set to zero by pySODM.

```python
model = ODE_SIR(states={'S': 1000, 'I': 1}, parameters={'beta': 0.35, 'gamma': 5})
model = ODE_SIR(initial_states={'S': 1000, 'I': 1}, parameters={'beta': 0.35, 'gamma': 5})
```

### Calibrating the model
Expand Down Expand Up @@ -409,7 +409,7 @@ We will apply this function to the infectivity parameter `beta`, and declare thi
model.parameters.update({'start_measures': '2023-01-21'})

# Initialize the model with the time dependent parameter funtion
model_with = ODE_SIR(states=init_states, parameters=model.parameters,
model_with = ODE_SIR(initial_states=init_states, parameters=model.parameters,
time_dependent_parameters={'beta': lower_infectivity})
```

Expand Down
16 changes: 6 additions & 10 deletions src/pySODM/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class JumpProcess:
----------
To initialise the model, provide following inputs:
states : dictionary
initial_states : dictionary
contains the initial values of all non-zero model states, f.i. for an SIR model,
e.g. {'S': 1000, 'I': 1}
initialising zeros is not required
Expand All @@ -46,17 +46,15 @@ class JumpProcess:
dimensions = None
dimensions_per_state = None

def __init__(self, states, parameters, coordinates=None, time_dependent_parameters=None):
def __init__(self, initial_states, parameters, coordinates=None, time_dependent_parameters=None):

# Add a suffix _names to all user-defined name declarations
self.states_names = self.states
self.parameters_names = self.parameters
self.parameters_stratified_names = self.stratified_parameters
self.dimensions_names = self.dimensions
self.states = states
self.states = initial_states
parameters = parameters

# Do not undergo manipulation during model initialization (#TODO: no input check?)
self.coordinates = coordinates
self.time_dependent_parameters = time_dependent_parameters

Expand Down Expand Up @@ -499,7 +497,7 @@ class ODE:
----------
To initialise the model, provide following inputs:
states : dictionary or callable
initial_states : dictionary or callable
contains the initial values of all non-zero model states, f.i. for an SIR model,
e.g. {'S': 1000, 'I': 1}
initialising zeros is not required
Expand All @@ -525,17 +523,15 @@ class ODE:
dimensions_per_state = None
# TODO: states, parameters, dimensions --> list containing str (check input!)

def __init__(self, states, parameters, coordinates=None, time_dependent_parameters=None):
def __init__(self, initial_states, parameters, coordinates=None, time_dependent_parameters=None):

# Add a suffix _names to all user-defined name declarations
self.states_names = self.states
self.parameters_names = self.parameters
self.parameters_stratified_names = self.stratified_parameters
self.dimensions_names = self.dimensions
self.states = states
self.states = initial_states
parameters = parameters

# Do not undergo manipulation during model initialization
self.coordinates = coordinates
self.time_dependent_parameters = time_dependent_parameters

Expand Down
4 changes: 2 additions & 2 deletions tutorials/SIR/workflow_tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def integrate(t, S, I, R, beta, gamma):
return dS, dI, dR

# Initialize model
model = ODE_SIR(states={'S': 1000, 'I': 1}, parameters={'beta':0.35, 'gamma':5})
model = ODE_SIR(initial_states={'S': 1000, 'I': 1}, parameters={'beta':0.35, 'gamma':5})

# Simulate from t=0 until t=121
out = model.sim([0, 121])
Expand Down Expand Up @@ -216,7 +216,7 @@ def draw_fcn(parameters, samples, ramp_length):
model.parameters.update({'start_measures': end_date})

# Initialize the model with the time dependent parameter funtion
model_with = ODE_SIR(states=model.initial_states, parameters=model.parameters, time_dependent_parameters={'beta': lower_infectivity})
model_with = ODE_SIR(initial_states=model.initial_states, parameters=model.parameters, time_dependent_parameters={'beta': lower_infectivity})

# Simulate the model
out_with = model_with.sim([start_date, end_date+pd.Timedelta(days=2*28)], N=100, draw_function=draw_fcn,
Expand Down
2 changes: 1 addition & 1 deletion tutorials/enzyme_kinetics/calibrate_intrinsic_kinetics.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# Define an initial condition
init_states = {'S': 46, 'A': 61, 'W': 37, 'Es': 0}
# Initialize model
model = PPBB_model(states=init_states, parameters=params)
model = PPBB_model(initial_states=init_states, parameters=params)

###############
## Load data ##
Expand Down
3 changes: 2 additions & 1 deletion tutorials/influenza_1718/calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@
# Define model coordinates
coordinates={'age_group': age_groups}
# Initialize model
model = influenza_model(states=init_states,parameters=params,coordinates=coordinates,time_dependent_parameters={'N': contact_function})
model = influenza_model(initial_states=init_states, parameters=params, coordinates=coordinates,
time_dependent_parameters={'N': contact_function})

#####################
## Calibrate model ##
Expand Down

0 comments on commit e3d32aa

Please sign in to comment.