Exogenous model input from a file
=================================
In this notebook we’ll demonstrate using an external data source to feed
values into a model. We’ll use the carbon emissions dataset, and feed
total emissions into a stock of excess atmospheric carbon:
We’ll begin as usual by importing PySD and the machinery we need in
order to deal with data manipulation and plotting.
.. code:: ipython3
%pylab inline
import pysd
import pandas as pd
.. parsed-literal::
Populating the interactive namespace from numpy and matplotlib
We use `Pandas `__ library to import
emissions data from a ``.csv`` file. In this command, we both rename the
columns of the dataset, and set the index to the ‘Year’ column.
.. code:: ipython3
emissions = pd.read_csv('../../data/Climate/global_emissions.csv',
skiprows=2, index_col='Year',
names=['Year', 'Total Emissions',
'Gas Emissions', 'Liquid Emissions',
'Solid Emissions', 'Cement Emissions',
'Flare Emissions', 'Per Capita Emissions'])
emissions.head()
.. raw:: html
|
Total Emissions |
Gas Emissions |
Liquid Emissions |
Solid Emissions |
Cement Emissions |
Flare Emissions |
Per Capita Emissions |
| Year |
|
|
|
|
|
|
|
| 1751 |
3 |
0 |
0 |
3 |
0 |
0 |
NaN |
| 1752 |
3 |
0 |
0 |
3 |
0 |
0 |
NaN |
| 1753 |
3 |
0 |
0 |
3 |
0 |
0 |
NaN |
| 1754 |
3 |
0 |
0 |
3 |
0 |
0 |
NaN |
| 1755 |
3 |
0 |
0 |
3 |
0 |
0 |
NaN |
.. code:: ipython3
model = pysd.read_vensim('../../models/Climate/Atmospheric_Bathtub.mdl')
In our vensim model file, the value of the inflow to the carbon bathtub,
the ``Emissions`` parameter, is set to zero. We want to instead have
this track our exogenous data.
.. code:: python
Emissions=
0
Excess Atmospheric Carbon= INTEG (
Emissions - Natural Removal,
0)
Natural Removal=
Excess Atmospheric Carbon * Removal Constant
Removal Constant=
0.01
Aligning the model time bounds with that of the dataset
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before we can substitute in our exogenous data, however, we need to
ensure that the model will execute over the proper timeseries. The
initial and final times of the simulation are specified in the model
file as:
.. code:: ipython3
print('initial:', model.components.initial_time())
print('final:', model.components.final_time())
.. parsed-literal::
initial: 0
final: 100
However, the time frame of the dataset runs:
.. code:: ipython3
print('initial:', emissions.index[0])
print('final:', emissions.index[-1])
.. parsed-literal::
initial: 1751
final: 2011
In order to run the model over a time series equal to that of the data
set, we need to specify the appropriate initial conditions, and ask the
run function to return to us timestamps equal to that of our dataset:
.. code:: ipython3
res = model.run(initial_condition=(emissions.index[0],
{'Excess Atmospheric Carbon': 0}),
return_timestamps=emissions.index.values,
return_columns=['Emissions', 'Excess Atmospheric Carbon'])
res.head()
.. raw:: html
|
Emissions |
Excess Atmospheric Carbon |
| 1751 |
0 |
0.0 |
| 1752 |
0 |
0.0 |
| 1753 |
0 |
0.0 |
| 1754 |
0 |
0.0 |
| 1755 |
0 |
0.0 |
Pass in our timeseries data
~~~~~~~~~~~~~~~~~~~~~~~~~~~
In place of the constant value of ``emissions``, we want to substitute
our dataset. We can do this in a very straightforward way by passing the
Pandas ``Series`` corresponding to the dataset in a dictionary to the
``params`` argument of the run function.
.. code:: ipython3
res = model.run(initial_condition=(emissions.index[0],
{'Excess Atmospheric Carbon': 0}),
return_timestamps=emissions.index.values,
return_columns=['Emissions', 'Excess Atmospheric Carbon'],
params={'Emissions': emissions['Total Emissions']})
.. code:: ipython3
res.plot();
.. image:: exogenous_timeseries_files/exogenous_timeseries_15_0.png