Skip to content

Commit 689e200

Browse files
authored
Improve readme/doc with a minimal, game of life example (#61)
* minor changes in FAQ * add "in a nutshell" section in README and About page (Game of Life) * show output dataset in readme * add what's new entry
1 parent 4769f2f commit 689e200

File tree

6 files changed

+237
-46
lines changed

6 files changed

+237
-46
lines changed

README.rst

+105-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ xarray-simlab: xarray extension for computer model simulations
66
xarray-simlab is a Python library that provides both a generic
77
framework for building computational models in a modular fashion and a
88
xarray_ extension for setting and running simulations using the
9-
xarray's ``Dataset`` structure. It is designed for interactive and
10-
exploratory modeling.
9+
xarray's ``Dataset`` structure. It is designed for fast, interactive
10+
and exploratory modeling.
1111

1212
.. _xarray: http://xarray.pydata.org
1313
.. |Build Status| image:: https://travis-ci.org/benbovy/xarray-simlab.svg?branch=master
@@ -23,6 +23,109 @@ exploratory modeling.
2323
:target: https://zenodo.org/badge/latestdoi/93938479
2424
:alt: Citation
2525

26+
In a nutshell
27+
-------------
28+
29+
The Conway's Game of Life example shown below is adapted from this
30+
`blog post <https://jakevdp.github.io/blog/2013/08/07/conways-game-of-life/>`_
31+
by Jake VanderPlas.
32+
33+
1. Create new model components by writing compact Python classes,
34+
i.e., very much like dataclasses_:
35+
36+
.. code-block:: python
37+
38+
import numpy as np
39+
import xsimlab as xs
40+
41+
@xs.process
42+
class GameOfLife:
43+
world = xs.variable(dims=('x', 'y'), intent='inout')
44+
45+
def run_step(self):
46+
nbrs_count = sum(
47+
np.roll(np.roll(self.world, i, 0), j, 1)
48+
for i in (-1, 0, 1) for j in (-1, 0, 1)
49+
if (i != 0 or j != 0)
50+
)
51+
self._world_next = (nbrs_count == 3) | (self.world & (nbrs_count == 2))
52+
53+
def finalize_step(self):
54+
self.world[:] = self._world_next
55+
56+
57+
@xs.process
58+
class Glider:
59+
pos = xs.variable(dims='point_xy', description='glider position')
60+
world = xs.foreign(GameOfLife, 'world', intent='out')
61+
62+
def initialize(self):
63+
x, y = self.pos
64+
65+
kernel = [[1, 0, 0],
66+
[0, 1, 1],
67+
[1, 1, 0]]
68+
69+
self.world = np.zeros((10, 10), dtype=bool)
70+
self.world[x:x+3, y:y+3] = kernel
71+
72+
2. Create a new model just by providing a dictionary of model components:
73+
74+
.. code-block:: python
75+
76+
model = xs.Model({'gol': GameOfLife,
77+
'init': Glider})
78+
79+
3. Create an input ``xarray.Dataset``, run the model and get an output
80+
``Dataset``:
81+
82+
.. code-block:: python
83+
84+
input_dataset = xs.create_setup(
85+
model=model,
86+
clocks={'step': np.arange(9)},
87+
input_vars={'init__pos': ('point_xy', [4, 5])},
88+
output_vars={'step': 'gol__world'}
89+
)
90+
91+
output_dataset = input_dataset.xsimlab.run(model=model)
92+
93+
.. code-block:: python
94+
95+
>>> output_dataset
96+
<xarray.Dataset>
97+
Dimensions: (point: 2, step: 9, x: 10, y: 10)
98+
Coordinates:
99+
* step (step) int64 0 1 2 3 4 5 6 7 8
100+
Dimensions without coordinates: point, x, y
101+
Data variables:
102+
init__pos (point) int64 4 5
103+
gol__world (step, x, y) bool False False False False ... False False False
104+
105+
4. Perform model setup, pre-processing, run, post-processing and
106+
visualization in a functional style, using method chaining:
107+
108+
.. code-block:: python
109+
110+
import matplotlib.pyplot as plt
111+
112+
with model:
113+
(input_dataset
114+
.xsimlab.update_vars(
115+
input_vars={'init__pos': ('point_xy', [2, 2])}
116+
)
117+
.xsimlab.run()
118+
.gol__world.plot.imshow(
119+
col='step', col_wrap=3, figsize=(5, 5),
120+
xticks=[], yticks=[],
121+
add_colorbar=False, cmap=plt.cm.binary)
122+
)
123+
124+
.. image:: doc/_static/gol.png
125+
:width: 400px
126+
127+
.. _dataclasses: https://docs.python.org/3/library/dataclasses.html
128+
26129
Documentation
27130
-------------
28131

doc/_static/gol.png

8.93 KB
Loading

doc/about.rst

+121-35
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,132 @@
33
About xarray-simlab
44
===================
55

6-
xarray-simlab provides a framework for easily building custom computational
7-
models from a set of modular components (i.e., Python classes), called
6+
xarray-simlab provides a framework to easily build custom
7+
computational models from a collection of modular components, called
88
processes.
99

10-
The framework handles issues that scientists who are developing models
11-
should not care too much about, like the model interface and the
12-
overall workflow management. Both are automatically determined from
13-
the succint, declarative-like interfaces of the model processes.
10+
It also provides an extension to `xarray <https://xarray.pydata.org>`_
11+
(i.e., labeled arrays and datasets), that connects it to a wide range
12+
of libraries of the SciPy / PyData stack for processing, analysis,
13+
visualization, etc.
1414

15-
Notably via its xarray extension, xarray-simlab has already deep
16-
integration with the SciPy / PyData stack. Next versions will
17-
hopefully handle other technical issues like command line integration,
18-
interactive visualization and/or running many simulations in parallel,
19-
e.g., in the context of sensitivity analyses or inversion procedures.
15+
In a nutshell
16+
-------------
17+
18+
The Conway's Game of Life example shown below is adapted from this
19+
`blog post <https://jakevdp.github.io/blog/2013/08/07/conways-game-of-life/>`_
20+
by Jake VanderPlas.
21+
22+
1. Create new model components by writing compact Python classes,
23+
i.e., very much like dataclasses_ (note: more features and Python <
24+
3.7 support are also available through the `attrs
25+
<https://www.attrs.org>`_ library):
26+
27+
.. ipython::
28+
29+
In [1]: import numpy as np
30+
...: import xsimlab as xs
31+
...:
32+
...:
33+
...: @xs.process
34+
...: class GameOfLife:
35+
...: world = xs.variable(dims=('x', 'y'), intent='inout')
36+
...:
37+
...: def run_step(self):
38+
...: nbrs_count = sum(
39+
...: np.roll(np.roll(self.world, i, 0), j, 1)
40+
...: for i in (-1, 0, 1) for j in (-1, 0, 1)
41+
...: if (i != 0 or j != 0)
42+
...: )
43+
...: self._world_next = (nbrs_count == 3) | (self.world & (nbrs_count == 2))
44+
...:
45+
...: def finalize_step(self):
46+
...: self.world[:] = self._world_next
47+
...:
48+
...:
49+
...: @xs.process
50+
...: class Glider:
51+
...: pos = xs.variable(dims='point_xy', description='glider position')
52+
...: world = xs.foreign(GameOfLife, 'world', intent='out')
53+
...:
54+
...: def initialize(self):
55+
...: x, y = self.pos
56+
...:
57+
...: kernel = [[1, 0, 0],
58+
...: [0, 1, 1],
59+
...: [1, 1, 0]]
60+
...:
61+
...: self.world = np.zeros((10, 10), dtype=bool)
62+
...: self.world[x:x+3, y:y+3] = kernel
63+
64+
2. Create a new model just by providing a dictionary of model components:
65+
66+
.. ipython::
67+
68+
In [2]: model = xs.Model({'gol': GameOfLife,
69+
...: 'init': Glider})
70+
71+
3. Create an input :py:class:`xarray.Dataset`, run the model and get an
72+
output Dataset:
73+
74+
.. ipython::
75+
76+
In [3]: input_dataset = xs.create_setup(
77+
...: model=model,
78+
...: clocks={'step': np.arange(9)},
79+
...: input_vars={'init__pos': ('point_xy', [4, 5])},
80+
...: output_vars={'step': 'gol__world'}
81+
...: )
82+
...:
83+
...: output_dataset = input_dataset.xsimlab.run(model=model)
84+
...:
85+
...: output_dataset
86+
87+
4. Perform model setup, pre-processing, run, post-processing and
88+
visualization in a functional style, using method chaining:
89+
90+
.. ipython::
91+
92+
@savefig gol.png width=4in
93+
In [5]: import matplotlib.pyplot as plt
94+
...:
95+
...: with model:
96+
...: (input_dataset
97+
...: .xsimlab.update_vars(
98+
...: input_vars={'init__pos': ('point_xy', [2, 2])}
99+
...: )
100+
...: .xsimlab.run()
101+
...: .gol__world.plot.imshow(
102+
...: col='step', col_wrap=3, figsize=(5, 5),
103+
...: xticks=[], yticks=[],
104+
...: add_colorbar=False, cmap=plt.cm.binary)
105+
...: )
106+
107+
.. _dataclasses: https://docs.python.org/3/library/dataclasses.html
20108

21109
Motivation
22110
----------
23111

24-
xarray-simlab is being developped with the idea of reducing the gap between the
25-
environments used for building and running computational models and the ones
26-
used for processing and analyzing simulation results. If the latter environments
27-
become more powerful and interactive, progress has still to be done for the
28-
former ones.
29-
30-
xarray-simlab also encourages building new models from re-usable sets of
31-
components in order to avoid reinventing the wheel. In many cases we want to
32-
customize existing models (e.g., adding a new feature or slightly modifying
33-
the behavior) instead of building new models from scratch. This modular
34-
framework allows to do that with minimal effort. By implementing models using
35-
a large number of small components that can be easily plugged in/out, we
36-
eliminate the need of hard-coding changes that we want to apply to a model,
37-
which often leads to over-complicated code and interface.
38-
39-
The design of this tool is thus mainly focused on both fast model development
40-
and easy, interactive model exploration. Ultimately, this would optimize the
41-
iterative back-and-forth process between ideas that we have on how to model a
42-
particular phenomenon and insights that we get from the exploration of model
43-
behavior.
112+
xarray-simlab is a tool for *fast model development* and *easy,
113+
interactive model exploration*. It aims at empowering scientists to do
114+
better research in less time, collaborate efficiently and make new
115+
discoveries.
116+
117+
**Fast model development**: xarray-simlab allows building new models
118+
from re-usable sets of components, with minimal effort. Models are
119+
created dynamically and instantly just by plugging in/out components,
120+
always keeping the model structure and interface tidy even in
121+
situations where the model development workflow is highly experimental
122+
or organic.
123+
124+
**Interactive model exploration**: xarray-simlab is being developed
125+
with the idea of reducing the gap between the environments used for
126+
building and running computational models and the ones used for
127+
processing, analyzing and visualizing simulation results. Users may
128+
fully leverage powerful environments like jupyter_ at all stages of
129+
their modeling workflow.
130+
131+
.. _jupyter: https://jupyter.org/
44132

45133
Sources of inspiration
46134
----------------------
@@ -49,8 +137,8 @@ xarray-simlab leverages the great number of packages that are part of the
49137
Python scientific ecosystem. More specifically, the packages below have been
50138
great sources of inspiration for this project.
51139

52-
- xarray_: xarray-simlab actually provides an xarray extension for setting and
53-
running models.
140+
- xarray_: xarray-simlab actually provides an xarray extension for
141+
setting up and running models.
54142
- attrs_: a package that allows writing Python classes without
55143
boilerplate. xarray-simlab uses and extends attrs for writing
56144
processes as succinct Python classes.
@@ -73,8 +161,6 @@ great sources of inspiration for this project.
73161
processes. In this project we actually borrow some code from dask
74162
for resolving process dependencies and for model visualization.
75163

76-
.. _attrs: https://github.com/python-attrs/attrs
77-
.. _xarray: https://github.com/pydata/xarray
78164
.. _dask: https://github.com/dask/dask
79165
.. _luigi: https://github.com/spotify/luigi
80166
.. _django: https://github.com/django/django

doc/faq.rst

+7-7
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ Does xarray-simlab provide built-in models?
99
No, xarray-simlab provides only the framework for creating,
1010
customizing and running computational models. It is intended to be a
1111
general-purpose tool. Domain specific models should be implemented in
12-
3rd party packages. For example, `xarray-topo`_ provides xarray-simlab
12+
3rd party packages. For example, `fastscape`_ provides xarray-simlab
1313
models and model components for simulating landscape evolution.
1414

15-
.. _`xarray-topo`: https://gitext.gfz-potsdam.de/sec55-public/xarray-topo
15+
.. _`fastscape`: https://github.com/fastscape-lem/fastscape
1616

1717
Can xarray-simlab be used with existing model implementations?
1818
--------------------------------------------------------------
@@ -113,11 +113,11 @@ Will xarray-simlab support Python 2.7.x?
113113
----------------------------------------
114114

115115
No, unless there are very good reasons to do so. The main packages of
116-
the Python scientific ecosystem support Python 3.4 or later, and it
117-
seems that Python 2.x will not be maintained anymore past 2020 (see
118-
`PEP 373`_). Although some tools easily allow supporting both Python 2
119-
and 3 versions in a single code base, it still makes the code harder
120-
to maintain.
116+
the Python scientific ecosystem support Python 3.x, and it seems that
117+
Python 2.x will not be maintained anymore past 2020 (see `PEP
118+
373`_). Although some tools easily allow supporting both Python 2 and
119+
3 versions in a single code base, it still makes the code harder to
120+
maintain.
121121

122122
.. _`PEP 373`: https://www.python.org/dev/peps/pep-0373/
123123

doc/index.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ xarray-simlab: xarray extension for computer model simulations
44
**xarray-simlab** is a Python library that provides both a generic
55
framework for building computational models in a modular fashion and a
66
`xarray`_ extension for setting and running simulations using the
7-
:py:class:`xarray.Dataset` structure. It is designed for interactive
8-
and exploratory modeling.
7+
:py:class:`xarray.Dataset` structure. It is designed for fast,
8+
interactive and exploratory modeling.
99

1010
.. _xarray: http://xarray.pydata.org
1111

doc/whats_new.rst

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Enhancements
3535
more meaningful error message is shown when it fails (:issue:`57`).
3636
- Added ``runtime`` decorator to pass simulation runtime information
3737
to the (runtime) methods defined in process classes (:issue:`59`).
38+
- Better documentation with a minimal, yet illustrative example based
39+
on Game of Life (:issue:`61`).
3840

3941
Bug fixes
4042
~~~~~~~~~

0 commit comments

Comments
 (0)