diff --git a/.travis.yml b/.travis.yml index 076c28fe..fa54f028 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,28 @@ language: python sudo: false # use container based build notifications: email: false +branches: + only: + - master matrix: fast_finish: True include: - - python: 3.4 - env: CONDA_ENV=py34 - python: 3.5 env: CONDA_ENV=py35 - python: 3.6 env: CONDA_ENV=py36 + - python: 3.6 + env: CONDA_ENV=py36-xarray-dev + - python: 3.6 + env: CONDA_ENV=py36-attrs-dev + - python: 3.5 + env: CONDA_ENV=docs + allow_failures: + - python: 3.6 + env: CONDA_ENV=py36-xarray-dev + - python: 3.6 + env: CONDA_ENV=py36-attrs-dev before_install: - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then @@ -29,12 +41,24 @@ before_install: - conda info -a install: - - conda env create --file ci/requirements-$CONDA_ENV.yml - - source activate test_env_$CONDA_ENV - - python setup.py install + - if [[ "$CONDA_ENV" == "docs" ]]; then + conda env create -n test_env --file doc/environment.yml; + else + conda env create -n test_env --file ci/requirements-$CONDA_ENV.yml; + fi + - source activate test_env + - conda list + - pip install --no-deps -e . script: - - py.test xsimlab --cov=xsimlab --cov-report term-missing + - python -OO -c "import xsimlab" + - if [[ "$CONDA_ENV" == "docs" ]]; then + conda install -c conda-forge sphinx_rtd_theme; + cd doc; + sphinx-build -n -j auto -b html -d _build/doctrees . _build/html; + else + py.test xsimlab --cov=xsimlab --cov-report term-missing --verbose; + fi after_success: - coveralls diff --git a/ci/requirements-py35.yml b/ci/requirements-py35.yml index 0d930e13..4aa4cb1b 100644 --- a/ci/requirements-py35.yml +++ b/ci/requirements-py35.yml @@ -2,6 +2,7 @@ name: test_env_py35 channels: - conda-forge dependencies: + - attrs>=18.1.0 - python=3.5 - pytest - numpy diff --git a/ci/requirements-py34.yml b/ci/requirements-py36-attrs-dev.yml similarity index 54% rename from ci/requirements-py34.yml rename to ci/requirements-py36-attrs-dev.yml index 2a501592..9909a83f 100644 --- a/ci/requirements-py34.yml +++ b/ci/requirements-py36-attrs-dev.yml @@ -1,11 +1,12 @@ -name: test_env_py34 +name: test_env_py36-attrs-dev channels: - conda-forge dependencies: - - python=3.4 + - python=3.6 - pytest - numpy - xarray - pip: + - git+https://github.com/python-attrs/attrs.git - coveralls - pytest-cov diff --git a/ci/requirements-py36-xarray-dev.yml b/ci/requirements-py36-xarray-dev.yml new file mode 100644 index 00000000..b4f1732e --- /dev/null +++ b/ci/requirements-py36-xarray-dev.yml @@ -0,0 +1,12 @@ +name: test_env_py36-xarray-dev +channels: + - conda-forge +dependencies: + - attrs>=18.1.0 + - python=3.6 + - pytest + - numpy + - pip: + - git+https://github.com/pydata/xarray.git + - coveralls + - pytest-cov diff --git a/ci/requirements-py36.yml b/ci/requirements-py36.yml index 8197b98a..d42b692e 100644 --- a/ci/requirements-py36.yml +++ b/ci/requirements-py36.yml @@ -2,6 +2,7 @@ name: test_env_py36 channels: - conda-forge dependencies: + - attrs>=18.1.0 - python=3.6 - pytest - numpy diff --git a/doc/api.rst b/doc/api.rst index 26532ce8..433bca23 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -40,7 +40,7 @@ properties listed below. Proper use of this accessor should be like: Dataset.xsimlab.clock_coords Dataset.xsimlab.master_clock_dim - Dataset.xsimlab.snapshot_vars + Dataset.xsimlab.output_vars **Methods** @@ -79,14 +79,17 @@ Model introspection ------------------- ``Model`` implements an immutable mapping interface where keys are -process names and values are objects of ``Process`` subclasses (attribute-style -access is also supported). +process names and values are objects of ``Process`` subclasses +(attribute-style access is also supported). .. autosummary:: :toctree: _api_generated/ + Model.all_vars + Model.all_vars_dict Model.input_vars - Model.is_input + Model.input_vars_dict + Model.dependent_processes Model.visualize Running a model @@ -109,126 +112,31 @@ interfaces. Process ======= -Note: ``Process`` is a base class that should be subclassed. +Creating a process +------------------ .. autosummary:: :toctree: _api_generated/ - Process + process -Clone a process ---------------- - -.. autosummary:: - :toctree: _api_generated/ - - Process.clone - -Process interface and introspection +Process introspection and variables ----------------------------------- -``Process`` implements an immutable mapping interface where keys are -variable names and values are Variable objects (attribute-style -access is also supported). - .. autosummary:: :toctree: _api_generated/ - Process.variables - Process.meta - Process.name - Process.info - -Process "abstract" methods --------------------------- - -Subclasses of ``Process`` usually implement at least some of the methods below. - -.. autosummary:: - :toctree: _api_generated/ - - Process.validate - Process.initialize - Process.run_step - Process.finalize_step - Process.finalize + process_info + variable_info + filter_variables Variable ======== -Base variable class -------------------- - -Although it has the same name, this class is different from -:py:class:`xarray.Variable`. - -.. autosummary:: - :toctree: _api_generated/ - - Variable - -**Attributes** - -.. autosummary:: - :toctree: _api_generated/ - - Variable.value - Variable.state - Variable.rate - Variable.change - -**Methods** - -.. autosummary:: - :toctree: _api_generated/ - - Variable.to_xarray_variable - -Derived variable classes ------------------------- - -These classes inherit from ``Variable``. - -.. autosummary:: - :toctree: _api_generated/ - - NumberVariable - FloatVariable - IntegerVariable - -Foreign variable ----------------- - -.. autosummary:: - :toctree: _api_generated/ - - ForeignVariable - -**Attributes** - -.. autosummary:: - :toctree: _api_generated/ - - ForeignVariable.ref_process - ForeignVariable.ref_var - ForeignVariable.value - ForeignVariable.state - ForeignVariable.rate - ForeignVariable.change - -Diagnostic variable -------------------- - -.. autosummary:: - :toctree: _api_generated/ - - diagnostic - -Collections of variables ------------------------- - .. autosummary:: :toctree: _api_generated/ - VariableList - VariableGroup + variable + foreign + group + on_demand diff --git a/doc/conf.py b/doc/conf.py index c5d8d913..637986e0 100755 --- a/doc/conf.py +++ b/doc/conf.py @@ -26,6 +26,11 @@ print("numpy: %s, %s" % (numpy.__version__, numpy.__file__)) except ImportError: print("no numpy") +try: + import attr + print("attr: %s, %s" % (attr.__version__, attr.__file__)) +except ImportError: + print("no attr") try: import xarray print("xarray: %s, %s" % (xarray.__version__, xarray.__file__)) @@ -120,15 +125,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # - -# on_rtd is whether we are on readthedocs.org, this line of code grabbed from -# docs.readthedocs.org -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' - -if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +html_theme = 'sphinx_rtd_theme' # otherwise, readthedocs.org uses their theme by default, so no need # to specify it @@ -205,6 +202,7 @@ intersphinx_mapping = { 'python': ('https://docs.python.org/3.6/', None), 'numpy': ('https://docs.scipy.org/doc/numpy/', None), + 'attr': ('http://www.attrs.org/en/stable/', None), 'pandas': ('http://pandas.pydata.org/pandas-docs/stable/', None), 'xarray': ('http://xarray.pydata.org/en/stable/', None) } diff --git a/doc/create_model.rst b/doc/create_model.rst index 2046b6ad..a093f5a9 100644 --- a/doc/create_model.rst +++ b/doc/create_model.rst @@ -30,7 +30,7 @@ between times :math:`n` and :math:`n+1`. We could just implement this numerical model with a few lines of Python / Numpy code, e.g., here below assuming periodic boundary -conditions and a gaussian pulse as initial profile. We will show, +conditions and a Gaussian pulse as initial profile. We will show, however, that it is very easy to refactor this code for using it with xarray-simlab. We will also show that, while enabling useful features, the refactoring still results in a short amount of readable code. @@ -42,9 +42,9 @@ the refactoring still results in a short amount of readable code. Anatomy of a Process subclass ----------------------------- -Let's first wrap the code above into a single subclass of -:class:`~xsimlab.Process` named ``AdvectionLax1D``. Next we'll explain in -detail the content of this class. +Let's first wrap the code above into a single class named +``AdvectionLax1D`` decorated by :class:`~xsimlab.process`. Next we'll +explain in detail the content of this class. .. literalinclude:: scripts/advection_model.py :lines: 3-32 @@ -54,44 +54,35 @@ Process interface ``AdvectionLax1D`` has some class attributes declared at the top, which together form the process' "public" interface, i.e., all the -variables that we want to be publicly exposed by this process. These -attributes usually correspond to instances of -:class:`~xsimlab.Variable` or derived classes, depending on their -expected value type, like :class:`~xsimlab.FloatVariable` in this case -(see section :doc:`api` for a full list of available classes). - -The creation of Variable objects requires to explicitly provide -dimension label(s) for arrays or an empty tuple for scalars. In this -case, variables ``spacing``, ``length``, ``loc`` and ``scale`` are all -scalars, whereas ``x`` and ``u`` are both arrays defined on the -1-dimensional :math:`x` grid. Multiple choices can also be given as a -list, like variable ``v`` which represents a velocity field that can -be either constant (scalar) or variable (array) in space. +variables that we want to be publicly exposed by this process. Here we +use :func:`~xsimlab.variable` to add some metadata to each variable +of the interface. + +We first may specify the labels of the dimensions expected for each +variable, which defaults to an empty tuple (i.e., a scalar value is +expected). In this example, variables ``spacing``, ``length``, ``loc`` +and ``scale`` are all scalars, whereas ``x`` and ``u`` are both arrays +defined on the 1-dimensional :math:`x` grid. Multiple choices can also +be given as a list, like variable ``v`` which represents a velocity +field that can be either constant (scalar) or variable (array) in +space. .. note:: - All variable objects also implicitly allow a time dimension as - well as their own dimension (coordinate). See section :doc:`run_model`. + All variable objects also implicitly allow a time dimension. + See section :doc:`run_model`. -There is also a set of common arguments available to all Variable -types. All are optional. In the example above, ``description`` and -``attrs`` are used to define some (custom) metadata. +Additionally, it is also possible to add a short ``description`` +and/or custom metadata like units with the ``attrs`` argument. -Variables ``x`` and ``u`` have also an option ``provided`` set to -``True``. It means that the process ``AdvectionLax1D`` itself provides -a value for these variables. ``provided=False`` (default) means -that a value should be provided elsewhere, either by another process -or as model input. - -.. note:: - - A process which updates the value (i.e., state) of a variable - during a simulation does not necessarily imply setting - ``provide=True`` for that variable, e.g., when it still requires an - initial value. - -Other options are available, see :class:`~xsimlab.Variable` for full -reference. +Another important argument is ``intent``, which specifies how the +process deals with the value of the variable. By default, +``intent='in'`` means that the process just needs the value of the +variable for its computation ; this value should either be computed +elsewhere by another process or be provided by the user as model +input. By contrast, variables ``x`` and ``u`` have ``intent='out'``, +which means that the process ``AdvectionLax1D`` itself initializes and +computes a value for these two variables. Process "runtime" methods ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -99,62 +90,56 @@ Process "runtime" methods Beside its interface, the process ``AdvectionLax1D`` also implements methods that will be called during simulation runtime: -- ``initialize`` will be called once at the beginning of a +- ``.initialize()`` will be called once at the beginning of a simulation. Here it is used to set the x-coordinate values of the - grid and the initial values of ``u`` along the grid (gaussian + grid and the initial values of ``u`` along the grid (Gaussian pulse). -- ``run_step`` will be called at each time step iteration and have the - current time step duration as required argument. This is where the - Lax method is implemented. -- ``finalize_step`` will be called at each time step iteration too but - after having called ``run_step`` for all other processes (if +- ``.run_step()`` will be called at each time step iteration and have + the current time step duration as required argument. This is where + the Lax method is implemented. +- ``.finalize_step()`` will be called at each time step iteration too + but after having called ``run_step`` for all other processes (if any). Its intended use is mainly to ensure that state variables like ``u`` are updated consistently and after having taken snapshots. -A fourth method ``finalize`` could also be implemented, but it is not -needed in this case. This method is called once at the end of the -simulation, e.g., for cleaning purposes. +A fourth method ``.finalize()`` could also be implemented, but it is +not needed in this case. This method is called once at the end of the +simulation, e.g., for some clean-up. -Accessing process variables and values -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Getting / setting variable values +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The Variable objects declared in ``AdvectionLax1D`` can be accessed -elsewhere in the class like normal attributes, e.g., using ``self.u`` -for variable ``u``. +For each variable declared as class attributes in ``AdvectionLax1D`` +we can get their value (and/or set a value depending on their +``intent``) elsewhere in the class like if it was defined as regular +instance attributes, e.g., using ``self.u`` for variable ``u``. .. note:: - Like the other variables, ``self.u`` actually returns a copy of the - corresponding ``FloatVariable`` object that is originally declared - as a class attribute. Some internal magic happens in xarray-simlab - in order to avoid value conflicts when using the same process in - different contexts. + In xarray-simlab it is safe to run multiple simulations + concurrently: each simulation has its own process instances. -Variable objects may hold multiple, independent values that we set/get -via specific properties (see section :doc:`framework`), e.g., -``self.u.state`` for :math:`u` values and ``self.x.value`` for -x-coordinate values on the grid. Note that we use here the property -``value`` for all time-independent variables, which is just an alias -of ``state`` (this is purely conventional). - -Beside Variable object attributes, we can of course use normal -attributes in Process subclasses too, like ``self.u1`` in -``AdvectionLax1D``. +Beside variables declared in the process interface, nothing prevent us +from using regular attributes in process classes if needed. For +example, ``self.u1`` is set as a temporary internal state in +``AdvectionLax1D`` to wait for the "finalize step" stage before +updating :math:`u`. Creating a Model instance ------------------------- Creating a new :class:`~xsimlab.Model` instance is very easy. We just -need to provide a dictionary with the process(es) that we want to -include in the model, e.g., with only the process created above: +need to provide a dictionary with the process class(es) that we want +to include in the model, e.g., with only the process created above: .. literalinclude:: scripts/advection_model.py - :lines: 35-38 + :lines: 35 -That's it! Now we can use that model with the xarray extension provided -by xarray-simlab to create new setups, run the model, take snapshots -for one or more variables on a given frequency, etc. (see section -:doc:`run_model`). +That's it! Now we have different tools already available to inspect +the model (see section :doc:`inspect_model`). We can also use that +model with the xarray extension provided by xarray-simlab to create +new setups, run the model, take snapshots for one or more variables on +a given frequency, etc. (see section :doc:`run_model`). Fine-grained process refactoring -------------------------------- @@ -164,9 +149,9 @@ the initial conditions? Use a grid with variable spacing? Add another physical process impacting :math:`u` such as a source or sink term? In all cases we would need to modify the class ``AdvectionLax1D``. -This framework works best if instead we first split the problem into -small pieces, i.e., small Process subclasses that we can easily -combine and replace in models. +This framework works best if we instead split the problem into small +pieces, i.e., small process classes that we can easily combine and +replace in models. The ``AdvectionLax1D`` process may for example be refactored into 4 separate processes: @@ -183,57 +168,57 @@ This process declares all grid-related variables and computes x-coordinate values. .. literalinclude:: scripts/advection_model.py - :lines: 41-52 + :lines: 38-47 -``class Meta`` is used here to specify that this process is not time -dependent (by default processes are considered as -time-dependent). Grid x-coordinate values only need to be set once at -the beginning of the simulation ; there is no need to implement -``run_step`` here. +Grid x-coordinate values only need to be set once at the beginning of +the simulation ; there is no need to implement ``.run_step()`` here. **ProfileU** .. literalinclude:: scripts/advection_model.py - :lines: 55-69 + :lines: 50-62 -``u_vars`` is declared as a :class:`~xsimlab.VariableGroup`, i.e., an +``u_vars`` is declared as a :func:`~xsimlab.group` variable, i.e., an iterable of all variables declared elsewhere that belong the same -group ('u_vars' in this case). In this case, it allows to further add -one or more processes that would also impact :math:`u` in addition to -advection. +group ('u_vars' in this case). In this example, it allows to further +add one or more processes that will also affect the evolution of +:math:`u` in addition to advection (see below). + +Note also ``intent='inout'`` set for ``u``, which means that +``ProfileU`` updates the value of :math:`u` but still needs an initial +value from elsewhere. **AdvectionLax** .. literalinclude:: scripts/advection_model.py - :lines: 72-92 + :lines: 65-83 ``u_advected`` represents the effect of advection on the evolution of -:math:`u` and therefore belongs to the group 'u_vars'. By convention -we use the property ``change`` to store values for that variable. - -Computing values of ``u_advected`` requires access to the values of -variables ``spacing`` and ``u`` that are already declared in the -``UniformGrid1D`` and ``ProfileU`` classes, respectively. -:class:`~xsimlab.ForeignVariable` allows to declare references to -these external variables and handle them just as if these were the -original variables. For example, ``self.grid_spacing.value`` in this -class will return the same value than ``self.spacing`` in -``UniformGrid1D``. +:math:`u` and therefore belongs to the group 'u_vars'. + +Computing values of ``u_advected`` requires values of variables +``spacing`` and ``u`` that are already declared in the +``UniformGrid1D`` and ``ProfileU`` classes, respectively. Here we +declare them as :func:`~xsimlab.foreign` variables, which allows to +handle them like if these were the original variables. For example, +``self.grid_spacing`` in this class will return the same value than +``self.spacing`` in ``UniformGrid1D``. **InitUGauss** .. literalinclude:: scripts/advection_model.py - :lines: 95-109 + :lines: 86-96 -Note that ForeignVariable can also be used to set values for variables -that are declared in other processes, as for ``u`` here. +A foreign variable can also be used to set values for variables that +are declared in other processes, as for ``u`` here with +``intent='out'``. **Refactored model** We now have all the building blocks to create a more flexible model: .. literalinclude:: scripts/advection_model.py - :lines: 112-115 + :lines: 99-102 The order in which processes are given doesn't matter (it is a dictionary). A computationally consistent order, as well as model @@ -258,9 +243,9 @@ original, simple version. For this we create a new process: .. literalinclude:: scripts/advection_model.py - :lines: 118-142 + :lines: 105-130 -A couple of comments about this class: +Some comments about this class: - ``u_source`` belongs to the group 'u_vars' and therefore will be added to ``u_advected`` in ``ProfileU`` process. @@ -270,21 +255,21 @@ A couple of comments about this class: - Nearest node index and source rate array will be recomputed at each time iteration because variables ``loc`` and ``flux`` may both have a time dimension (variable source location and intensity), i.e., - ``self.loc.value`` and ``self.flux.value`` may both change at each + ``self.loc`` and ``self.flux`` may both change at each time iteration. In this example we also want to start with a flat, zero :math:`u` -profile instead of a gaussian pulse. We create another (minimal) +profile instead of a Gaussian pulse. We create another (minimal) process for that: .. literalinclude:: scripts/advection_model.py - :lines: 145-155 + :lines: 133-141 Using one command, we can then update the model with these new features: .. literalinclude:: scripts/advection_model.py - :lines: 158-159 + :lines: 144-145 Compared to ``model2``, this new ``model3`` have a new process named 'source' and a replaced process 'init'. @@ -295,7 +280,7 @@ It is also possible to create new models by removing one or more processes from existing Model instances, e.g., .. literalinclude:: scripts/advection_model.py - :lines: 162 + :lines: 148 In this latter case, users will have to provide initial values of :math:`u` along the grid directly as an input array. @@ -304,5 +289,5 @@ In this latter case, users will have to provide initial values of Model instances are immutable, i.e., once created it is not possible to modify these instances by adding, updating or removing - processes. Both methods ``.update_processes`` and - ``.drop_processes`` always return new Model instances. + processes. Both methods ``.update_processes()`` and + ``.drop_processes()`` always return new instances of ``Model``. diff --git a/doc/develop.rst b/doc/develop.rst index 086ffed4..b0eba214 100644 --- a/doc/develop.rst +++ b/doc/develop.rst @@ -53,7 +53,7 @@ To install the dependencies, we recommend using the conda_ package manager with the conda-forge_ channel. For development purpose, you might consider installing the packages in a new conda environment:: - $ conda create -n xarray-simlab_dev python=3.6 numpy xarray -c conda-forge + $ conda create -n xarray-simlab_dev python=3.6 attrs numpy xarray -c conda-forge $ source activate xarray-simlab_dev Then install xarray-simlab locally using ``pip``:: diff --git a/doc/environment.yml b/doc/environment.yml index 7476a860..6134daf4 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -3,16 +3,17 @@ channels: - conda-forge - defaults dependencies: + - attrs - python=3.5 - numpy=1.12 - pandas=0.22 - xarray=0.10.0 - - ipython=6.2.1 + - ipython=6.3.1 - ipykernel=4.6.1 - matplotlib=2.0.2 - graphviz - python-graphviz - nbconvert=5.2.1 - - sphinx=1.6.2 - - nbsphinx=0.3.1 + - sphinx=1.7.4 + - nbsphinx=0.3.3 - pandoc=1.19.2 diff --git a/doc/examples/landscape-evolution-model.ipynb b/doc/examples/landscape-evolution-model.ipynb index fd85dacd..b551e6c2 100644 --- a/doc/examples/landscape-evolution-model.ipynb +++ b/doc/examples/landscape-evolution-model.ipynb @@ -19,7 +19,7 @@ "source": [ "import numpy as np\n", "import xarray as xr\n", - "import xsimlab" + "import xsimlab as xs" ] }, { @@ -28,7 +28,7 @@ "source": [ "## Import and inspect a model\n", "\n", - "The model (i.e., the `xsimlab.Model` object) that we use here is provided by the [xarray-topo](https://gitext.gfz-potsdam.de/sec55-public/xarray-topo) package." + "The model (i.e., the `xsimlab.Model` object) that we use here is provided by the [xarray-topo](https://gitext.gfz-potsdam.de/sec55-public/xarray-topo) package (**Note:** check the version of this package below, it may not correspond to the latest stable release)." ] }, { @@ -40,7 +40,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "v0.0.10\n" + "v0.0.10+0.gb27cf6e.dirty\n" ] } ], @@ -93,32 +93,28 @@ { "data": { "text/plain": [ - "\n", + "\n", "grid\n", - " x_length (in) total grid length in x\n", - " x_origin (in) grid x-origin\n", - " x_size (in) nb. of nodes in x\n", - " x_spacing (in) node spacing in x\n", - " y_length (in) total grid length in y\n", - " y_origin (in) grid y-origin\n", - " y_size (in) nb. of nodes in y\n", - " y_spacing (in) node spacing in y\n", + " y_size [in] nb. of nodes in y\n", + " y_length [in] total grid length in y\n", + " x_size [in] nb. of nodes in x\n", + " x_length [in] total grid length in x\n", "boundaries\n", "block_uplift\n", - " u_coef (in) uplift rate\n", + " u_coef [in] () or ('y', 'x') uplift rate\n", "flow_routing\n", - " pit_method (in) \n", + " pit_method [in]\n", "area\n", "spower\n", - " k_coef (in) stream-power constant\n", - " m_exp (in) stream-power drainage area exponent\n", - " n_exp (in) stream-power slope exponent\n", + " n_exp [in] stream-power slope exponent\n", + " k_coef [in] stream-power constant\n", + " m_exp [in] stream-power drainage area exponent\n", "diffusion\n", - " k_coef (in) diffusivity\n", + " k_coef [in] diffusivity\n", "erosion\n", "uplift\n", "topography\n", - " elevation (in) topographic elevation" + " elevation [inout] ('y', 'x') topographic elevation" ] }, "execution_count": 4, @@ -146,7 +142,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABKkAAAIzCAYAAADLbkqhAAAAAXNSR0IArs4c6QAAQABJREFUeAHs\n3Qd8FVXaBvAnvffeSUgooffeQRRUwN4F1q5r2VVX1/1W3bWXtTdUsGIBUVBEpPdeAoSEFNJDeu/1\ne8+EGxJKSCAh9948x98w986cmTnzn4C57z3nPSb19fU/goUCFKAABShAAQpQgAIUoAAFKEABClCA\nAp0nUG0iQar6zrs+r0wBClCAAhSgAAUoQAEKUIACFKAABShAAVSaEoECFKAABShAAQpQgAIUoAAF\nKEABClCAAp0twCBVZz8BXp8CFKAABShAAQpQgAIUoAAFKEABClAADFLxh4ACFKAABShAAQpQgAIU\noAAFKEABClCg0wXMW9OCqvJ8rP/qatTWVLSmOuu0UcDDfxiGz/qwjUexOgUoQAEKUIACFKAABShA\nAQpQgAIUMB6BVgWpaqpKtABVSPhUWNu5GM/d68GdZKdForw0Ww9awiZQgAIUoAAFKEABClCAAhSg\nAAUoQIHOE2hVkErXPFevUNg5eunect0OAqVFWSgvT2qHM/EUFKAABShAAQpQgAIUoAAFKEABClDA\ncAWYk8pwnx1bTgEKUIACFKAABShAAQpQgAIUoAAFjEaAQSqjeZS8EQpQgAIUoAAFKEABClCAAhSg\nAAUoYLgCDFIZ7rNjyylAAQpQgAIUoAAFKEABClCAAhSggNEIMEhlNI+SN0IBClCAAhSgAAUoQAEK\nUIACFKAABQxXgEEqw312bDkFKEABClCAAhSgAAUoQAEKUIACFDAaAQapjOZR8kYoQAEKUIACFKAA\nBShAAQpQgAIUoIDhCjBIZbjPji2nAAUoQAEKUIACFKAABShAAQpQgAJGI8AgldE8St4IBShAAQpQ\ngAIUoAAFKEABClCAAhQwXAEGqQz32bHlFKAABShAAQpQgAIUoAAFKEABClDAaAQYpDKaR8kboQAF\nKEABClCAAhSgAAUoQAEKUIAChivAIJXhPju2nAIUoAAFKEABClCAAhSgAAUoQAEKGI0Ag1RG8yh5\nIxSgAAUoQAEKUIACFKAABShAAQpQwHAFGKQy3GfHllOAAhSgAAUoQAEKUIACFKAABShAAaMRYJDK\naB4lb4QCFKAABShAAQpQgAIUoAAFKEABChiuAINUhvvs2HIKUIACFKAABShAAQpQgAIUoAAFKGA0\n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\n6GaGr38VpSV5GDDl/1rRrDlVEiABEiABEiABEiABEiABEiABEiABEjg3AYpU52ZkES1Sjq1FbPhP\nGDD5X7Cxd7eIOXESJEACJEACJEACJEACJEACJEACJEACJGAuAhSpzEWyCfspLszE3lXPIqDXLHh3\nm9SEI7FrEiABEiABEiABEiABEiABEiABEiABEmgZAhSpWoZ7g0bd+8eT6GRli74T/tag89iYBEiA\nBEiABEiABEiABEiABEiABEiABFoLAbNk92stF9sa53ls79dIid2E0Ze/Bytrx9Z4CZwzCZAACZAA\nCZAACZAACZAACZAACZAACZyTAC2pzomo5Rpkpx7GoY1vosfwO+DmM6DlJsKRSYAESIAESIAESIAE\nSIAESIAESIAESKCJCVCkamLAje2+rLQQu5b9C519+iN02M2N7YbnkQAJkAAJkAAJkAAJkAAJkAAJ\nkAAJkECrIEB3Pwu9TQfWvoTigkyMumyBzLCDhc6S0yIBEiABEiABEiABEiABEiABEiABEiAB8xCg\nJZV5OJq1l4SIJYg7+DMGTv03bB09zdo3OyMBEiABEiABEiABEiABEiABEiABEiABSyRAkcrC7kp2\nagT2rX4e3QdfD6+u4y1sdpwOCZAACZAACZAACZAACZAACZAACZAACTQNAYpUTcO1Ub2WFGVhx9J/\nwM13AHqNvq9RffAkEiABEiABEiABEiABEiABEiABEiABEmiNBChSWchdO1leKgLVP3HyZDmGTH9O\nwlDx1ljIreE0SIAESIAESIAESIAESIAESIAESIAEmoEAA6c3A+T6DLHnjyeRfSICo2e/D2s71/qc\nwjYkQAIkQAIkQAIkQAIkQAIkQAIkQAIk0GYIUKSygFsZsXk+jketwPBZr8O5S6gFzIhTIAESIAES\nIAESIAESIAESIAESIAESIIHmJUCfsublXWu06N1fInLHJxgw+XF4BIyodZwVJEACJEACJEACJEAC\nJEACJEACJEACJNAeCFCkasG7HLP/e4RvmIe+4x+Cf8+LWnAmHJoESIAESIAESIAESIAESIDMsMMn\nAAAP3klEQVQESIAESIAEWpYARaoW4h938GccWPuikcWv64CrW2gWHJYESIAESIAESIAESIAESIAE\nSIAESIAELIMAY1K1wH2IPbAQ+9c8j7Bht6H7kBtbYAYckgRIgARIgARIgARIgARIgARIgARIgAQs\niwBFqma+HxqDSl38eo68G6HDbmnm0TkcCZAACZAACZAACZAACZAACZAACZAACVgmAYpUzXhfVKA6\nuPF1iUH1MLoOmNuMI3MoEiABEiABEiABEiABEiABEiABEiABErBsAh1OSqk6xcK8FKz6fDbKy4qq\nVnO7mQm4+w7C6NnvN/OoHI4ESIAESIAESIAESIAESIAESIAESIAEWoRAUS1LqpKiHEOgCu0/EzZ2\nzi0yq/Y+aOrxQ8jJTmnvGHj9JEACJEACJEACJEACJEACJEACJEAC7YhALZHKdO1uXt3h4ORh2uW6\nGQkU5GeISJXWjCNyKBIgARIgARIgARIgARIgARIgARIgARJoWQIdW3Z4jk4CJEACJEACJEACJEAC\nJEACJEACJEACJEACAEUqfgpIgARIgARIgARIgARIgARIgARIgARIgARanABFqha/BZwACZAACZAA\nCZAACZAACZAACZAACZAACZAARSp+BkiABEiABEiABEiABEiABEiABEiABEiABFqcAEWqFr8FnAAJ\nkAAJkAAJkAAJkAAJkAAJkAAJkAAJkABFKn4GSIAESIAESIAESIAESIAESIAESIAESIAEWpwARaoW\nvwWcAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAEUqfgZIgARIgARIgARIgARIgARIgARIgARIgARa\nnABFqha/BZwACZAACZAACZAACZAACZAACZAACZAACZAARSp+BkiABEiABEiABEiABEiABEiABEiA\nBEiABFqcAEWqFr8FnAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkABFKn4GSIAESIAESIAESIAESIAE\nSIAESIAESIAEWpwARaoWvwWcAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAEUqfgZIgARIgARIgARI\ngARIgARIgARIgARIgARanABFqha/BZwACZAACZAACZAACZAACZAACZAACZAACZAARao6PgNff7cY\nP/y0vI4jrCIBEiABEiABEiABEiABEiABEiABEiABEmgKAhSp6qD6y9I1+G3ZujqOsIoESIAESIAE\nSIAESIAESIAESIAESIAESKApCFg1Raetvc8PFjyNjh06tPbL4PxJgARIgARIgARIgARIgARIgARI\ngARIoNUQoEhVx62yt7Oto5ZVJEACJEACJEACJEACJEACJEACJEACJEACTUXgvEWq7Tv3IzklzZif\n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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -175,20 +171,18 @@ { "data": { "text/plain": [ - "\n", + "\n", "Variables:\n", - " * x Variable ('x')\n", - " x_length FloatVariable ()\n", - " x_origin FloatVariable ()\n", - " x_size IntegerVariable ()\n", - " x_spacing FloatVariable ()\n", - " * y Variable ('y')\n", - " y_length FloatVariable ()\n", - " y_origin FloatVariable ()\n", - " y_size IntegerVariable ()\n", - " y_spacing FloatVariable ()\n", - "Meta:\n", - " time_dependent: False" + " x_size [in] nb. of nodes in x\n", + " y_size [in] nb. of nodes in y\n", + " x_length [in] total grid length in x\n", + " y_length [in] total grid length in y\n", + " x_spacing [out]\n", + " y_spacing [out]\n", + " x [out] ('x',) \n", + " y [out] ('y',) \n", + "Simulation stages:\n", + " initialize" ] }, "execution_count": 6, @@ -220,7 +214,7 @@ "nx = 101\n", "ny = 101\n", "\n", - "in_ds = xsimlab.create_setup(\n", + "in_ds = xs.create_setup(\n", " model=fastscape_base_model,\n", " clocks={\n", " 'time': {'end': 1e6, 'step': 1e4},\n", @@ -235,7 +229,7 @@ " 'diffusion': {'k_coef': 1.},\n", " 'block_uplift': {'u_coef': 2e-3}\n", " },\n", - " snapshot_vars={\n", + " output_vars={\n", " 'out': {'topography': 'elevation'},\n", " None: {'grid': ('x', 'y')}\n", " }\n", @@ -287,15 +281,11 @@ " * out (out) float64 0.0 1e+05 2e+05 3e+05 4e+05 ...\n", "Dimensions without coordinates: x, y\n", "Data variables:\n", - " grid__x_length float64 1e+05\n", - " grid__x_origin float64 0.0\n", " grid__x_size int64 101\n", - " grid__x_spacing float64 1e+03\n", - " grid__y_length float64 1e+05\n", - " grid__y_origin float64 0.0\n", " grid__y_size int64 101\n", - " grid__y_spacing float64 1e+03\n", - " topography__elevation (y, x) float64 0.2121 0.1451 0.7867 0.614 ...\n", + " grid__x_length float64 1e+05\n", + " grid__y_length float64 1e+05\n", + " topography__elevation (y, x) float64 0.7405 0.8413 0.5533 0.06639 ...\n", " flow_routing__pit_method " + "" ] }, "metadata": {}, @@ -509,12 +491,244 @@ "data": { "text/html": [ "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "\n", - "\n", "\n", + "/**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + "function handle_clear_output(event, handle) {\n", + " var id = handle.cell.output_area._hv_plot_id;\n", + " if ((id === undefined) || !(id in HoloViews.plot_index)) { return; }\n", + " var comm = window.HoloViews.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", + " if (comm !== null) {\n", + " comm.send({event_type: 'delete', 'id': id});\n", + " }\n", + " delete HoloViews.plot_index[id];\n", + " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", + " window.Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "}\n", + "\n", + "/**\n", + " * Handle kernel restart event\n", + " */\n", + "function handle_kernel_cleanup(event, handle) {\n", + " delete HoloViews.comms[\"hv-extension-comm\"];\n", + " window.HoloViews.plot_index = {}\n", + "}\n", "\n", + "/**\n", + " * Handle update_display_data messages\n", + " */\n", + "function handle_update_output(event, handle) {\n", + " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", + " handle_add_output(event, handle)\n", + "}\n", "\n", - " \n", - " \n", - "\n", - "\n", - "
\n" + "function register_renderer(events, OutputArea) {\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " var toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[0]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " events.on('output_added.OutputArea', handle_add_output);\t\n", + " events.on('output_updated.OutputArea', handle_update_output);\n", + " events.on('clear_output.CodeCell', handle_clear_output);\n", + " events.on('delete.Cell', handle_clear_output);\n", + " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", + "\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " safe: true,\n", + " index: 0\n", + " });\n", + "}\n", + "\n", + "if (window.Jupyter !== undefined) {\n", + " try {\n", + " var events = require('base/js/events');\n", + " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " } catch(err) {\n", + " }\n", + "}\n", + "\n", + "// Define MPL specific subclasses\n", + "function MPLSelectionWidget() {\n", + " SelectionWidget.apply(this, arguments);\n", + "}\n", + "\n", + "function MPLScrubberWidget() {\n", + " ScrubberWidget.apply(this, arguments);\n", + "}\n", + "\n", + "// Let them inherit from the baseclasses\n", + "MPLSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\n", + "MPLScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n", + "\n", + "// Define methods to override on widgets\n", + "var MPLMethods = {\n", + " init_slider : function(init_val){\n", + " if(this.load_json) {\n", + " this.from_json()\n", + " } else {\n", + " this.update_cache();\n", + " }\n", + " if (this.dynamic | !this.cached | (this.current_vals === undefined)) {\n", + " this.update(0)\n", + " } else {\n", + " this.set_frame(this.current_vals[0], 0)\n", + " }\n", + " },\n", + " process_msg : function(msg) {\n", + " var data = msg.content.data;\n", + " this.frames[this.current] = data;\n", + " this.update_cache(true);\n", + " this.update(this.current);\n", + " }\n", + "}\n", + "// Extend MPL widgets with backend specific methods\n", + "extend(MPLSelectionWidget.prototype, MPLMethods);\n", + "extend(MPLScrubberWidget.prototype, MPLMethods);\n", + "\n", + "window.HoloViews.MPLSelectionWidget = MPLSelectionWidget\n", + "window.HoloViews.MPLScrubberWidget = MPLScrubberWidget\n", + "\n", + " function JupyterCommManager() {\n", + " }\n", + "\n", + " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", + " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", + " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", + " comm_manager.register_target(comm_id, function(comm) {\n", + " comm.on_msg(msg_handler);\n", + " });\n", + " } else if ((plot_id in HoloViews.kernels) && (HoloViews.kernels[plot_id])) {\n", + " HoloViews.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", + " comm.onMsg = msg_handler;\n", + " });\n", + " }\n", + " }\n", + "\n", + " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", + " if (comm_id in window.HoloViews.comms) {\n", + " return HoloViews.comms[comm_id];\n", + " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", + " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", + " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", + " if (msg_handler) {\n", + " comm.on_msg(msg_handler);\n", + " }\n", + " } else if ((plot_id in HoloViews.kernels) && (HoloViews.kernels[plot_id])) {\n", + " var comm = HoloViews.kernels[plot_id].connectToComm(comm_id);\n", + " comm.open();\n", + " if (msg_handler) {\n", + " comm.onMsg = msg_handler;\n", + " }\n", + " }\n", + " HoloViews.comms[comm_id] = comm;\n", + " return comm;\n", + " }\n", + "\n", + " window.HoloViews.comm_manager = new JupyterCommManager();\n", + " " ], - "text/plain": [ - "" - ] + "application/vnd.holoviews_load.v0+json": "function HoloViewsWidget() {\n}\n\nHoloViewsWidget.prototype.init_slider = function(init_val){\n if(this.load_json) {\n this.from_json()\n } else {\n this.update_cache();\n }\n}\n\nHoloViewsWidget.prototype.populate_cache = function(idx){\n this.cache[idx].innerHTML = this.frames[idx];\n if (this.embed) {\n delete this.frames[idx];\n }\n}\n\nHoloViewsWidget.prototype.process_error = function(msg){\n}\n\nHoloViewsWidget.prototype.from_json = function() {\n var data_url = this.json_path + this.id + '.json';\n $.getJSON(data_url, $.proxy(function(json_data) {\n this.frames = json_data;\n this.update_cache();\n this.update(0);\n }, this));\n}\n\nHoloViewsWidget.prototype.dynamic_update = function(current){\n if (current === undefined) {\n return\n }\n this.current = current;\n if (this.comm) {\n var msg = {comm_id: this.id+'_client', content: current}\n this.comm.send(msg);\n }\n}\n\nHoloViewsWidget.prototype.update_cache = function(force){\n var frame_len = Object.keys(this.frames).length;\n for (var i=0; i 0) {\n that.time = Date.now();\n that.dynamic_update(that.queue[that.queue.length-1]);\n that.queue = [];\n } else {\n that.wait = false;\n }\n if ((msg.msg_type == \"Ready\") && msg.content) {\n console.log(\"Python callback returned following output:\", msg.content);\n } else if (msg.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", msg['traceback'])\n }\n }\n var comm = HoloViews.comm_manager.get_client_comm(this.plot_id, this.id+'_client', ack_callback);\n return comm\n }\n}\n\nHoloViewsWidget.prototype.process_msg = function(msg) {\n}\n\nfunction SelectionWidget(frames, id, slider_ids, keyMap, dim_vals, notFound, load_json, mode, cached, json_path, dynamic, plot_id){\n this.frames = frames;\n this.id = id;\n this.plot_id = plot_id;\n this.slider_ids = slider_ids;\n this.keyMap = keyMap\n this.current_frame = 0;\n this.current_vals = dim_vals;\n this.load_json = load_json;\n this.mode = mode;\n this.notFound = notFound;\n this.cached = cached;\n this.dynamic = dynamic;\n this.cache = {};\n this.json_path = json_path;\n this.init_slider(this.current_vals[0]);\n this.queue = [];\n this.wait = false;\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms();\n }\n}\n\nSelectionWidget.prototype = new HoloViewsWidget;\n\n\nSelectionWidget.prototype.get_key = function(current_vals) {\n var key = \"(\";\n for (var i=0; i Date.now()))) {\n this.queue.push(key);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.current_frame = key;\n this.wait = true;\n this.dynamic_update(key)\n } else if (key !== undefined) {\n this.update(key)\n }\n}\n\n\n/* Define the ScrubberWidget class */\nfunction ScrubberWidget(frames, num_frames, id, interval, load_json, mode, cached, json_path, dynamic, plot_id){\n this.slider_id = \"_anim_slider\" + id;\n this.loop_select_id = \"_anim_loop_select\" + id;\n this.id = id;\n this.plot_id = plot_id;\n this.interval = interval;\n this.current_frame = 0;\n this.direction = 0;\n this.dynamic = dynamic;\n this.timer = null;\n this.load_json = load_json;\n this.mode = mode;\n this.cached = cached;\n this.frames = frames;\n this.cache = {};\n this.length = num_frames;\n this.json_path = json_path;\n document.getElementById(this.slider_id).max = this.length - 1;\n this.init_slider(0);\n this.wait = false;\n this.queue = [];\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms()\n }\n}\n\nScrubberWidget.prototype = new HoloViewsWidget;\n\nScrubberWidget.prototype.set_frame = function(frame){\n this.current_frame = frame;\n var widget = document.getElementById(this.slider_id);\n if (widget === null) {\n this.pause_animation();\n return\n }\n widget.value = this.current_frame;\n if(this.cached) {\n this.update(frame)\n } else {\n this.dynamic_update(frame)\n }\n}\n\n\nScrubberWidget.prototype.get_loop_state = function(){\n var button_group = document[this.loop_select_id].state;\n for (var i = 0; i < button_group.length; i++) {\n var button = button_group[i];\n if (button.checked) {\n return button.value;\n }\n }\n return undefined;\n}\n\n\nScrubberWidget.prototype.next_frame = function() {\n this.set_frame(Math.min(this.length - 1, this.current_frame + 1));\n}\n\nScrubberWidget.prototype.previous_frame = function() {\n this.set_frame(Math.max(0, this.current_frame - 1));\n}\n\nScrubberWidget.prototype.first_frame = function() {\n this.set_frame(0);\n}\n\nScrubberWidget.prototype.last_frame = function() {\n this.set_frame(this.length - 1);\n}\n\nScrubberWidget.prototype.slower = function() {\n this.interval /= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.faster = function() {\n this.interval *= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.anim_step_forward = function() {\n if(this.current_frame < this.length - 1){\n this.next_frame();\n }else{\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.first_frame();\n }else if(loop_state == \"reflect\"){\n this.last_frame();\n this.reverse_animation();\n }else{\n this.pause_animation();\n this.last_frame();\n }\n }\n}\n\nScrubberWidget.prototype.anim_step_reverse = function() {\n if(this.current_frame > 0){\n this.previous_frame();\n } else {\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.last_frame();\n }else if(loop_state == \"reflect\"){\n this.first_frame();\n this.play_animation();\n }else{\n this.pause_animation();\n this.first_frame();\n }\n }\n}\n\nScrubberWidget.prototype.pause_animation = function() {\n this.direction = 0;\n if (this.timer){\n clearInterval(this.timer);\n this.timer = null;\n }\n}\n\nScrubberWidget.prototype.play_animation = function() {\n this.pause_animation();\n this.direction = 1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n}\n\nScrubberWidget.prototype.reverse_animation = function() {\n this.pause_animation();\n this.direction = -1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n}\n\nfunction extend(destination, source) {\n for (var k in source) {\n if (source.hasOwnProperty(k)) {\n destination[k] = source[k];\n }\n }\n return destination;\n}\n\nfunction update_widget(widget, values) {\n if (widget.hasClass(\"ui-slider\")) {\n widget.slider('option', {\n min: 0,\n max: values.length-1,\n dim_vals: values,\n value: 0,\n dim_labels: values\n })\n widget.slider('option', 'slide').call(widget, event, {value: 0})\n } else {\n widget.empty();\n for (var i=0; i\", {\n value: i,\n text: values[i]\n }))\n };\n widget.data('values', values);\n widget.data('value', 0);\n widget.trigger(\"change\");\n };\n}\n\nfunction init_slider(id, plot_id, dim, values, next_vals, labels, dynamic, step, value, next_dim,\n dim_idx, delay, jQueryUI_CDN, UNDERSCORE_CDN) {\n // Slider JS Block START\n function loadcssfile(filename){\n var fileref=document.createElement(\"link\")\n fileref.setAttribute(\"rel\", \"stylesheet\")\n fileref.setAttribute(\"type\", \"text/css\")\n fileref.setAttribute(\"href\", filename)\n document.getElementsByTagName(\"head\")[0].appendChild(fileref)\n }\n loadcssfile(\"https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css\");\n /* Check if jQuery and jQueryUI have been loaded\n otherwise load with require.js */\n var jQuery = window.jQuery,\n // check for old versions of jQuery\n oldjQuery = jQuery && !!jQuery.fn.jquery.match(/^1\\.[0-4](\\.|$)/),\n jquery_path = '',\n paths = {},\n noConflict;\n var jQueryUI = jQuery.ui;\n // check for jQuery\n if (!jQuery || oldjQuery) {\n // load if it's not available or doesn't meet min standards\n paths.jQuery = jQuery;\n noConflict = !!oldjQuery;\n } else {\n // register the current jQuery\n define('jquery', [], function() { return jQuery; });\n }\n if (!jQueryUI) {\n paths.jQueryUI = jQueryUI_CDN.slice(null, -3);\n } else {\n define('jQueryUI', [], function() { return jQuery.ui; });\n }\n paths.underscore = UNDERSCORE_CDN.slice(null, -3);\n var jquery_require = {\n paths: paths,\n shim: {\n \"jQueryUI\": {\n exports:\"$\",\n deps: ['jquery']\n },\n \"underscore\": {\n exports: '_'\n }\n }\n }\n require.config(jquery_require);\n require([\"jQueryUI\", \"underscore\"], function(jUI, _){\n if (noConflict) $.noConflict(true);\n var vals = values;\n if (dynamic && vals.constructor === Array) {\n var default_value = parseFloat(value);\n var min = parseFloat(vals[0]);\n var max = parseFloat(vals[vals.length-1]);\n var wstep = step;\n var wlabels = [default_value];\n var init_label = default_value;\n } else {\n var min = 0;\n if (dynamic) {\n var max = Object.keys(vals).length - 1;\n var init_label = labels[value];\n var default_value = values[value];\n } else {\n var max = vals.length - 1;\n var init_label = labels[value];\n var default_value = value;\n }\n var wstep = 1;\n var wlabels = labels;\n }\n function adjustFontSize(text) {\n var width_ratio = (text.parent().width()/8)/text.val().length;\n var size = Math.min(0.9, Math.max(0.6, width_ratio))+'em';\n text.css('font-size', size);\n }\n var slider = $('#_anim_widget'+id+'_'+dim);\n slider.slider({\n animate: \"fast\",\n min: min,\n max: max,\n step: wstep,\n value: default_value,\n dim_vals: vals,\n dim_labels: wlabels,\n next_vals: next_vals,\n slide: function(event, ui) {\n var vals = slider.slider(\"option\", \"dim_vals\");\n var next_vals = slider.slider(\"option\", \"next_vals\");\n var dlabels = slider.slider(\"option\", \"dim_labels\");\n if (dynamic) {\n var dim_val = ui.value;\n if (vals.constructor === Array) {\n var label = ui.value;\n } else {\n var label = dlabels[ui.value];\n }\n } else {\n var dim_val = vals[ui.value];\n var label = dlabels[ui.value];\n }\n var text = $('#textInput'+id+'_'+dim);\n text.val(label);\n adjustFontSize(text);\n HoloViews.index[plot_id].set_frame(dim_val, dim_idx);\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n }\n });\n slider.keypress(function(event) {\n if (event.which == 80 || event.which == 112) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"max\");\n for (var i=start; i<=stop; i++) {\n var delay = i*delay;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n if (event.which == 82 || event.which == 114) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"min\");\n var count = 0;\n for (var i=start; i>=stop; i--) {\n var delay = count*delay;\n count = count + 1;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n });\n var textInput = $('#textInput'+id+'_'+dim)\n textInput.val(init_label);\n adjustFontSize(textInput);\n });\n}\n\nfunction init_dropdown(id, plot_id, dim, vals, value, next_vals, labels, next_dim, dim_idx, dynamic) {\n var widget = $(\"#_anim_widget\"+id+'_'+dim);\n widget.data('values', vals)\n for (var i=0; i\", {\n value: val,\n text: labels[i]\n }));\n };\n widget.data(\"next_vals\", next_vals);\n widget.val(value);\n widget.on('change', function(event, ui) {\n if (dynamic) {\n var dim_val = parseInt(this.value);\n } else {\n var dim_val = $.data(this, 'values')[this.value];\n }\n var next_vals = $.data(this, \"next_vals\");\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n var widgets = HoloViews.index[plot_id]\n if (widgets) {\n widgets.set_frame(dim_val, dim_idx);\n }\n });\n}\n\nif (window.HoloViews === undefined) {\n window.HoloViews = {}\n}\n\nvar _namespace = {\n init_slider: init_slider,\n init_dropdown: init_dropdown,\n comms: {},\n comm_status: {},\n index: {},\n plot_index: {},\n kernels: {},\n receivers: {}\n}\n\nfor (var k in _namespace) {\n if (!(k in window.HoloViews)) {\n window.HoloViews[k] = _namespace[k];\n }\n}\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if (!output.data.hasOwnProperty(EXEC_MIME_TYPE)) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n toinsert[0].children[0].innerHTML = output.data[HTML_MIME_TYPE];\n toinsert[0].children[1].textContent = output.data[JS_MIME_TYPE];\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n HoloViews.plot_index[id] = Bokeh.index[id];\n } else {\n HoloViews.plot_index[id] = null;\n }\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n if ((id === undefined) || !(id in HoloViews.plot_index)) { return; }\n var comm = window.HoloViews.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete HoloViews.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n window.Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete HoloViews.comms[\"hv-extension-comm\"];\n window.HoloViews.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\t\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n\n// Define MPL specific subclasses\nfunction MPLSelectionWidget() {\n SelectionWidget.apply(this, arguments);\n}\n\nfunction MPLScrubberWidget() {\n ScrubberWidget.apply(this, arguments);\n}\n\n// Let them inherit from the baseclasses\nMPLSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\nMPLScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n\n// Define methods to override on widgets\nvar MPLMethods = {\n init_slider : function(init_val){\n if(this.load_json) {\n this.from_json()\n } else {\n this.update_cache();\n }\n if (this.dynamic | !this.cached | (this.current_vals === undefined)) {\n this.update(0)\n } else {\n this.set_frame(this.current_vals[0], 0)\n }\n },\n process_msg : function(msg) {\n var data = msg.content.data;\n this.frames[this.current] = data;\n this.update_cache(true);\n this.update(this.current);\n }\n}\n// Extend MPL widgets with backend specific methods\nextend(MPLSelectionWidget.prototype, MPLMethods);\nextend(MPLScrubberWidget.prototype, MPLMethods);\n\nwindow.HoloViews.MPLSelectionWidget = MPLSelectionWidget\nwindow.HoloViews.MPLScrubberWidget = MPLScrubberWidget\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in HoloViews.kernels) && (HoloViews.kernels[plot_id])) {\n HoloViews.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.HoloViews.comms) {\n return HoloViews.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in HoloViews.kernels) && (HoloViews.kernels[plot_id])) {\n var comm = HoloViews.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n }\n HoloViews.comms[comm_id] = comm;\n return comm;\n }\n\n window.HoloViews.comm_manager = new JupyterCommManager();\n " }, "metadata": {}, "output_type": "display_data" @@ -1144,215 +1488,109 @@ "outputs": [ { "data": { - "text/html": [ - "
\n", - "
\n", - "
\n", + "application/javascript": [ + "\n", + "// Ugly hack - see #2574 for more information\n", + "if (!(document.getElementById('4838369880')) && !(document.getElementById('_anim_img243df457cda84b4b9d292c76dcc9d1d3'))) {\n", + " console.log(\"Creating DOM nodes dynamically for assumed nbconvert export. To generate clean HTML output set HV_DOC_HTML as an environment variable.\")\n", + " var htmlObject = document.createElement('div');\n", + " htmlObject.innerHTML = `
\n", + "
\n", + "
\n", " \n", " \n", " \n", "
\n", "
\n", - "
\n", - "
\n", + "
\n", + " \n", " \n", " \n", "
\n", - "
\n", - "\t \n", - " \n", + " \n", " \n", " \n", "
\n", - "
\n", - "\n", - "\n", - "" + "var widget_ids = new Array(1);\n", + "\n", + "\n", + "widget_ids[0] = \"_anim_widget243df457cda84b4b9d292c76dcc9d1d3_out\";\n", + "\n", + "\n", + "function create_widget() {\n", + " var frame_data = {\"0\": \"\", \"1\": \"\", \"2\": \"\", \"3\": \"\", \"4\": \"\", \"5\": \"\", \"6\": \"\", \"7\": \"\", \"8\": \"\", \"9\": \"\", \"10\": \"\"};\n", + " var dim_vals = ['0.0'];\n", + " var keyMap = {\"('0.0',)\": 0, \"('100000.0',)\": 1, \"('200000.0',)\": 2, \"('300000.0',)\": 3, \"('400000.0',)\": 4, \"('500000.0',)\": 5, \"('600000.0',)\": 6, \"('700000.0',)\": 7, \"('800000.0',)\": 8, \"('900000.0',)\": 9, \"('1000000.0',)\": 10};\n", + " var notFound = \"

\n", + "
\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

" ], "text/plain": [ ":HoloMap [out]\n", @@ -1360,7 +1598,11 @@ ] }, "execution_count": 14, - "metadata": {}, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": 4838369880 + } + }, "output_type": "execute_result" } ], @@ -1415,9 +1657,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1450,7 +1692,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1487,15 +1729,11 @@ " * out (out) float64 0.0 1e+05 2e+05 3e+05 4e+05 ...\n", "Dimensions without coordinates: x, y\n", "Data variables:\n", - " grid__x_length float64 1e+05\n", - " grid__x_origin float64 0.0\n", " grid__x_size int64 101\n", - " grid__x_spacing float64 1e+03\n", - " grid__y_length float64 1e+05\n", - " grid__y_origin float64 0.0\n", " grid__y_size int64 101\n", - " grid__y_spacing float64 1e+03\n", - " topography__elevation (y, x) float64 0.2121 0.1451 0.7867 0.614 ...\n", + " grid__x_length float64 1e+05\n", + " grid__y_length float64 1e+05\n", + " topography__elevation (y, x) float64 0.7405 0.8413 0.5533 0.06639 ...\n", " flow_routing__pit_method " + "" ] }, "metadata": {}, @@ -1623,20 +1861,16 @@ " * y (y) float64 0.0 1e+03 2e+03 3e+03 4e+03 5e+03 ...\n", " * spower__k_coef (spower__k_coef) float64 5e-05 6e-05 7e-05\n", "Data variables:\n", - " grid__x_length float64 1e+05\n", - " grid__x_origin float64 0.0\n", " grid__x_size int64 101\n", - " grid__x_spacing float64 1e+03\n", - " grid__y_length float64 1e+05\n", - " grid__y_origin float64 0.0\n", " grid__y_size int64 101\n", - " grid__y_spacing float64 1e+03\n", + " grid__x_length float64 1e+05\n", + " grid__y_length float64 1e+05\n", " flow_routing__pit_method \n", - "
\n", - "
\n", + "application/javascript": [ + "\n", + "// Ugly hack - see #2574 for more information\n", + "if (!(document.getElementById('4849944672')) && !(document.getElementById('_anim_img223e300e1980416d9c840b47a7f91119'))) {\n", + " console.log(\"Creating DOM nodes dynamically for assumed nbconvert export. To generate clean HTML output set HV_DOC_HTML as an environment variable.\")\n", + " var htmlObject = document.createElement('div');\n", + " htmlObject.innerHTML = `
\n", + "
\n", + "
\n", " \n", " \n", " \n", "
\n", "
\n", - "
\n", - "
\n", + "
\n", + " \n", " \n", " \n", "
\n", - "
\n", - "\t \n", - " \n", + " \n", " \n", " \n", "
\n", - "
\n", - "\t \n", - " \n", + " \n", " \n", " \n", "
\n", - "
\n", - "\n", - "\n", - "" + "var widget_ids = new Array(2);\n", + "\n", + "\n", + "widget_ids[0] = \"_anim_widget223e300e1980416d9c840b47a7f91119_out\";\n", + "\n", + "widget_ids[1] = \"_anim_widget223e300e1980416d9c840b47a7f91119_spower__k_coef\";\n", + "\n", + "\n", + "function create_widget() {\n", + " var frame_data = {\"0\": \"\", \"1\": \"\", \"2\": \"\", \"3\": \"\", \"4\": \"\", \"5\": \"\", \"6\": \"\", \"7\": \"\", \"8\": \"\", \"9\": \"\", \"10\": \"\", \"11\": \"\", \"12\": \"\", \"13\": \"\", \"14\": \"\", \"15\": \"\", \"16\": \"\", \"17\": \"\", \"18\": \"\", \"19\": \"\", \"20\": \"\", \"21\": \"\", \"22\": \"\", \"23\": \"\", \"24\": \"\", \"25\": \"\", \"26\": \"\", \"27\": \"\", \"28\": \"\", \"29\": \"\", \"30\": \"\", \"31\": \"\", \"32\": \"\"};\n", + " var dim_vals = ['0.0', '0.000050000'];\n", + " var keyMap = {\"('0.0', '0.000050000')\": 0, \"('0.0', '0.000060000')\": 1, \"('0.0', '0.000070000')\": 2, \"('100000.0', '0.000050000')\": 3, \"('100000.0', '0.000060000')\": 4, \"('100000.0', '0.000070000')\": 5, \"('200000.0', '0.000050000')\": 6, \"('200000.0', '0.000060000')\": 7, \"('200000.0', '0.000070000')\": 8, \"('300000.0', '0.000050000')\": 9, \"('300000.0', '0.000060000')\": 10, \"('300000.0', '0.000070000')\": 11, \"('400000.0', '0.000050000')\": 12, \"('400000.0', '0.000060000')\": 13, \"('400000.0', '0.000070000')\": 14, \"('500000.0', '0.000050000')\": 15, \"('500000.0', '0.000060000')\": 16, \"('500000.0', '0.000070000')\": 17, \"('600000.0', '0.000050000')\": 18, \"('600000.0', '0.000060000')\": 19, \"('600000.0', '0.000070000')\": 20, \"('700000.0', '0.000050000')\": 21, \"('700000.0', '0.000060000')\": 22, \"('700000.0', '0.000070000')\": 23, \"('800000.0', '0.000050000')\": 24, \"('800000.0', '0.000060000')\": 25, \"('800000.0', '0.000070000')\": 26, \"('900000.0', '0.000050000')\": 27, \"('900000.0', '0.000060000')\": 28, \"('900000.0', '0.000070000')\": 29, \"('1000000.0', '0.000050000')\": 30, \"('1000000.0', '0.000060000')\": 31, \"('1000000.0', '0.000070000')\": 32};\n", + " var notFound = \"

\n", + "
\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + " \n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

" ], "text/plain": [ ":HoloMap [out,spower__k_coef]\n", @@ -2042,7 +2048,11 @@ ] }, "execution_count": 23, - "metadata": {}, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": 4849944672 + } + }, "output_type": "execute_result" } ], @@ -2058,7 +2068,7 @@ "source": [ "## Create an alternative version of the model\n", "\n", - "xarray-simlab makes it easy to create alternative versions of a model. In the example below, instead of using constant block uplift, we set a linear uplift function along the $x$ dimension. The first step is to create a new `Process` class. " + "xarray-simlab makes it easy to create alternative versions of a model. In the example below, instead of using constant block uplift, we set a linear uplift function along the $x$ dimension. The first step is to create a new process, i.e., a Python class decorated by ``xsimlab.process``. " ] }, { @@ -2069,29 +2079,31 @@ }, "outputs": [], "source": [ - "from xtopo.models.fastscape_base import StackedGridXY, BoundaryFacesXY\n", - "from xsimlab import Process, FloatVariable, Variable, ForeignVariable\n", + "from xtopo.models.fastscape_base import Grid2D, ClosedBoundaryFaces\n", "\n", "\n", - "class VariableUplift(xsimlab.Process):\n", + "@xs.process\n", + "class VariableUplift(object):\n", " \"\"\"Compute spatially variable uplift as a linear function of x.\"\"\"\n", " \n", - " x_coef = FloatVariable((), description='uplift function x coefficient')\n", - " active_nodes = ForeignVariable(BoundaryFacesXY, 'active_nodes')\n", - " x = ForeignVariable(StackedGridXY, 'x')\n", - " uplift = Variable((), provided=True, group='uplift')\n", + " x_coef = xs.variable(description='uplift function x coefficient')\n", + " \n", + " active_nodes = xs.foreign(ClosedBoundaryFaces, 'active_nodes')\n", + " x = xs.foreign(Grid2D, 'x')\n", + " \n", + " uplift = xs.variable(intent='out', group='uplift')\n", "\n", " def initialize(self):\n", - " mask = self.active_nodes.value\n", + " mask = self.active_nodes\n", " ny, nx = mask.shape\n", "\n", - " u_rate = np.ones((ny, nx)) * self.x_coef.value * self.x.value[None, :]\n", + " u_rate = np.ones((ny, nx)) * self.x_coef * self.x[None, :]\n", " \n", - " self.uplift.rate = np.zeros((ny, nx))\n", - " self.uplift.rate[mask] = u_rate[mask]\n", + " self._u_rate = np.zeros((ny, nx))\n", + " self._u_rate[mask] = u_rate[mask]\n", "\n", " def run_step(self, dt):\n", - " self.uplift.value = self.uplift.rate * dt\n" + " self.uplift = self._u_rate * dt\n" ] }, { @@ -2109,32 +2121,28 @@ { "data": { "text/plain": [ - "\n", + "\n", "grid\n", - " x_length (in) total grid length in x\n", - " x_origin (in) grid x-origin\n", - " x_size (in) nb. of nodes in x\n", - " x_spacing (in) node spacing in x\n", - " y_length (in) total grid length in y\n", - " y_origin (in) grid y-origin\n", - " y_size (in) nb. of nodes in y\n", - " y_spacing (in) node spacing in y\n", + " y_size [in] nb. of nodes in y\n", + " y_length [in] total grid length in y\n", + " x_size [in] nb. of nodes in x\n", + " x_length [in] total grid length in x\n", "boundaries\n", "flow_routing\n", - " pit_method (in) \n", + " pit_method [in]\n", "area\n", "spower\n", - " k_coef (in) stream-power constant\n", - " m_exp (in) stream-power drainage area exponent\n", - " n_exp (in) stream-power slope exponent\n", + " n_exp [in] stream-power slope exponent\n", + " k_coef [in] stream-power constant\n", + " m_exp [in] stream-power drainage area exponent\n", "diffusion\n", - " k_coef (in) diffusivity\n", + " k_coef [in] diffusivity\n", "erosion\n", "uplift_func\n", - " x_coef (in) uplift function x coefficient\n", + " x_coef [in] uplift function x coefficient\n", "uplift\n", "topography\n", - " elevation (in) topographic elevation" + " elevation [inout] ('y', 'x') topographic elevation" ] }, "execution_count": 25, @@ -2190,9 +2198,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\nAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2211,215 +2219,109 @@ "outputs": [ { "data": { - "text/html": [ - "
\n", - "
\n", - "
\n", + "application/javascript": [ + "\n", + "// Ugly hack - see #2574 for more information\n", + "if (!(document.getElementById('4846779416')) && !(document.getElementById('_anim_img1e0d684e6f4e43239ed8bf308478af1c'))) {\n", + " console.log(\"Creating DOM nodes dynamically for assumed nbconvert export. To generate clean HTML output set HV_DOC_HTML as an environment variable.\")\n", + " var htmlObject = document.createElement('div');\n", + " htmlObject.innerHTML = `
\n", + "
\n", + "
\n", " \n", " \n", " \n", "
\n", "
\n", - "
\n", - "
\n", + "
\n", + " \n", " \n", " \n", "
\n", - "
\n", - "\t \n", - " \n", + " \n", " \n", " \n", "
\n", - "
\n", - "\n", - "\n", - "" + "var widget_ids = new Array(1);\n", + "\n", + "\n", + "widget_ids[0] = \"_anim_widget1e0d684e6f4e43239ed8bf308478af1c_out\";\n", + "\n", + "\n", + "function create_widget() {\n", + " var frame_data = {\"0\": \"\", \"1\": \"\", \"2\": \"\", \"3\": \"\", \"4\": \"\", \"5\": \"\", \"6\": \"\", \"7\": \"\", \"8\": \"\", \"9\": \"\", \"10\": \"\"};\n", + " var dim_vals = ['0.0'];\n", + " var keyMap = {\"('0.0',)\": 0, \"('100000.0',)\": 1, \"('200000.0',)\": 2, \"('300000.0',)\": 3, \"('400000.0',)\": 4, \"('500000.0',)\": 5, \"('600000.0',)\": 6, \"('700000.0',)\": 7, \"('800000.0',)\": 8, \"('900000.0',)\": 9, \"('1000000.0',)\": 10};\n", + " var notFound = \"

\n", + "
\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + " \n", + " \n", + "
\n", + "
\n", + "

" ], "text/plain": [ ":HoloMap [out]\n", @@ -2427,7 +2329,11 @@ ] }, "execution_count": 28, - "metadata": {}, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": 4846779416 + } + }, "output_type": "execute_result" } ], diff --git a/doc/faq.rst b/doc/faq.rst index 51748b8a..788fb80c 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -35,17 +35,20 @@ main bottleneck of the overall model execution, especially when using an implicit time scheme. For inner (e.g., spatial) loops in each model processes, it might be better to have a numpy vectorized implementation, use tools like Cython_ or Numba_ or call wrapped code -that is written in, e.g., C or Fortran (see for example f2py_ for -wrapping Fortran code). +that is written in, e.g., C/C++ or Fortran (see for example f2py_ for +wrapping Fortran code or pybind11_ for wrapping C++11 code). As with any other framework, xarray-simlab introduces an overhead compared to a simple, straightforward (but non-flexible) implementation of a model. The preliminary benchmarks that we have run -show only a very small overhead, though. +show only a very small (almost free) overhead, though. This overhead +is mainly introduced by the thin object-oriented layer that model +components (i.e., Python classes) together form. .. _Cython: http://cython.org/ .. _Numba: http://numba.pydata.org/ .. _f2py: https://docs.scipy.org/doc/numpy-dev/f2py/ +.. _pybind11: https://pybind11.readthedocs.io Does xarray-simlab support running model(s) in parallel? -------------------------------------------------------- diff --git a/doc/framework.rst b/doc/framework.rst index 185d6f56..8c86f30c 100644 --- a/doc/framework.rst +++ b/doc/framework.rst @@ -40,8 +40,8 @@ The Model class also implements specific methods for: Processes --------- -Processes are defined as custom Python classes that inherit from the -base class :class:`~xsimlab.Process`. The role of a process is twofold: +Processes are defined as Python classes that are decorated by +:func:`~xsimlab.process`. The role of a process is twofold: - declare a given subset of the variables used in a model, - define a specific set of instructions that use or compute values for @@ -52,41 +52,54 @@ model. It may for example represent a particular physical mechanism that is described in terms of one or more state variables (e.g., scalar or vector fields) and one or more operations -- with or without parameters -- that modify those state variables through time. Note -that some processes may be time-independent. +that some processes may be time-independent or may even be used to +declare variables without implementing any computation. .. note:: xarray-simlab does not provide any built-in logic for tasks like generating computational meshes or setting boundary conditions, which should rather be implemented in 3rd-party libraries as - time-independent processes. Even those tasks may be too specialized - to justify including them in this framework, which aims to be as - general as possible. + processes. Even those tasks may be too specialized to justify + including them in this framework, which aims to be as general as + possible. + +A process-ified class behaves mostly like any other regular Python +class, i.e., there is a-priori nothing that prevents you from using +the common object-oriented features as you like. The only difference +is that you can here create classes in a very succinct way without +boilerplate, i.e., you don't need to implement dunder methods like +``__init__`` or ``__repr__`` as this is handled by the framework. In +fact, this framework uses and extends the attrs_ package: +:func:`~xsimlab.process` is a wrapper around :func:`attr.s` and the +functions used to create variables (see below) are thin wrappers +around :func:`attr.ib`. + +.. _attrs: http://www.attrs.org Variables --------- -Variables are the most basic elements of a model. They consist of -:class:`~xsimlab.Variable` [*]_ objects that are declared in processes as class -attributes. They have the following properties: +Variables are the most basic elements of a model. They are declared in +processes as class attributes, using :func:`~xsimlab.variable`. +Declaring variables mainly consists of defining useful metadata such +as: -- data values (state, rate or change -- see below), -- validators, i.e., callables for checking supplied data values, - labeled dimensions (or no dimension for scalars), -- predefined meta-data attributes like description or default value, -- user-defined meta-data attributes (e.g., units, math symbol). +- predefined meta-data attributes, e.g., a short description, +- user-defined meta-data attributes, e.g., units or math symbol, +- the intent for a variable, i.e., whether the process + needs (``intent='in'``), updates (``intent='inout'``) or computes + (``intent='out'``) a value for that variable. .. note:: - xarray-simlab does not distinguish between model parameters - and state variables. Both are declared as Variable objects. - -.. [*] usually variables consist of objects of derived classes like, - e.g., ``FloatVariable`` or ``IntegerVariable`` depending on their - expected value type. + xarray-simlab does not distinguish between model parameters, input + and output variables. All can be declared using + :func:`~xsimlab.variable`. Foreign variables ------------------ +~~~~~~~~~~~~~~~~~ Like different physical mechanisms involve some common state variables (e.g., temperature or pressure), different processes may operate on @@ -94,11 +107,18 @@ common variables. In xarray-simlab, a variable is declared at a unique place, i.e., within one and only one process. Using common variables across -processes is achieved by declaring foreign variables. -:class:`~xsimlab.ForeignVariable` objects are references to -variables that are declared in other processes ; it allows getting or -setting values just as if these references were the original -variables. +processes is achieved by declaring :func:`~xsimlab.foreign` +variables. These are simply references to variables that are declared +in other processes. + +You can use foreign variables for almost any computation inside a +process just like original variables. The only difference is that +``intent='inout'`` is not supported for a foreign variable, i.e., a +process may either need or compute a value of a foreign variable but +may not update it (otherwise it would not be possible to unambiguously +determine process dependencies -- see below). For the same reason, +only one process in a model may compute a value of a variable (i.e., +``intent='out'``). The great advantage of declaring variables at unique places is that all their meta-data are defined once. However, a downside of this @@ -106,62 +126,41 @@ approach is that foreign variables may potentially add many hard-coded links between processes, which makes harder reusing these processes independently of each other. -Variable groups ---------------- +Group variables +~~~~~~~~~~~~~~~ -In some cases, using variables groups may provide an elegant +In some cases, using group variables may provide an elegant alternative to hard-coded links between processes. -The membership of Variable objects to a group is defined via their -``group`` attribute. If we want to use in a separate process all the -variables of a group, instead of explicitly declaring foreign -variables we can declare a :class:`~xsimlab.VariableGroup` object -which behaves like an iterable of ForeignVariable objects pointing to -each of the variables of the group. - -Variable groups are useful particularly in cases where we want to -combine different processes that act on the same variable, e.g. in -landscape evolution modeling combine the effect of different erosion -processes on the evolution of the surface elevation. This way we can -easily add or remove processes to/from a model and avoid missing or -broken links between processes. - -Variable state, rate and change -------------------------------- - -A single variable may accept up to 3 concurrent values that each -have a particular meaning: +The membership of variables to a group is defined via their ``group`` +attribute. If you want to use in a separate process all the variables +of a group, instead of explicitly declaring foreign variables you can +declare a :func:`~xsimlab.group` variable. The latter behaves like an +iterable of foreign variables pointing to each of the variables that +are members of the group, across the model. -- a state, i.e., the value of the variable at a given time, -- a rate, i.e., the value of the time-derivative at a given time, -- a change, i.e., the value of the time-derivative integrated for a given - time step. +Note that group variables only support ``intent='in'``, i.e, group +variables should only be used to get the values of multiple foreign +variables of a same group. -These are accessible as properties of Variable and ForeignVariable -objects: ``state``, ``rate`` and ``change``. An additional property -``value`` is defined as an alias of ``state``. +Group variables are useful particularly in cases where you want to +combine (aggregate) different processes that act on the same +variable, e.g. in landscape evolution modeling combine the effect of +different erosion processes on the evolution of the surface +elevation. This way you can easily add or remove processes to/from a +model and avoid missing or broken links between processes. -.. note:: - - These properties are for convenience only, it avoids having to - duplicate Variable objects for state variables. The properties are - independent of each other and their given meanings serve only as - conventions. Although there is no restriction in using any of these - properties anywhere in a process, it is good practice to follow - these conventions. - -.. note:: +On-demand variables +~~~~~~~~~~~~~~~~~~~ - The ``rate`` and ``change`` properties should never be used for - variables other than state variables. Moreover, it is preferable - to use the alias ``value`` instead of ``state`` as the latter is - quite meaningless in this case. +On-demand variables are like regular variables, except that their +value is not intended to be computed systematically, e.g., at each +time step of a simulation, but instead only at a given few +times. These are declared using :func:`~xsimlab.on_demand` and must +implement in the same process-ified class a dedicated method that +computes their value. They have always ``intent='out'``. -.. todo_move_this_elsewhere - - For state variables, a common practice is to compute ``rate`` or - ``change`` values during the "run step" stage and update ``state`` - values during the "finalize step" stage. +On-demand variables are useful, e.g., for model diagnostics. Simulation workflow ------------------- @@ -173,35 +172,55 @@ A model run is divided into four successive stages: 3. finalize step 4. finalization -During a simulation, stages 1 and 4 are run only once while steps 2 +During a simulation, stages 1 and 4 are run only once while stages 2 and 3 are repeated for a given number of (time) steps. -Each process provides its own computation instructions for those -stages. Note that this is optional, except for time-dependent -processes that must provide some instructions at least for stage 2 -(run step). For time-independent processes stages 2 and 3 are ignored. +Each process-ified class may provide its own computation instructions +by implementing specific methods named ``.initialize()``, +``.run_step()``, ``.finalize_step()`` and ``.finalize()`` for each +stage above, respectively. Note that this is entirely optional. For +example, time-independent processes (e.g., for setting model grids) +usually implement stage 1 only. In a few cases, the role of a process +may even consist of just declaring some variables that are used +elsewhere. + +Get / set variable values inside a process +------------------------------------------ + +Once you have declared a variable as a class attribute in a process, you +can further get and/or set its value like it was defined as a property +of that class. For example, if you declare a variable ``foo`` you can +just use ``self.foo`` to get/set its value inside one method of that +class. + +This is exactly what does the :func:`~xsimlab.process` decorator: it +takes all variables declared as class attributes and turns them into +properties, which may be read-only depending on the ``intent`` set for +the variables. + +Basically, the getter (setter) methods of these properties read +(write) values from (into) a simple key-value store (except for +on-demand variables). Currently the store is fully in-memory but it +could be easily replaced by an on-disk or a distributed store. The +xarray-simlab's modeling framework can thus be viewed as a thin +object-oriented layer built on top of an abstract key-value store. Process dependencies and ordering --------------------------------- The order in which processes are executed during a simulation is -critical. For example, if the role of a process is to provide a value +critical. For example, if the role of a process is to compute a value for a given variable, then the execution of this process must happen before the execution of all other processes that use the same variable in their computation. -Such role can be defined using the ``provided`` attribute of Variable -and ForeignVariable objects, which is either set to True or False -(note that a process may still update a variable value even if -``provided`` is set to False, see Model inputs section below). - In a model, the processes and their dependencies together form the nodes and the edges of a Directed Acyclic Graph (DAG). The graph -topology is fully determined by the role set for each variable or -foreign variable declared in each process. An ordering that is +topology is fully determined by the ``intent`` set for each variable +or foreign variable declared in each process. An ordering that is computationally consistent can then be obtained using topological -sorting. This is done at Model object creation. The same ordering -is used at every stage of a model run. +sorting. This is done at Model object creation. The same ordering is +used at every stage of a model run. In principle, the DAG structure would also allow running the processes in parallel at every stage of a model run. This is not yet @@ -214,20 +233,7 @@ In a model, inputs are variables that need a value to be set by the user before running a simulation. Like process ordering, inputs are automatically retrieved at Model -object creation, using the ``provided`` attribute of Variable and -ForeignVariable objects. Inputs are Variable objects for which -``provided`` is set to False and which don't have any linked -ForeignVariable object with ``provided`` set to True. - -.. note:: - - Any value required as model input relates to the ``state`` property - (or its alias ``value``) of a Variable object. The ``rate`` and - ``change`` properties should never be set by model users, like any - property of ForeignVariable objects. - -.. move_this_foreign_variable - - ForeignVariable.state return the same object (usually a numpy array) than - Variable.state (replace class names by variable names in processes). - ForeignVariable.state is actually a shortcut to ForeignVariable.ref_var.state. +object creation by looking at the ``intent`` set for all variables and +foreign variables in the model. A variable is a model input if it has +``intent`` set to ``'in'`` or ``'inout'`` and if it has no linked +foreign variable with ``intent='out'``. diff --git a/doc/inspect_model.rst b/doc/inspect_model.rst index 59599310..231041f3 100644 --- a/doc/inspect_model.rst +++ b/doc/inspect_model.rst @@ -13,19 +13,45 @@ this user guide. import sys sys.path.append('scripts') - from advection_model import model2 + from advection_model import model2, ProfileU -Inspect processes and variables -------------------------------- +.. ipython:: python + + import xsimlab as xs + +Inspect model inputs +-------------------- Model *repr* already gives information about the number and names of -processes and their variables that need an input value (if provided, a -short description is also displayed for these variables): +processes and their variables that need an input value (if any): .. ipython:: python model2 +For each input, a one-line summary is shown with the intent (either +'in' or 'inout') as well as the dimension labels for inputs that don't +expect a scalar value only. If provided, a short description is also +displayed in the summary. + +The convenient property :attr:`~xsimlab.Model.input_vars` of Model +returns all inputs as a list of 2-length tuples with process and +variable names, respectively. + +.. ipython:: python + + model2.input_vars + +:attr:`~xsimlab.Model.input_vars_dict` returns all inputs grouped by +process, as a dictionary: + +.. ipython:: python + + model2.input_vars_dict + +Inspect processes and variables +------------------------------- + For deeper inspection, Model objects support both dict-like and attribute-like access to their processes, e.g., @@ -36,34 +62,41 @@ attribute-like access to their processes, e.g., As shown here above, process *repr* includes: -- the path to the corresponding Process subclass (top line) ; +- the name to the process class and the name of the process in the model + (top line) ; - a "Variables" section with all variables declared in the process - (not only model inputs), their types (e.g., ``FloatVariable``, - ``ForeignVariable``) and some additional information depending on - their type like dimension labels for regular variables or references - to original variables for ``ForeignVariable`` objects ; -- a "Meta" section with all process metadata. + (not only model inputs) including one-line summaries that depend on + their type (i.e., ``variable``, ``foreign``, ``group``, etc.) ; +- a "Simulation stages" section with the stages that are implemented + in the process. -In "Variables" section, symbol ``*`` means that a value for the -variable is provided by the process itself (i.e., ``provided=True``). - -Processes also support dict-like and attribute-like access to all -their declared variables, e.g., +It is also possible to inspect a process class taken individually with +:func:`~xsimlab.process_info`: .. ipython:: python - model2['advect']['v'] - model2.grid.x + xs.process_info(ProfileU) + +Similarly, :func:`~xsimlab.variable_info` allows inspection at the +variable level: -It is also possible to have direct access to all input variables in a -model using the :attr:`~xsimlab.Model.input_vars` property. +.. ipython:: python -We can further test whether a variable is a model input or not, e.g., + xs.variable_info(ProfileU, 'u') + xs.variable_info(model2.profile, 'u_vars') + +Alternatively, we can look at the docstrings of auto-generated +properties for each variable, e.g., .. ipython:: python - model2.is_input(('advect', 'v')) - model2.is_input(('profile', 'u')) + ProfileU.u? + +Like :attr:`~xsimlab.Model.input_vars` and +:attr:`~xsimlab.Model.input_vars_dict`, Model properties +:attr:`~xsimlab.Model.all_vars` and +:attr:`~xsimlab.Model.all_vars_dict` are available for all model +variables, not only inputs. Visualize models as graphs -------------------------- @@ -115,10 +148,10 @@ square nodes: :width: 60% Nodes with solid border correspond to regular variables while nodes -with dashed border correspond to ``ForeignVariable`` objects. 3d-box -nodes correspond to iterables of Variable objects, like -``VariableGroup``. Variables connected to their process with an arrow -have a value provided by the process. +with dashed border correspond to foreign variables. 3d-box nodes +correspond group variables. Variables connected to their process with +an arrow have a value computed by the process itself (i.e., +``intent='out'``). A third option ``show_only_variable`` allows to show only one given variable and all its references in other processes, e.g., diff --git a/doc/installing.rst b/doc/installing.rst index ea6f8658..9be8e8f2 100644 --- a/doc/installing.rst +++ b/doc/installing.rst @@ -6,9 +6,10 @@ Install xarray-simlab Required dependencies --------------------- -- Python 3.4 or later. +- Python 3.5 or later. +- `attrs `__ (18.1.0 or later) - `numpy `__ -- `xarray `__ (0.8.0 or later) +- `xarray `__ (0.10.0 or later) Optional dependencies --------------------- @@ -49,12 +50,12 @@ To install xarray-simlab from source, be sure you have the required dependencies (numpy and xarray) installed first. You might consider using conda_ to install them:: - $ conda install xarray numpy pip -c conda-forge + $ conda install attrs xarray numpy pip -c conda-forge A good practice (especially for development purpose) is to install the packages in a separate environment, e.g. using conda:: - $ conda create -n simlab_py36 python=3.6 xarray numpy pip -c conda-forge + $ conda create -n simlab_py36 python=3.6 attrs xarray numpy pip -c conda-forge $ source activate simlab_py36 Then you can clone the xarray-simlab git repository and install it diff --git a/doc/run_model.rst b/doc/run_model.rst index 9f6bb3b7..05a3e602 100644 --- a/doc/run_model.rst +++ b/doc/run_model.rst @@ -20,7 +20,7 @@ The following imports are necessary for the examples below. .. ipython:: python - import xsimlab + import xsimlab as xs import matplotlib.pyplot as plt .. note:: @@ -45,16 +45,16 @@ create a new setup in a very declarative way: .. ipython:: python - in_ds = xsimlab.create_setup( + in_ds = xs.create_setup( model=model2, clocks={'time': {'start': 0, 'end': 1, 'step': 0.01}, - 'stime': {'data': [0, 0.5, 1]}}, + 'otime': {'data': [0, 0.5, 1]}}, master_clock='time', input_vars={'grid': {'length': 1.5, 'spacing': 0.01}, 'advect': {'v': 1.}, 'init': {'loc': 0.3, 'scale': 0.1}}, - snapshot_vars={None: {'grid': 'x'}, - 'stime': {'profile': 'u'}} + output_vars={None: {'grid': 'x'}, + 'otime': {'profile': 'u'}} ) A setup consists in: @@ -71,7 +71,7 @@ A setup consists in: (``None``). In the example above, we set ``time`` as the master clock dimension -and ``stime`` as another dimension for taking snapshots of :math:`u` +and ``otime`` as another dimension for taking snapshots of :math:`u` along the grid at three given times of the simulation (beginning, middle and end). The time-independent x-coordinate values of the grid will be saved as well. @@ -94,24 +94,21 @@ variables, e.g., Run a simulation ---------------- -A simple call to :meth:`.xsimlab.run` from the input dataset created -above is needed to perform the simulation. It returns a new dataset: +A new simulation is run by simply calling the :meth:`.xsimlab.run` +method from the input dataset created above. It returns a new dataset: .. ipython:: python out_ds = in_ds.xsimlab.run(model=model2) The returned dataset contains all the variables of the input -dataset. It also contains snapshots values as new data variables, -e.g., ``grid__x`` and ``profile__u`` in this example: +dataset. It also contains simulation outputs as new or updated data +variables, e.g., ``grid__x`` and ``profile__u`` in this example: .. ipython:: python out_ds -Note that in other cases snapshots may also result in updated data -variables with an additional time dimension. - Post-processing and plotting ---------------------------- @@ -137,8 +134,8 @@ e.g., for plotting snapshots: def plot_u(ds): fig, axes = plt.subplots(ncols=3, figsize=(10, 3)) - for t, ax in zip(ds.stime, axes): - ds.profile__u.sel(stime=t).plot(ax=ax) + for t, ax in zip(ds.otime, axes): + ds.profile__u.sel(otime=t).plot(ax=ax) fig.tight_layout() return fig @@ -159,7 +156,7 @@ update only the value of velocity, thanks to .. ipython:: python - in_vars = {'advect': {'v': 0.5}} + in_vars = {('advect', 'v'): 0.5} with model2: out_ds2 = (in_ds.xsimlab.update_vars(input_vars=in_vars) .xsimlab.run() @@ -167,7 +164,7 @@ update only the value of velocity, thanks to .. note:: - For convenience, we may use a Model instance in a context instead + For convenience, a Model instance may be used in a context instead of providing it repeatedly as an argument of xarray-simlab's functions or methods in which it is required. @@ -185,13 +182,13 @@ Update time dimensions :meth:`.xsimlab.update_clocks` allows to only update the time dimensions and/or their coordinates. Here below we set other values -for the ``stime`` coordinate (which serves to take snapshots of +for the ``otime`` coordinate (which serves to take snapshots of :math:`u`): .. ipython:: python clocks = {'time': {'data': in_ds.time}, - 'stime': {'data': [0, 0.25, 0.5]}} + 'otime': {'data': [0, 0.25, 0.5]}} with model2: out_ds3 = (in_ds.xsimlab.update_clocks(clocks=clocks, master_clock='time') @@ -226,8 +223,8 @@ flat initial profile for :math:`u`) instead of ``model2`` : Time-varying input values ------------------------- -All model inputs accept as values arrays which have a dimension that -corresponds to the master clock. +All model inputs accept arrays which have a dimension that corresponds +to the master clock. The example below is based on the last example above, but instead of being fixed, the flux of :math:`u` at the source point decreases over diff --git a/doc/scripts/advection_model.py b/doc/scripts/advection_model.py index f03d81e2..4547c663 100644 --- a/doc/scripts/advection_model.py +++ b/doc/scripts/advection_model.py @@ -1,158 +1,144 @@ import numpy as np -from xsimlab import Process, FloatVariable +import xsimlab as xs -class AdvectionLax1D(Process): +@xs.process +class AdvectionLax1D(object): """Wrap 1-dimensional advection in a single Process.""" - spacing = FloatVariable((), description='grid spacing') - length = FloatVariable((), description='grid total length') - x = FloatVariable('x', provided=True) + spacing = xs.variable(description='grid spacing') + length = xs.variable(description='grid total length') + x = xs.variable(dims='x', intent='out') - v = FloatVariable([(), 'x'], description='velocity') + v = xs.variable(dims=[(), 'x'], description='velocity') - loc = FloatVariable((), description='location of initial profile') - scale = FloatVariable((), description='scale of initial profile') - u = FloatVariable('x', description='quantity u', - attrs={'units': 'm'}, provided=True) + loc = xs.variable(description='location of initial profile') + scale = xs.variable(description='scale of initial profile') + u = xs.variable(dims='x', intent='out', description='quantity u', + attrs={'units': 'm'}) def initialize(self): - self.x.value = np.arange(0, self.length.value, self.spacing.value) - self.u.state = np.exp(-1 / self.scale.value**2 * - (self.x.value - self.loc.value)**2) + self.x = np.arange(0, self.length, self.spacing) + self.u = np.exp(-1 / self.scale**2 * (self.x - self.loc)**2) def run_step(self, dt): - factor = (self.v.value * dt) / (2 * self.spacing.value) - u_left = np.roll(self.u.state, 1) - u_right = np.roll(self.u.state, -1) + factor = (self.v * dt) / (2 * self.spacing) + u_left = np.roll(self.u, 1) + u_right = np.roll(self.u, -1) self.u1 = 0.5 * (u_right + u_left) - factor * (u_right - u_left) def finalize_step(self): - self.u.state = self.u1 + self.u = self.u1 -from xsimlab import Model +model1 = xs.Model({'advect': AdvectionLax1D}) -model1 = Model({'advect': AdvectionLax1D}) - - -class UniformGrid1D(Process): +@xs.process +class UniformGrid1D(object): """Create a 1-dimensional, equally spaced grid.""" - spacing = FloatVariable((), description='uniform spacing') - length = FloatVariable((), description='total length') - x = FloatVariable('x', provided=True) - - class Meta: - time_dependent = False + spacing = xs.variable(description='uniform spacing') + length = xs.variable(description='total length') + x = xs.variable(dims='x', intent='out') def initialize(self): - self.x.value = np.arange(0, self.length.value, self.spacing.value) - - -from xsimlab import VariableGroup + self.x = np.arange(0, self.length, self.spacing) -class ProfileU(Process): +@xs.process +class ProfileU(object): """Compute the evolution of the profile of quantity `u`.""" - u_vars = VariableGroup('u_vars') - u = FloatVariable('x', description='quantity u', - attrs={'units': 'm'}) + u_vars = xs.group('u_vars') + u = xs.variable(dims='x', intent='inout', description='quantity u', + attrs={'units': 'm'}) def run_step(self, *args): - self.u.change = sum((var.change for var in self.u_vars)) + self._delta_u = sum((v for v in self.u_vars)) def finalize_step(self): - self.u.state += self.u.change + self.u += self._delta_u -from xsimlab import ForeignVariable - - -class AdvectionLax(Process): +@xs.process +class AdvectionLax(object): """Advection using finite difference (Lax method) on a fixed grid with periodic boundary conditions. """ - v = FloatVariable([(), 'x'], description='velocity') - grid_spacing = ForeignVariable(UniformGrid1D, 'spacing') - u = ForeignVariable(ProfileU, 'u') - u_advected = FloatVariable('x', provided=True, group='u_vars') + v = xs.variable(dims=[(), 'x'], description='velocity') + grid_spacing = xs.foreign(UniformGrid1D, 'spacing') + u = xs.foreign(ProfileU, 'u') + u_advected = xs.variable(dims='x', intent='out', group='u_vars') def run_step(self, dt): - factor = self.v.value / (2 * self.grid_spacing.value) + factor = self.v / (2 * self.grid_spacing) - u_left = np.roll(self.u.state, 1) - u_right = np.roll(self.u.state, -1) + u_left = np.roll(self.u, 1) + u_right = np.roll(self.u, -1) u_1 = 0.5 * (u_right + u_left) - factor * dt * (u_right - u_left) - self.u_advected.change = u_1 - self.u.state + self.u_advected = u_1 - self.u -class InitUGauss(Process): - """Initialize `u` profile using a gaussian pulse.""" +@xs.process +class InitUGauss(object): + """Initialize `u` profile using a Gaussian pulse.""" - loc = FloatVariable((), description='location of initial pulse') - scale = FloatVariable((), description='scale of initial pulse') - x = ForeignVariable(UniformGrid1D, 'x') - u = ForeignVariable(ProfileU, 'u', provided=True) - - class Meta: - time_dependent = False + loc = xs.variable(description='location of initial pulse') + scale = xs.variable(description='scale of initial pulse') + x = xs.foreign(UniformGrid1D, 'x') + u = xs.foreign(ProfileU, 'u', intent='out') def initialize(self): - self.u.state = np.exp( - -1 / self.scale.value**2 * (self.x.value - self.loc.value)**2 - ) + self.u = np.exp(-1 / self.scale**2 * (self.x - self.loc)**2) -model2 = Model({'grid': UniformGrid1D, - 'profile': ProfileU, - 'init': InitUGauss, - 'advect': AdvectionLax}) +model2 = xs.Model({'grid': UniformGrid1D, + 'profile': ProfileU, + 'init': InitUGauss, + 'advect': AdvectionLax}) -class SourcePoint(Process): +@xs.process +class SourcePoint(object): """Source point for quantity `u`. The location of the source point is adjusted to coincide with the nearest node the grid. """ - loc = FloatVariable((), description='source location') - flux = FloatVariable((), description='source flux') - x = ForeignVariable(UniformGrid1D, 'x') - u_source = FloatVariable('x', provided=True, group='u_vars') + loc = xs.variable(description='source location') + flux = xs.variable(description='source flux') + x = xs.foreign(UniformGrid1D, 'x') + u_source = xs.variable(dims='x', intent='out', group='u_vars') @property def nearest_node(self): - idx = np.abs(self.x.value - self.loc.value).argmin() + idx = np.abs(self.x - self.loc).argmin() return idx @property def source_rate(self): - src_array = np.zeros_like(self.x.value) - src_array[self.nearest_node] = self.flux.value + src_array = np.zeros_like(self.x) + src_array[self.nearest_node] = self.flux return src_array def run_step(self, dt): - self.u_source.change = self.source_rate * dt + self.u_source = self.source_rate * dt -class InitUFlat(Process): +@xs.process +class InitUFlat(object): """Flat initial profile of `u`.""" - x = ForeignVariable(UniformGrid1D, 'x') - u = ForeignVariable(ProfileU, 'u', provided=True) - - class Meta: - time_dependent = False + x = xs.foreign(UniformGrid1D, 'x') + u = xs.foreign(ProfileU, 'u', intent='out') def initialize(self): - self.u.state = np.zeros_like(self.x.value) + self.u = np.zeros_like(self.x) model3 = model2.update_processes({'source': SourcePoint, diff --git a/doc/whats_new.rst b/doc/whats_new.rst index f31e2cd9..5a86da75 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -3,6 +3,128 @@ Release Notes ============= +v0.2.0 (Unreleased) +------------------- + +Highlights +~~~~~~~~~~ + +This release includes a major refactoring of both the internals and +the API on how processes and variables are defined and depends on +each other in a model. xarray-simlab now uses and extends +attrs_ (:issue:`33`). + +Also, Python 3.4 support has been dropped. It may still work with that +version but it is not actively tested anymore and it is not packaged +with conda. + +.. _attrs: http://www.attrs.org + +Breaking changes +~~~~~~~~~~~~~~~~ + +As xarray-simlab is still at an early development stage and hasn't +been adopted "in production" yet (to our knowledge), we haven't gone +through any depreciation cycle, which by the way would have been +almost impossible for such a major refactoring. The following breaking +changes are effective now! + +- ``Variable``, ``ForeignVariable`` and ``VariableGroup`` classes have + been replaced by ``variable``, ``foreign`` and ``group`` factory + functions (wrappers around ``attr.ib``), respectively. +- ``VariableList`` has been removed and has not been replaced by + anything equivalent. +- ``DiagnosticVariable`` has been replaced by ``on_demand`` and the + ``diagnostic`` decorator has been replaced by the variable's + ``compute`` decorator. +- The ``provided`` (``bool``) argument (variable constructors) has + been replaced by ``intent`` (``{'in', 'out', 'inout'}``). +- The ``allowed_dims`` argument has been renamed to ``dims`` and is + now optional (a scalar value is expected by default). +- The ``validators`` argument has been renamed to ``validator`` to be + consistent with ``attr.ib``. +- The ``optional`` argument has been removed. Variables that don't + require an input value may be defined using a special validator + function (see ``attrs`` documentation). +- Variable values are not anymore accessed using three different + properties ``state``, ``rate`` and ``change`` (e.g., + ``self.foo.state``). Instead, all variables accept a unique value, + which one can get/set by simply using the variable name (e.g., + ``self.foo``). Now multiple variables have to be declared for + holding different values. + +- Process classes are now defined using the ``process`` decorator + instead of inheriting from a ``Process`` base class. +- It is not needed anymore to explicitly define whether or not a + process is time dependent (it is now deducted from the methods + implemented in the process class). +- Using ``class Meta`` inside a process class to define some metadata + is not used anymore. + +- ``Model.input_vars`` now returns a list of ``(process_name, + variable_name)`` tuples instead of a dict of dicts. + ``Model.input_vars_dict`` has been added for convenience + (i.e., to get input variables grouped by process as a dictionary). +- ``Model.is_input`` has been removed. Use ``Model.input_vars`` + instead to check if a variable is a model input. + +- ``__repr__`` has slightly changed for variables, processes and + models. Process classes don't have an ``.info()`` method anymore, + which has been replaced by the ``process_info()`` top-level + function. Another helper function ``variable_info()`` has been + added. + +- In ``Model.visualize()`` and ``xsimlab.dot.dot_graph()``, + ``show_variables=True`` now shows all model variables including + inputs. Items of group variables are not shown anymore as nodes. +- ``Model.visualize()`` and ``xsimlab.dot.dot_graph()`` now only + accept tuples for ``show_only_variable``. + +- For simplicity, ``Dataset.xsimlab.snapshot_vars`` has been renamed to + ``output_vars``. The corresponding arguments in ``create_setup`` and + ``Dataset.xsimlab.update_vars`` have been renamed accordingly. +- Values for all model inputs must be provided when creating or + updating a setup using ``create_setup`` or + ``Dataset.xsimlab.update_vars``. this is a regression that will be + fixed in the next releases. + +Enhancements +~~~~~~~~~~~~ + +- The major refactoring in this release should reduce the overhead + caused by the indirect access to variable values in process objects. +- Another benefit of the refactoring is that a process-decorated class + may now inherit from other classes (possibly also + process-decorated), which allows more flexibility in model + customization. +- By creating read-only properties in specific cases (i.e., when + ``intent='in'``), the ``process`` decorator applied on a class adds + some safeguards to prevent setting variable values where it is not + intended. +- Some more sanity checks have been added when creating process + classes. +- Simulation active and output data r/w access has been refactored + internally so that it should be easy to later support alternative + data storage backends (e.g., on-disk, distributed). +- Added ``Model.dependent_processes`` property (so far this was not + in public API). +- Added ``Model.all_vars`` and ``Model.all_vars_dict`` properties that + are similar to ``Model.input_vars`` and ``Model.input_vars_dict`` + but return all variable names in the model. +- ``input_vars`` and ``output_vars`` arguments of ``create_setup`` and + ``Dataset.xsimlab.update_vars`` now accepts different formats. + +Regressions (will be fixed in future releases) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Although it is possible to set validators, converters and/or default + values for variables (this is directly supported by ``attrs``), these + are not handled by xarray-simlab yet. +- Variables don't accept anymore a dimension that corresponds to their + own name. This may be useful, e.g., for sensitivity analysis, but as + the latter is not implemented yet this feature has been removed and + will be added back in a next release. + v0.1.1 (20 November 2017) ------------------------- diff --git a/setup.py b/setup.py index 7e8cbf60..4095835d 100755 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ packages=find_packages(), long_description=(open('README.rst').read() if exists('README.rst') else ''), - python_requires='>=3.4', - install_requires=['numpy', 'xarray >= 0.8.0'], + python_requires='>=3.5', + install_requires=['attrs >= 18.1.0', 'numpy', 'xarray >= 0.10.0'], tests_require=['pytest >= 3.3.0'], zip_safe=False) diff --git a/xsimlab/__init__.py b/xsimlab/__init__.py index e04283cc..ab453f7e 100644 --- a/xsimlab/__init__.py +++ b/xsimlab/__init__.py @@ -3,10 +3,8 @@ """ from .xr_accessor import SimlabAccessor, create_setup -from .variable.base import (Variable, ForeignVariable, VariableList, - VariableGroup, diagnostic, ValidationError) -from .variable.custom import NumberVariable, FloatVariable, IntegerVariable -from .process import Process +from .variable import variable, on_demand, foreign, group +from .process import filter_variables, process, process_info, variable_info from .model import Model from ._version import get_versions diff --git a/xsimlab/dot.py b/xsimlab/dot.py index 44ec6cf3..4c5a1dd0 100644 --- a/xsimlab/dot.py +++ b/xsimlab/dot.py @@ -9,14 +9,11 @@ http://dask.pydata.org """ -from __future__ import absolute_import, division, print_function - import os from functools import partial -from .utils import import_required -from .variable.base import (AbstractVariable, ForeignVariable, - DiagnosticVariable, VariableGroup) +from .utils import variables_dict, import_required, maybe_to_list +from .variable import VarIntent, VarType graphviz = import_required("graphviz", "Drawing dask graphs requires the " @@ -35,92 +32,100 @@ VAR_EDGE_ATTRS = {'arrowhead': 'none', 'color': '#555555'} -def hash_variable(var): - return str(hash(var)) +def _hash_variable(var): + # issue with variables with the same name declared in different processes + # return str(hash(var)) + return str(id(var)) -def _add_processes(g, model): - seen = set() +def _get_target_keys(p_obj, var_name): + return ( + maybe_to_list(p_obj.__xsimlab_store_keys__.get(var_name, [])) + + maybe_to_list(p_obj.__xsimlab_od_keys__.get(var_name, [])) + ) - for proc_name, proc in model._processes.items(): - label = proc_name - if proc_name not in seen: - seen.add(proc_name) - g.node(proc_name, label=label, **PROC_NODE_ATTRS) - for dep_proc_name in model._dep_processes[proc_name]: - # check and add node shouldn't be needed here, but not sure - #if dep_proc_name not in seen: - # seen.add(dep_proc_name) - # dep_label = dep_proc_name - # g.node(dep_proc_name, label=dep_label, **PROC_NODE_ATTRS) - g.edge(dep_proc_name, proc_name, **PROC_EDGE_ATTRS) +class _GraphBuilder(object): + def __init__(self, model, graph_attr): + self.model = model + self.g = graphviz.Digraph(graph_attr=graph_attr) -def _add_var(g, var, label, link_2_node, is_input=False): - node_attrs = VAR_NODE_ATTRS.copy() - edge_attrs = VAR_EDGE_ATTRS.copy() - var_key = hash_variable(var) + def add_processes(self): + seen = set() - if is_input: - node_attrs = INPUT_NODE_ATTRS.copy() - edge_attrs = INPUT_EDGE_ATTRS.copy() - elif isinstance(var, DiagnosticVariable): - node_attrs['style'] = 'diagonals' - elif isinstance(var, ForeignVariable): - node_attrs['style'] = 'dashed' - edge_attrs['style'] = 'dashed' - elif isinstance(var, (tuple, VariableGroup)): - node_attrs['shape'] = 'box3d' + for p_name, p_obj in self.model._processes.items(): + if p_name not in seen: + seen.add(p_name) + self.g.node(p_name, label=p_name, **PROC_NODE_ATTRS) - if not isinstance(var, tuple) and var.provided: - edge_attrs.update({'arrowhead': 'empty'}) - edge_ends = link_2_node, var_key - else: - edge_ends = var_key, link_2_node + for dep_p_name in self.model.dependent_processes[p_name]: + self.g.edge(dep_p_name, p_name, **PROC_EDGE_ATTRS) + + def _add_var(self, var, p_name): + if (p_name, var.name) in self.model._input_vars: + node_attrs = INPUT_NODE_ATTRS.copy() + edge_attrs = INPUT_EDGE_ATTRS.copy() + else: + node_attrs = VAR_NODE_ATTRS.copy() + edge_attrs = VAR_EDGE_ATTRS.copy() - g.node(var_key, label=label, **node_attrs) - g.edge(*edge_ends, weight='200', **edge_attrs) + var_key = _hash_variable(var) + var_intent = var.metadata['intent'] + var_type = var.metadata['var_type'] + if var_type == VarType.ON_DEMAND: + node_attrs['style'] = 'diagonals' -def _add_inputs(g, model): - for proc_name, variables in model._input_vars.items(): - for var_name, var in variables.items(): - _add_var(g, var, var_name, proc_name, is_input=True) + elif var_type == VarType.FOREIGN: + node_attrs['style'] = 'dashed' + edge_attrs['style'] = 'dashed' + + elif var_type == VarType.GROUP: + node_attrs['shape'] = 'box3d' + + if var_intent == VarIntent.OUT: + edge_attrs.update({'arrowhead': 'empty'}) + edge_ends = p_name, var_key + else: + edge_ends = var_key, p_name + self.g.node(var_key, label=var.name, **node_attrs) + self.g.edge(*edge_ends, weight='200', **edge_attrs) -def _add_variables(g, model): - for proc_name, variables in model._processes.items(): - for var_name, var in variables.items(): - if model.is_input(var): - continue - _add_var(g, var, var_name, proc_name) + def add_inputs(self): + for p_name, var_name in self.model._input_vars: + p_cls = type(self.model[p_name]) + var = variables_dict(p_cls)[var_name] - if isinstance(var, (tuple, VariableGroup)): - for v in var: - _add_var(g, v, '\', hash_variable(var)) + self._add_var(var, p_name) + def add_variables(self): + for p_name, p_obj in self.model._processes.items(): + p_cls = type(p_obj) -def _add_var_and_foreign_vars(g, model, proc_name, var_name): - variable = model[proc_name][var_name] + for var_name, var in variables_dict(p_cls).items(): + self._add_var(var, p_name) - if isinstance(variable, ForeignVariable): - variable = variable.ref_var + def add_var_and_targets(self, p_name, var_name): + this_p_name = p_name + this_var_name = var_name - for p_name, variables in model._processes.items(): - for v_name, var in variables.items(): - if model.is_input(var): - is_input = True - else: - is_input = False + this_p_obj = self.model._processes[this_p_name] + this_target_keys = _get_target_keys(this_p_obj, this_var_name) - if var is variable or getattr(var, 'ref_var', None) is variable: - _add_var(g, var, v_name, p_name, is_input=is_input) - elif isinstance(var, (tuple, VariableGroup)): - for v in var: - if v is variable or getattr(v, 'ref_var', None) is variable: - _add_var(g, var, v_name, p_name, is_input=is_input) - _add_var(g, v, '\', hash_variable(var)) + for p_name, p_obj in self.model._processes.items(): + p_cls = type(p_obj) + + for var_name, var in variables_dict(p_cls).items(): + target_keys = _get_target_keys(p_obj, var_name) + + if ((p_name, var_name) == (this_p_name, this_var_name) or + len(set(target_keys) & set(this_target_keys))): + self._add_var(var, p_name) + + def get_graph(self): + return self.g def to_graphviz(model, rankdir='LR', show_only_variable=None, @@ -129,25 +134,22 @@ def to_graphviz(model, rankdir='LR', show_only_variable=None, graph_attr = graph_attr or {} graph_attr['rankdir'] = rankdir graph_attr.update(kwargs) - g = graphviz.Digraph(graph_attr=graph_attr) - _add_processes(g, model) + builder = _GraphBuilder(model, graph_attr) + + builder.add_processes() if show_only_variable is not None: - if isinstance(show_only_variable, AbstractVariable): - proc_name, var_name = model._get_proc_var_name(show_only_variable) - else: - proc_name, var_name = show_only_variable - _add_var_and_foreign_vars(g, model, proc_name, var_name) + p_name, var_name = show_only_variable + builder.add_var_and_targets(p_name, var_name) - else: - if show_inputs: - _add_inputs(g, model) + elif show_variables: + builder.add_variables() - if show_variables: - _add_variables(g, model) + elif show_inputs: + builder.add_inputs() - return g + return builder.get_graph() IPYTHON_IMAGE_FORMATS = frozenset(['jpeg', 'png']) @@ -188,27 +190,25 @@ def dot_graph(model, filename=None, format=None, show_only_variable=None, show_inputs=False, show_variables=False, **kwargs): """ Render a model as a graph using dot. - If `filename` is not None, write a file to disk with that name in the - format specified by `format`. `filename` should not include an extension. Parameters ---------- model : object The Model instance to display. filename : str or None, optional - The name (without an extension) of the file to write to disk. If + The name (without an extension) of the file to write to disk. If `filename` is None (default), no file will be written, and we communicate with dot using only pipes. format : {'png', 'pdf', 'dot', 'svg', 'jpeg', 'jpg'}, optional Format in which to write output file. Default is 'png'. - show_only_variable : object or tuple, optional - Show only a variable (and all other linked variables) given either - as a Variable object or a tuple corresponding to process name and - variable name. Deactivated by default. + show_only_variable : tuple, optional + Show only a variable (and all other variables sharing the + same value) given as a tuple ``(process_name, variable_name)``. + Deactivated by default. show_inputs : bool, optional If True, show all input variables in the graph (default: False). Ignored if `show_only_variable` is not None. - show_variabless : bool, optional + show_variables : bool, optional If True, show also the other variables (default: False). Ignored if `show_only_variable` is not None. **kwargs @@ -216,7 +216,8 @@ def dot_graph(model, filename=None, format=None, show_only_variable=None, Returns ------- - result : None or IPython.display.Image or IPython.display.SVG (See below.) + result : None or IPython.display.Image or IPython.display.SVG + (See below.) Notes ----- diff --git a/xsimlab/drivers.py b/xsimlab/drivers.py new file mode 100644 index 00000000..6d6fe721 --- /dev/null +++ b/xsimlab/drivers.py @@ -0,0 +1,266 @@ +import copy + +import numpy as np +import xarray as xr + +from .utils import variables_dict + + +class BaseSimulationDriver(object): + """Base class that provides a minimal interface for creating + simulation drivers (should be inherited). + + It also implements methods for binding a simulation data store to + a model and for updating both this active data store and the + simulation output store. + + """ + def __init__(self, model, store, output_store): + self.model = model + self.store = store + self.output_store = output_store + + self._bind_store_to_model() + + def _bind_store_to_model(self): + """Bind the simulation active data store to each process in the + model. + """ + for p_obj in self.model.values(): + p_obj.__xsimlab_store__ = self.store + + def update_store(self, input_vars): + """Update the simulation active data store with input variable + values. + + ``input_vars`` is a dictionary where keys are store keys, i.e., + ``(process_name, var_name)`` tuples, and values are the input + values to set in the store. + + Values are first copied from ``input_vars`` before being put in + the store to prevent weird behavior (as model processes might + update in-place the values in the store). + + Entries of ``input_vars`` that doesn't correspond to model + inputs are silently ignored. + + """ + for key in self.model.input_vars: + value = input_vars.get(key) + + if value is not None: + self.store[key] = copy.copy(value) + + def update_output_store(self, output_var_keys): + """Update the simulation output store (i.e., append new values to the + store) from snapshots of variables given in ``output_var_keys`` list. + """ + for key in output_var_keys: + p_name, var_name = key + p_obj = self.model._processes[p_name] + value = getattr(p_obj, var_name) + + self.output_store.append(key, value) + + def run_model(self): + """Main function of the driver used to run a simulation (must be + implemented in sub-classes). + """ + raise NotImplementedError() + + +def _get_dims_from_variable(array, var, clock): + """Given an array with numpy compatible interface and a + (xarray-simlab) variable, return dimension labels for the + array. + + """ + ndim = array.ndim + if clock is not None: + ndim -= 1 # ignore clock dimension + + for dims in var.metadata['dims']: + if len(dims) == ndim: + return dims + + return tuple() + + +class XarraySimulationDriver(BaseSimulationDriver): + """Simulation driver using xarray.Dataset objects as I/O. + + - Perform some sanity checks on the content of the given input Dataset. + - Set model inputs from data variables or coordinates in the input Dataset. + - Save model outputs for given model variables, defined in specific + attributes of the input Dataset, on time frequencies given by clocks + defined as coordinates in the input Dataset. + - Get simulation results as a new xarray.Dataset object. + + """ + def __init__(self, dataset, model, store, output_store): + self.dataset = dataset + self.model = model + + super(XarraySimulationDriver, self).__init__( + model, store, output_store) + + self.master_clock_dim = dataset.xsimlab.master_clock_dim + if self.master_clock_dim is None: + raise ValueError("Missing master clock dimension / coordinate") + + self._check_missing_model_inputs() + + self.output_vars = dataset.xsimlab.output_vars + self.output_save_steps = self._get_output_save_steps() + + def _check_missing_model_inputs(self): + """Check if all model inputs have their corresponding variables + in the input Dataset. + """ + missing_xr_vars = [] + + for p_name, var_name in self.model.input_vars: + xr_var_name = p_name + '__' + var_name + + if xr_var_name not in self.dataset: + missing_xr_vars.append(xr_var_name) + + if missing_xr_vars: + raise KeyError("Missing variables %s in Dataset" + % missing_xr_vars) + + def _get_output_save_steps(self): + """Returns a dictionary where keys are names of clock coordinates and + values are numpy boolean arrays that specify whether or not to + save outputs at every step of a simulation. + """ + save_steps = {} + + for clock in self.output_vars: + if clock is None: + continue + + elif clock == self.master_clock_dim: + save_steps[clock] = np.ones_like( + self.dataset[self.master_clock_dim].values, dtype=bool) + + else: + save_steps[clock] = np.in1d( + self.dataset[self.master_clock_dim].values, + self.dataset[clock].values) + + return save_steps + + def _get_time_steps(self): + """Return a xarray.DataArray of duration between two + consecutive time steps.""" + mclock = self.dataset[self.master_clock_dim] + return mclock.diff(self.master_clock_dim).values + + def _split_clock_inputs(self): + """Return two datasets with time-independent and time-dependent + inputs.""" + ds_in = self.dataset.filter( + lambda var: self.master_clock_dim not in var.dims) + ds_in_clock = self.dataset.filter( + lambda var: self.master_clock_dim in var.dims) + + return ds_in, ds_in_clock + + def _set_input_vars(self, dataset): + for p_name, var_name in self.model.input_vars: + xr_var_name = p_name + '__' + var_name + xr_var = dataset.get(xr_var_name) + + # TODO: convert 0-d arrays to scalars + + if xr_var is not None: + self.store[(p_name, var_name)] = xr_var.data.copy() + + def _maybe_save_output_vars(self, istep): + # TODO: optimize this for performance + for clock, var_keys in self.output_vars.items(): + save_output = ( + clock is None and istep == -1 or + clock is not None and self.output_save_steps[clock][istep] + ) + + if save_output: + self.update_output_store(var_keys) + + def _to_xr_variable(self, key, clock): + """Convert an output variable to a xarray.Variable object.""" + p_name, var_name = key + p_obj = self.model[p_name] + var = variables_dict(type(p_obj))[var_name] + + data = self.output_store[key] + if clock is None: + data = data[0] + + dims = _get_dims_from_variable(data, var, clock) + if clock is not None: + dims = (clock,) + dims + + attrs = var.metadata['attrs'].copy() + if var.metadata['description']: + attrs['description'] = var.metadata['description'] + + return xr.Variable(dims, data, attrs=attrs) + + def _get_output_dataset(self): + """Return a new dataset as a copy of the input dataset updated with + output variables. + """ + from .xr_accessor import SimlabAccessor + + xr_vars = {} + + for clock, vars in self.output_vars.items(): + for key in vars: + var_name = '__'.join(key) + xr_vars[var_name] = self._to_xr_variable(key, clock) + + out_ds = self.dataset.update(xr_vars, inplace=False) + + # remove output_vars attributes in output dataset + for clock in self.output_vars: + if clock is None: + attrs = out_ds.attrs + else: + attrs = out_ds[clock].attrs + attrs.pop(SimlabAccessor._output_vars_key) + + return out_ds + + def run_model(self): + """Run the model and return a new Dataset with all the simulation + inputs and outputs. + + - Set model inputs from the input Dataset (update + time-dependent model inputs -- if any -- before each time step). + - Save outputs (snapshots) between the 'run_step' and the + 'finalize_step' stages or at the end of the simulation. + + """ + ds_in, ds_in_clock = self._split_clock_inputs() + has_clock_inputs = bool(ds_in_clock.data_vars) + + dt_array = self._get_time_steps() + + self._set_input_vars(ds_in) + self.model.initialize() + + for istep, dt in enumerate(dt_array): + if has_clock_inputs: + ds_in_step = ds_in_clock.isel(**{self.master_clock_dim: istep}) + self._set_input_vars(ds_in_step) + + self.model.run_step(dt) + self._maybe_save_output_vars(istep) + self.model.finalize_step() + + self._maybe_save_output_vars(-1) + self.model.finalize() + + return self._get_output_dataset() diff --git a/xsimlab/formatting.py b/xsimlab/formatting.py index 028be365..9e0daf18 100644 --- a/xsimlab/formatting.py +++ b/xsimlab/formatting.py @@ -1,4 +1,8 @@ """Formatting utils and functions.""" +import textwrap + +from .utils import variables_dict, has_method +from .variable import VarIntent, VarType def _calculate_col_width(col_items): @@ -30,51 +34,141 @@ def wrap_indent(text, start='', length=None): return start + indent.join(x for x in text.splitlines()) -def _summarize_var(name, var, col_width, marker=' '): +def _summarize_var(var, process, col_width): max_line_length = 70 - first_col = pretty_print(" %s %s" % (marker, name), col_width) + var_name = var.name + var_type = var.metadata['var_type'] + var_intent = var.metadata['intent'] + + if var_intent == VarIntent.IN: + link_symbol = '<---' + var_intent_str = ' [in]' + elif var_intent == VarIntent.OUT: + link_symbol = '--->' + var_intent_str = ' [out]' + else: + var_intent_str = '[inout]' + + if var_type == VarType.GROUP: + var_info = '{} group {!r}'.format(link_symbol, var.metadata['group']) + + elif var_type == VarType.FOREIGN: + key = process.__xsimlab_store_keys__.get(var_name) + if key is None: + key = process.__xsimlab_od_keys__.get(var_name) + if key is None: + key = (var.metadata['other_process_cls'].__name__, + var.metadata['var_name']) + + var_info = '{} {}.{}'.format(link_symbol, *key) - if isinstance(var, tuple): - var_repr = "VariableList" else: - var_repr = str(var).strip('<>').replace('xsimlab.', '') - var_repr = maybe_truncate(var_repr, max_line_length - col_width) + var_dims = " or ".join([str(d) for d in var.metadata['dims']]) + + if var_dims != "()": + var_info = " ".join([var_dims, var.metadata['description']]) + else: + var_info = var.metadata['description'] - return first_col + var_repr + left_col = pretty_print(" {}".format(var.name), col_width) + right_col = var_intent_str + if var_info: + right_col += maybe_truncate(' ' + var_info, + max_line_length - col_width - 7) -def _summarize_var_list(name, var, col_width): - vars_lines = '\n'.join([_summarize_var('- ', v, col_width) - for v in var]) - return '\n'.join([_summarize_var(name, var, col_width), vars_lines]) + return left_col + right_col -def process_info(cls_or_obj): - col_width = _calculate_col_width(cls_or_obj._variables) +def var_details(var): max_line_length = 70 - var_block = "Variables:\n" + var_metadata = var.metadata.copy() - lines = [] - for name, var in cls_or_obj._variables.items(): - if isinstance(var, (tuple, list)): - line = _summarize_var_list(name, var, col_width) - else: - marker = '*' if var.provided else ' ' - line = _summarize_var(name, var, col_width, - marker=marker) - lines.append(line) + description = textwrap.fill(var_metadata.pop('description').capitalize(), + width=max_line_length) + + detail_items = [('type', var_metadata.pop('var_type').value), + ('intent', var_metadata.pop('intent').value)] + detail_items += list(var_metadata.items()) + + details = "\n".join(["- {} : {}".format(k, v) for k, v in detail_items]) + + return description + "\n\n" + details + '\n' + + +def repr_process(process): + process_cls = type(process) + + if process.__xsimlab_name__ is not None: + process_name = '{!r}'.format(process.__xsimlab_name__) + else: + process_name = '' - if not lines: - var_block += " *empty*" + header = "<{} {} (xsimlab process)>".format(process_cls.__name__, + process_name) + + variables = variables_dict(process_cls) + + col_width = _calculate_col_width(variables) + + var_section_summary = "Variables:" + var_section_details = "\n".join( + [_summarize_var(var, process, col_width) for var in variables.values()] + ) + if not var_section_details: + var_section_details = " *empty*" + + stages_implemented = [ + " {}".format(m) + for m in ['initialize', 'run_step', 'finalize_step', 'finalize'] + if has_method(process, m) + ] + + stages_section_summary = "Simulation stages:" + if stages_implemented: + stages_section_details = "\n".join(stages_implemented) else: - var_block += '\n'.join(lines) + stages_section_details = " *no stage implemented*" + + process_repr = "\n".join([header, + var_section_summary, + var_section_details, + stages_section_summary, + stages_section_details]) + + return process_repr + '\n' + + +def repr_model(model): + n_processes = len(model) - meta_block = "Meta:\n" - meta_block += '\n'.join( - [maybe_truncate(" %s: %s" % (k, v), max_line_length) - for k, v in cls_or_obj._meta.items()] + header = ("" + .format(n_processes, len(model.input_vars))) + + if not n_processes: + return header + '\n' + + col_width = _calculate_col_width( + [var_name for _, var_name in model.input_vars] ) - return '\n'.join([var_block, meta_block]) + sections = [] + + for p_name, p_obj in model.items(): + p_section = p_name + + p_input_vars = model.input_vars_dict.get(p_name, []) + input_var_lines = [] + + for var_name in p_input_vars: + var = variables_dict(type(p_obj))[var_name] + input_var_lines.append(_summarize_var(var, p_obj, col_width)) + + if input_var_lines: + p_section += '\n' + '\n'.join(input_var_lines) + + sections.append(p_section) + + return header + '\n' + '\n'.join(sections) + '\n' diff --git a/xsimlab/model.py b/xsimlab/model.py index 9691c3ca..a43d198c 100644 --- a/xsimlab/model.py +++ b/xsimlab/model.py @@ -1,167 +1,326 @@ -from collections import OrderedDict +from collections import OrderedDict, defaultdict +from inspect import isclass -from .variable.base import (AbstractVariable, Variable, ForeignVariable, - VariableList, VariableGroup) -from .process import Process -from .utils import AttrMapping, ContextMixin -from .formatting import _calculate_col_width, pretty_print, maybe_truncate +from .variable import VarIntent, VarType +from .process import (ensure_process_decorated, filter_variables, + get_target_variable) +from .utils import AttrMapping, ContextMixin, has_method, variables_dict +from .formatting import repr_model -def _set_process_names(processes): - # type: Dict[str, Process] - """Set process names using keys of the mapping.""" - for k, p in processes.items(): - p._name = k +def _flatten_keys(key_seq): + """returns a flat list of keys, i.e., ``('foo', 'bar')`` tuples, from + a nested sequence. + """ + flat_keys = [] -def _set_group_vars(processes): - """Assign variables that belong to variable groups.""" - for proc in processes.values(): - for var in proc._variables.values(): - if isinstance(var, VariableGroup): - var._set_variables(processes) + for key in key_seq: + if not isinstance(key, tuple): + flat_keys += _flatten_keys(key) + else: + flat_keys.append(key) + return flat_keys -def _get_foreign_vars(processes): - # type: Dict[str, Process] -> Dict[str, List[ForeignVariable]] - foreign_vars = {} +class _ModelBuilder(object): + """Used to iteratively build a new model. - for proc_name, proc in processes.items(): - foreign_vars[proc_name] = [] + This builder implements the following tasks: - for var in proc._variables.values(): - if isinstance(var, (tuple, list, VariableGroup)): - foreign_vars[proc_name] += [ - v for v in var if isinstance(v, ForeignVariable) - ] - elif isinstance(var, ForeignVariable): - foreign_vars[proc_name].append(var) + - Attach the model instance to each process and assign their given + name in model. + - Define for each variable of the model its corresponding key + (in store or on-demand) + - Find variables that are model inputs + - Find process dependencies and sort processes (DAG) + - Find the processes that implement the method relative to each + step of a simulation - return foreign_vars + """ + def __init__(self, processes_cls): + self._processes_cls = processes_cls + self._processes_obj = {k: cls() for k, cls in processes_cls.items()} + self._reverse_lookup = {cls: k for k, cls in processes_cls.items()} -def _link_foreign_vars(processes): - """Assign process instances to foreign variables.""" - proc_lookup = {v.__class__: v for v in processes.values()} + self._input_vars = None - for variables in _get_foreign_vars(processes).values(): - for var in variables: - var._other_process_obj = proc_lookup[var._other_process_cls] + self._dep_processes = None + self._sorted_processes = None + # a cache for group keys + self._group_keys = {} -def _get_input_vars(processes): - # type: Dict[str, Process] -> Dict[str, Dict[str, Variable]] + def bind_processes(self, model_obj): + for p_name, p_obj in self._processes_obj.items(): + p_obj.__xsimlab_model__ = model_obj + p_obj.__xsimlab_name__ = p_name - input_vars = {} + def _get_var_key(self, p_name, var): + """Get store and/or on-demand keys for variable `var` declared in + process `p_name`. - for proc_name, proc in processes.items(): - input_vars[proc_name] = {} + Returned key(s) are either None (if no key), a tuple or a list + of tuples (for group variables). - for k, var in proc._variables.items(): - if isinstance(var, Variable) and not var.provided: - input_vars[proc_name][k] = var + A key tuple looks like ``('foo', 'bar')`` where 'foo' is the + name of any process in the model and 'bar' is the name of a + variable declared in that process. - # case of variables provided by other processes - foreign_vars = _get_foreign_vars(processes) - for variables in foreign_vars.values(): - for var in variables: - if input_vars[var.ref_process.name].get(var.var_name, False): - if var.provided: - del input_vars[var.ref_process.name][var.var_name] + """ + store_key = None + od_key = None - return {k: v for k, v in input_vars.items() if v} + var_type = var.metadata['var_type'] + if var_type == VarType.VARIABLE: + store_key = (p_name, var.name) -def _get_process_dependencies(processes): - # type: Dict[str, Process] -> Dict[str, List[Process]] + elif var_type == VarType.ON_DEMAND: + od_key = (p_name, var.name) - dep_processes = {k: set() for k in processes} - foreign_vars = _get_foreign_vars(processes) + elif var_type == VarType.FOREIGN: + target_p_cls, target_var = get_target_variable(var) + target_p_name = self._reverse_lookup.get(target_p_cls, None) - for proc_name, variables in foreign_vars.items(): - for var in variables: - if var.provided: - dep_processes[var.ref_process.name].add(proc_name) - else: - ref_var = var.ref_var - if ref_var.provided or getattr(ref_var, 'optional', False): - dep_processes[proc_name].add(var.ref_process.name) + if target_p_name is None: + raise KeyError( + "Process class '{}' missing in Model but required " + "by foreign variable '{}' declared in process '{}'" + .format(target_p_cls.__name__, var.name, p_name) + ) - return {k: list(v) for k, v in dep_processes.items()} + store_key, od_key = self._get_var_key(target_p_name, target_var) + elif var_type == VarType.GROUP: + var_group = var.metadata['group'] + store_key, od_key = self._get_group_var_keys(var_group) -def _sort_processes(dep_processes): - # type: Dict[str, List[Process]] -> List[str] - """Stack-based depth-first search traversal. + return store_key, od_key - This is based on Tarjan's method for topological sorting. + def _get_group_var_keys(self, group): + """Get from cache or find model-wise store and on-demand keys + for all variables related to a group (except group variables). - Part of the code below is copied and modified from: + """ + if group in self._group_keys: + return self._group_keys[group] - - dask 0.14.3 (Copyright (c) 2014-2015, Continuum Analytics, Inc. - and contributors) - Licensed under the BSD 3 License - http://dask.pydata.org + store_keys = [] + od_keys = [] - """ - ordered = [] - - # Nodes whose descendents have been completely explored. - # These nodes are guaranteed to not be part of a cycle. - completed = set() - - # All nodes that have been visited in the current traversal. Because - # we are doing depth-first search, going "deeper" should never result - # in visiting a node that has already been seen. The `seen` and - # `completed` sets are mutually exclusive; it is okay to visit a node - # that has already been added to `completed`. - seen = set() - - for key in dep_processes: - if key in completed: - continue - nodes = [key] - while nodes: - # Keep current node on the stack until all descendants are visited - cur = nodes[-1] - if cur in completed: - # Already fully traversed descendants of cur - nodes.pop() + filter_group = lambda var: (var.metadata.get('group') == group and + var.metadata['var_type'] != VarType.GROUP) + + for p_name, p_obj in self._processes_obj.items(): + for var in filter_variables(p_obj, func=filter_group).values(): + store_key, od_key = self._get_var_key(p_name, var) + + if store_key is not None: + store_keys.append(store_key) + if od_key is not None: + od_keys.append(od_key) + + self._group_keys[group] = store_keys, od_keys + + return store_keys, od_keys + + def set_process_keys(self): + """Find store and/or on-demand keys for all variables in a model and + store them in their respective process, i.e., the following + attributes: + + __xsimlab_store_keys__ (store keys) + __xsimlab_od_keys__ (on-demand keys) + + """ + for p_name, p_obj in self._processes_obj.items(): + for var in filter_variables(p_obj).values(): + store_key, od_key = self._get_var_key(p_name, var) + + if store_key is not None: + p_obj.__xsimlab_store_keys__[var.name] = store_key + if od_key is not None: + p_obj.__xsimlab_od_keys__[var.name] = od_key + + def get_all_variables(self): + """Get all variables in the model as a list of + ``(process_name, var_name)`` tuples. + + """ + all_keys = [] + + for p_name, p_cls in self._processes_cls.items(): + all_keys += [(p_name, var_name) + for var_name in variables_dict(p_cls)] + + return all_keys + + def get_input_variables(self): + """Get all input variables in the model as a list of + ``(process_name, var_name)`` tuples. + + Model input variables meet the following conditions: + + - model-wise (i.e., in all processes), there is no variable with + intent='out' targeting those variables (in store keys). + - although group variables always have intent='in', they are not + model inputs. + + """ + filter_in = lambda var: ( + var.metadata['var_type'] != VarType.GROUP and + var.metadata['intent'] != VarIntent.OUT + ) + filter_out = lambda var: var.metadata['intent'] == VarIntent.OUT + + in_keys = [] + out_keys = [] + + for p_name, p_obj in self._processes_obj.items(): + in_keys += [ + p_obj.__xsimlab_store_keys__.get(var.name) + for var in filter_variables(p_obj, func=filter_in).values() + ] + out_keys += [ + p_obj.__xsimlab_store_keys__.get(var.name) + for var in filter_variables(p_obj, func=filter_out).values() + ] + + self._input_vars = [k for k in set(in_keys) - set(out_keys) + if k is not None] + + return self._input_vars + + def get_process_dependencies(self): + """Return a dictionary where keys are each process of the model and + values are lists of the names of dependent processes (or empty + lists for processes that have no dependencies). + + Process 1 depends on process 2 if the later declares a + variable (resp. a foreign variable) with intent='out' that + itself (resp. its target variable) is needed in process 1. + + """ + self._dep_processes = {k: set() for k in self._processes_obj} + + d_keys = {} # all store/on-demand keys for each process + + for p_name, p_obj in self._processes_obj.items(): + d_keys[p_name] = _flatten_keys([ + p_obj.__xsimlab_store_keys__.values(), + p_obj.__xsimlab_od_keys__.values() + ]) + + for p_name, p_obj in self._processes_obj.items(): + for var in filter_variables(p_obj, intent=VarIntent.OUT).values(): + if var.metadata['var_type'] == VarType.ON_DEMAND: + key = p_obj.__xsimlab_od_keys__[var.name] + else: + key = p_obj.__xsimlab_store_keys__[var.name] + + for pn in self._processes_obj: + if pn != p_name and key in d_keys[pn]: + self._dep_processes[pn].add(p_name) + + self._dep_processes = {k: list(v) + for k, v in self._dep_processes.items()} + + return self._dep_processes + + def _sort_processes(self): + """Sort processes based on their dependencies (return a list of sorted + process names). + + Stack-based depth-first search traversal. + + This is based on Tarjan's method for topological sorting. + + Part of the code below is copied and modified from: + + - dask 0.14.3 (Copyright (c) 2014-2015, Continuum Analytics, Inc. + and contributors) + Licensed under the BSD 3 License + http://dask.pydata.org + + """ + ordered = [] + + # Nodes whose descendents have been completely explored. + # These nodes are guaranteed to not be part of a cycle. + completed = set() + + # All nodes that have been visited in the current traversal. Because + # we are doing depth-first search, going "deeper" should never result + # in visiting a node that has already been seen. The `seen` and + # `completed` sets are mutually exclusive; it is okay to visit a node + # that has already been added to `completed`. + seen = set() + + for key in self._dep_processes: + if key in completed: continue - seen.add(cur) - - # Add direct descendants of cur to nodes stack - next_nodes = [] - for nxt in dep_processes[cur]: - if nxt not in completed: - if nxt in seen: - # Cycle detected! - cycle = [nxt] - while nodes[-1] != nxt: + nodes = [key] + while nodes: + # Keep current node on the stack until all descendants are + # visited + cur = nodes[-1] + if cur in completed: + # Already fully traversed descendants of cur + nodes.pop() + continue + seen.add(cur) + + # Add direct descendants of cur to nodes stack + next_nodes = [] + for nxt in self._dep_processes[cur]: + if nxt not in completed: + if nxt in seen: + # Cycle detected! + cycle = [nxt] + while nodes[-1] != nxt: + cycle.append(nodes.pop()) cycle.append(nodes.pop()) - cycle.append(nodes.pop()) - cycle.reverse() - cycle = '->'.join(cycle) - raise ValueError( - "cycle detected in process graph: %s" % cycle - ) - next_nodes.append(nxt) - - if next_nodes: - nodes.extend(next_nodes) - else: - # cur has no more descendants to explore, so we're done with it - ordered.append(cur) - completed.add(cur) - seen.remove(cur) - nodes.pop() - return ordered + cycle.reverse() + cycle = '->'.join(cycle) + raise RuntimeError( + "Cycle detected in process graph: %s" % cycle + ) + next_nodes.append(nxt) + + if next_nodes: + nodes.extend(next_nodes) + else: + # cur has no more descendants to explore, + # so we're done with it + ordered.append(cur) + completed.add(cur) + seen.remove(cur) + nodes.pop() + return ordered + + def get_sorted_processes(self): + self._sorted_processes = OrderedDict( + [(p_name, self._processes_obj[p_name]) + for p_name in self._sort_processes()] + ) + return self._sorted_processes + + def get_stage_processes(self, stage): + """Return a (sorted) list of all process objects that implement the + method relative to a given simulation stage {'initialize', 'run_step', + 'finalize_step', 'finalize'}. + + """ + return [p_obj for p_obj in self._sorted_processes.values() + if has_method(p_obj, stage)] class Model(AttrMapping, ContextMixin): - """An immutable collection (mapping) of process units that together - form a computational model. + """An immutable collection of process units that together form a + computational model. This collection is ordered such that the computational flow is consistent with process inter-dependencies. @@ -170,7 +329,7 @@ class Model(AttrMapping, ContextMixin): computed using the processes interfaces. Processes interfaces are also used for automatically retrieving - the model inputs, i.e., all the variables which require setting a + the model inputs, i.e., all the variables that require setting a value before running the model. """ @@ -179,78 +338,107 @@ def __init__(self, processes): Parameters ---------- processes : dict - Dictionnary with process names as keys and subclasses of - `Process` as values. + Dictionnary with process names as keys and classes (decorated with + :func:`process`) as values. + + Raises + ------ + :exc:`TypeError` + If values in ``processes`` are not classes. + :exc:`NoteAProcessClassError` + If values in ``processes`` are not classes decorated with + :func:`process`. """ - processes_obj = {} - - for k, cls in processes.items(): - if not issubclass(cls, Process) or cls is Process: - raise TypeError("%s is not a subclass of Process" % cls) - processes_obj[k] = cls() - - _set_process_names(processes_obj) - _set_group_vars(processes_obj) - _link_foreign_vars(processes_obj) - - self._input_vars = _get_input_vars(processes_obj) - self._dep_processes = _get_process_dependencies(processes_obj) - self._processes = OrderedDict( - [(k, processes_obj[k]) - for k in _sort_processes(self._dep_processes)] - ) - self._time_processes = OrderedDict( - [(k, proc) for k, proc in self._processes.items() - if proc.meta['time_dependent']] - ) + for cls in processes.values(): + if not isclass(cls): + raise TypeError("Dictionary values must be classes, " + "found {}".format(cls)) + ensure_process_decorated(cls) + + builder = _ModelBuilder(processes) + + builder.bind_processes(self) + builder.set_process_keys() + + self._all_vars = builder.get_all_variables() + self._all_vars_dict = None + + self._input_vars = builder.get_input_variables() + self._input_vars_dict = None + + self._dep_processes = builder.get_process_dependencies() + self._processes = builder.get_sorted_processes() + + self._p_initialize = builder.get_stage_processes('initialize') + self._p_run_step = builder.get_stage_processes('run_step') + self._p_finalize_step = builder.get_stage_processes('finalize_step') + self._p_finalize = builder.get_stage_processes('finalize') super(Model, self).__init__(self._processes) self._initialized = True - def _get_proc_var_name(self, variable): - # type: AbstractVariable -> Union[tuple[str, str], None] - for proc_name, variables in self._processes.items(): - for var_name, var in variables.items(): - if var is variable: - return proc_name, var_name - return None, None + @property + def all_vars(self): + """Returns all variables in the model as a list of + ``(process_name, var_name)`` tuples (or an empty list). + + """ + return self._all_vars + + @property + def all_vars_dict(self): + """Returns all variables in the model as a dictionary of lists of + variable names grouped by process. + + """ + if self._all_vars_dict is None: + all_vars = defaultdict(list) + + for p_name, var_name in self._all_vars: + all_vars[p_name].append(var_name) + + self._all_vars_dict = dict(all_vars) + + return self._all_vars_dict @property def input_vars(self): - """Returns all variables that require setting a - value before running the model. + """Returns all variables that require setting a value before running + the model. - These variables are grouped by process name (dict of dicts). + A list of ``(process_name, var_name)`` tuples (or an empty list) + is returned. """ return self._input_vars - def is_input(self, variable): - """Test if a variable is an input of Model. - - Parameters - ---------- - variable : object or tuple - Either a Variable object or a (str, str) tuple - corresponding to process name and variable name. + @property + def input_vars_dict(self): + """Returns all variables that require setting a value before running + the model. - Returns - ------- - is_input : bool - True if the variable is a input of Model (otherwise False). + Unlike :attr:`Model.input_vars`, a dictionary of lists of + variable names grouped by process is returned. """ - if isinstance(variable, AbstractVariable): - proc_name, var_name = self._get_proc_var_name(variable) - elif isinstance(variable, (VariableList, VariableGroup)): - proc_name, var_name = None, None # prevent unpack iterable below - else: - proc_name, var_name = variable + if self._input_vars_dict is None: + inputs = defaultdict(list) + + for p_name, var_name in self._input_vars: + inputs[p_name].append(var_name) + + self._input_vars_dict = dict(inputs) + + return self._input_vars_dict + + @property + def dependent_processes(self): + """Returns a dictionary where keys are process names and values are + lists of the names of dependent processes. - if self._input_vars.get(proc_name, {}).get(var_name, False): - return True - return False + """ + return self._dep_processes def visualize(self, show_only_variable=None, show_inputs=False, show_variables=False): @@ -258,20 +446,20 @@ def visualize(self, show_only_variable=None, show_inputs=False, Parameters ---------- - show_only_variable : object or tuple, optional - Show only a variable (and all other linked variables) given either - as a Variable object or a tuple corresponding to process name and - variable name. Deactivated by default. + show_only_variable : tuple, optional + Show only a variable (and all other variables sharing the + same value) given as a tuple ``(process_name, variable_name)``. + Deactivated by default. show_inputs : bool, optional If True, show all input variables in the graph (default: False). Ignored if `show_only_variable` is not None. show_variables : bool, optional If True, show also the other variables (default: False). - Ignored if `show_only_variable` is not None. + Ignored if ``show_only_variable`` is not None. See Also -------- - dot.dot_graph + :func:`dot.dot_graph` """ from .dot import dot_graph @@ -280,34 +468,29 @@ def visualize(self, show_only_variable=None, show_inputs=False, show_variables=show_variables) def initialize(self): - """Run `.initialize()` for each processes in the model.""" - for proc in self._processes.values(): - proc.initialize() + """Run the 'initialize' stage of a simulation.""" + for p in self._p_initialize: + p.initialize() def run_step(self, step): - """Run `.run_step()` for each time dependent processes in the model. - """ - for proc in self._time_processes.values(): - proc.run_step(step) + """Run a single 'run_step()' stage of a simulation.""" + for p in self._p_run_step: + p.run_step(step) def finalize_step(self): - """Run `.finalize_step()` for each time dependent processes - in the model. - """ - for proc in self._time_processes.values(): - proc.finalize_step() + """Run a single 'finalize_step' stage of a simulation.""" + for p in self._p_finalize_step: + p.finalize_step() def finalize(self): - """Run `.finalize()` for each processes in the model.""" - for proc in self._processes.values(): - proc.finalize() + """Run the 'finalize' stage of a simulation.""" + for p in self._p_finalize: + p.finalize() def clone(self): - """Clone the Model. + """Clone the Model, i.e., create a new Model instance with the same + process classes but different instances. - This is equivalent to a deep copy, except that variable data - (i.e., `state`, `value`, `change` or `rate` properties) in all - processes are not copied. """ processes_cls = {k: type(obj) for k, obj in self._processes.items()} return type(self)(processes_cls) @@ -318,8 +501,8 @@ def update_processes(self, processes): Parameters ---------- processes : dict - Dictionnary with process names as keys and subclasses of - `Process` as values. + Dictionnary with process names as keys and process classes + as values. Returns ------- @@ -353,32 +536,4 @@ def drop_processes(self, keys): return type(self)(processes_cls) def __repr__(self): - n_inputs = sum([len(v) for v in self._input_vars.values()]) - - hdr = ("" - % (len(self._processes), n_inputs)) - - if not len(self._processes): - return hdr - - max_line_length = 70 - col_width = max([_calculate_col_width(var) - for var in self._input_vars.values()]) - - blocks = [] - for proc_name in self._processes: - proc_str = "%s" % proc_name - - inputs = self._input_vars.get(proc_name, {}) - lines = [] - for name, var in inputs.items(): - line = pretty_print(" %s " % name, col_width) - line += maybe_truncate("(in) %s" % var.description, - max_line_length - col_width) - lines.append(line) - - if lines: - proc_str += '\n' + '\n'.join(lines) - blocks.append(proc_str) - - return hdr + '\n' + '\n'.join(blocks) + return repr_model(self) diff --git a/xsimlab/process.py b/xsimlab/process.py index b630fb52..88a8dfa8 100644 --- a/xsimlab/process.py +++ b/xsimlab/process.py @@ -1,237 +1,413 @@ +from inspect import isclass import sys -import inspect -import copy -from collections import OrderedDict - -from .variable.base import (AbstractVariable, DiagnosticVariable, - VariableList, VariableGroup) -from .formatting import process_info -from .utils import AttrMapping, combomethod +import attr -_process_meta_default = { - 'time_dependent': True -} +from .variable import VarIntent, VarType +from .formatting import repr_process, var_details +from .utils import variables_dict -def _extract_variables(mapping): - # type: Dict[str, Any] -> Tuple[ - # Dict[str, Union[AbstractVariable, Variablelist, VariableGroup]], - # Dict[str, Any]] +class NotAProcessClassError(ValueError): + """ + A non-``xsimlab.process`` class has been passed into a ``xsimlab`` + function. + + """ + pass + + +def ensure_process_decorated(cls): + if not getattr(cls, "__xsimlab_process__", False): + raise NotAProcessClassError("{cls!r} is not a " + "process-decorated class.".format(cls=cls)) + + +def get_process_cls(obj_or_cls): + if not isclass(obj_or_cls): + cls = type(obj_or_cls) + else: + cls = obj_or_cls + + ensure_process_decorated(cls) + + return cls + + +def get_process_obj(obj_or_cls): + if isclass(obj_or_cls): + cls = obj_or_cls + obj = cls() + else: + cls = type(obj_or_cls) + obj = obj_or_cls + + ensure_process_decorated(cls) + + return obj + + +def filter_variables(process, var_type=None, intent=None, group=None, + func=None): + """Filter the variables declared in a process. + + Parameters + ---------- + process : object or class + Process class or object. + var_type : {'variable', 'on_demand', 'foreign', 'group'}, optional + Return only variables of a specified type. + intent : {'in', 'out', 'inout'}, optional + Return only input, output or input/output variables. + group : str, optional + Return only variables that belong to a given group. + func : callable, optional + A callable that takes a variable (i.e., a :class:`attr.Attribute` + object) as input and return True or False. Useful for more advanced + filtering. + + Returns + ------- + attributes : dict + A dictionary of variable names as keys and :class:`attr.Attribute` + objects as values. + + """ + process_cls = get_process_cls(process) + + # be consistent and always return a dict (not OrderedDict) when no filter + vars = dict(variables_dict(process_cls)) + + if var_type is not None: + vars = {k: v for k, v in vars.items() + if v.metadata.get('var_type') == VarType(var_type)} + + if intent is not None: + vars = {k: v for k, v in vars.items() + if v.metadata.get('intent') == VarIntent(intent)} + + if group is not None: + vars = {k: v for k, v in vars.items() + if v.metadata.get('group') == group} + + if func is not None: + vars = {k: v for k, v in vars.items() if func(v)} + + return vars + + +def get_target_variable(var): + """Return the target (original) variable of a given variable and + the process class in which the target variable is declared. - var_dict = {} + If `var` is not a foreign variable, return itself and None instead + of a process class. - for key, value in mapping.items(): - if isinstance(value, (AbstractVariable, VariableList, VariableGroup)): - var_dict[key] = value + If the target of foreign variable is another foreign variable (and + so on...), this function follow the links until the original + variable is found. An error is thrown if a cyclic pattern is detected. - elif getattr(value, '_diagnostic', False): - var = DiagnosticVariable(value, description=value.__doc__, - attrs=value._diagnostic_attrs) - var_dict[key] = var + """ + target_process_cls = None + target_var = var + + visited = [] + + while target_var.metadata['var_type'] == VarType.FOREIGN: + visited.append((target_process_cls, target_var)) + + target_process_cls = target_var.metadata['other_process_cls'] + var_name = target_var.metadata['var_name'] + target_var = filter_variables(target_process_cls)[var_name] + + # TODO: maybe remove this? not even sure such a cycle may happen + # unless we allow later providing other values than classes as first + # argument of `foreign` + if (target_process_cls, target_var) in visited: # pragma: no cover + cycle = '->'.join(['{}.{}'.format(cls.__name__, var.name) + if cls is not None else var.name + for cls, var in visited]) + + raise RuntimeError("Cycle detected in process dependencies: {}" + .format(cycle)) + + return target_process_cls, target_var + + +def _attrify_class(cls): + """Return a `cls` after having passed through :func:`attr.attrs`. + + This pulls out and converts `attr.ib` declared as class attributes + into :class:`attr.Attribute` objects and it also adds + dunder-methods such as `__init__`. + + The following instance attributes are also defined with None or + empty values (proper values will be set later at model creation): + + __xsimlab_model__ : obj + :class:`Model` instance to which the process instance is attached. + __xsimlab_name__ : str + Name given for this process in the model. + __xsimlab_store__ : dict or object + Simulation data store. + __xsimlab_store_keys__ : dict + Dictionary that maps variable names to their corresponding key + (or list of keys for group variables) in the store. + Such keys consist of pairs like `('foo', 'bar')` where + 'foo' is the name of any process in the same model and 'bar' is + the name of a variable declared in that process. + __xsimlab_od_keys__ : dict + Dictionary that maps variable names to the location of their target + on-demand variable (or a list of locations for group variables). + Locations are tuples like store keys. + + """ + def init_process(self): + self.__xsimlab_model__ = None + self.__xsimlab_name__ = None + self.__xsimlab_store__ = None + self.__xsimlab_store_keys__ = {} + self.__xsimlab_od_keys__ = {} + + setattr(cls, '__attrs_post_init__', init_process) - no_var_dict = {k: v for k, v in mapping.items() if k not in var_dict} + return attr.attrs(cls) - return var_dict, no_var_dict +def _make_property_variable(var): + """Create a property for a variable or a foreign variable (after + some sanity checks). -class ProcessBase(type): - """Metaclass for all processes.""" + The property get/set functions either read/write values from/to + the simulation data store or get (and trigger computation of) the + value of an on-demand variable. + + The property is read-only if `var` is declared as input. + + """ + var_name = var.name - def __new__(cls, name, bases, attrs): - parents = [b for b in bases if isinstance(b, ProcessBase)] - if not parents: - # Skip customization for the `Process` class - # (only applied to its subclasses) - new_attrs = attrs.copy() - new_attrs.update({'_variables': {}, '_meta': {}}) - return super().__new__(cls, name, bases, new_attrs) - for p in parents: - mro = [c for c in inspect.getmro(p) - if isinstance(c, ProcessBase)] - if len(mro) > 1: - # Currently not supported to create a class that - # inherits from a subclass of Process - raise TypeError("subclassing a subclass of Process " - "is not supported") + def get_from_store(self): + key = self.__xsimlab_store_keys__[var_name] + return self.__xsimlab_store__[key] - # start with new attributes - new_attrs = {'__module__': attrs.pop('__module__')} - classcell = attrs.pop('__classcell__', None) - if classcell is not None: - new_attrs['__classcell__'] = classcell # pragma: no cover + def get_on_demand(self): + p_name, v_name = self.__xsimlab_od_keys__[var_name] + p_obj = self.__xsimlab_model__._processes[p_name] + return getattr(p_obj, v_name) - # check and add metadata - meta_cls = attrs.pop('Meta', None) - meta_dict = _process_meta_default.copy() + def put_in_store(self, value): + key = self.__xsimlab_store_keys__[var_name] + self.__xsimlab_store__[key] = value - if meta_cls is not None: - meta_attrs = {k: v for k, v in meta_cls.__dict__.items() - if not k.startswith('__')} - invalid_attrs = set(meta_attrs) - set(meta_dict) - if invalid_attrs: - keys = ", ".join(["%r" % k for k in invalid_attrs]) - raise AttributeError( - "invalid attribute(s) %s set in class %s.Meta" - % (keys, cls.__name__) - ) - meta_dict.update(meta_attrs) + target_process_cls, target_var = get_target_variable(var) - new_attrs['_meta'] = OrderedDict(sorted(meta_dict.items())) + var_type = var.metadata['var_type'] + target_type = target_var.metadata['var_type'] + var_intent = var.metadata['intent'] + target_intent = target_var.metadata['intent'] - # add variables and diagnostics separately from the rest of - # the attributes and methods defined in the class - vars, novars = _extract_variables(attrs) - new_attrs['_variables'] = OrderedDict(sorted(vars.items())) - for k, v in novars.items(): - new_attrs[k] = v + var_doc = var_details(var) - new_class = super().__new__(cls, name, bases, new_attrs) + if target_process_cls is not None: + target_str = '.'.join([target_process_cls.__name__, target_var.name]) + else: + target_str = target_var.name - return new_class + if target_type == VarType.GROUP: + raise ValueError("Variable {var!r} links to group variable {target!r}, " + "which is not supported. Declare {var!r} as a group " + "variable instead." + .format(var=var.name, target=target_str)) + elif (var_type == VarType.FOREIGN and + var_intent == VarIntent.OUT and target_intent == VarIntent.OUT): + raise ValueError("Conflict between foreign variable {!r} and its " + "target variable {!r}, both have intent='out'." + .format(var.name, target_str)) -class Process(AttrMapping, metaclass=ProcessBase): - """Base class that represents a logical unit in a computational model. + elif target_type == VarType.ON_DEMAND: + return property(fget=get_on_demand, doc=var_doc) - A subclass of `Process` usually implements: + elif var_intent == VarIntent.IN: + return property(fget=get_from_store, doc=var_doc) - - A process interface as a set of `Variable`, `ForeignVariable`, - `VariableGroup` or `VariableList` objects, all defined as class - attributes. + else: + return property(fget=get_from_store, fset=put_in_store, doc=var_doc) - - Some of the five `.validate()`, `.initialize()`, `.run_step()`, - `.finalize_step()` and `.finalize()` methods, which use or compute - values of the variables defined in the interface during a model run. - - Additional methods decorated with `@diagnostic` that compute - the values of diagnostic variables during a model run. +def _make_property_on_demand(var): + """Create a read-only property for an on-demand variable. - Once created, a `Process` object provides both dict-like and - attribute-like access for all its variables, including diagnostic - variables if any. + This property is a simple wrapper around the variable's compute method. """ - def __init__(self): - # prevent modifying variables at the class level. also prevent - # using the same variable objects in two distinct instances - self._variables = copy.deepcopy(self._variables) + if 'compute' not in var.metadata: + raise KeyError("No compute method found for on_demand variable " + "'{name}'. A method decorated with '@{name}.compute' " + "is required in the class definition." + .format(name=var.name)) - super(Process, self).__init__(self._variables) + get_method = var.metadata['compute'] - for var in self._variables.values(): - if isinstance(var, DiagnosticVariable): - var.assign_process_obj(self) + return property(fget=get_method, doc=var_details(var)) - self._name = None - self._initialized = True - def clone(self): - """Clone the process. +def _make_property_group(var): + """Create a read-only property for a group variable.""" - This is equivalent to a deep copy, except that variable data - (i.e., `state`, `value`, `change` or `rate` properties) are not copied. - """ - obj = type(self)() - obj._name = self._name - return obj + var_name = var.name - @property - def variables(self): - """A dictionary of Process variables.""" - return self._variables + def getter_store_or_on_demand(self): + model = self.__xsimlab_model__ + store_keys = self.__xsimlab_store_keys__.get(var_name, []) + od_keys = self.__xsimlab_od_keys__.get(var_name, []) - @property - def meta(self): - """A dictionary of Process metadata (i.e., Meta attributes).""" - return self._meta + for key in store_keys: + yield self.__xsimlab_store__[key] - @property - def name(self): - """Process name. + for key in od_keys: + p_name, v_name = key + p_obj = model._processes[p_name] + yield getattr(p_obj, v_name) - Returns the name of the Process subclass if it is not attached to - any Model object. + return property(fget=getter_store_or_on_demand, doc=var_details(var)) - """ - if self._name is None: - return type(self).__name__ - return self._name +class _ProcessBuilder(object): + """Used to iteratively create a new process class. - def validate(self): - """Validate and/or update the process variables values. + The original class must be already "attr-yfied", i.e., it must + correspond to a class returned by `attr.attrs`. - Implementation is optional (by default it does nothing). + """ + _make_prop_funcs = { + VarType.VARIABLE: _make_property_variable, + VarType.ON_DEMAND: _make_property_on_demand, + VarType.FOREIGN: _make_property_variable, + VarType.GROUP: _make_property_group + } + + def __init__(self, attr_cls): + self._cls = attr_cls + self._cls.__xsimlab_process__ = True + self._cls_dict = {} + + def add_properties(self, var_type): + make_prop_func = self._make_prop_funcs[var_type] + + for var_name, var in filter_variables(self._cls, var_type).items(): + self._cls_dict[var_name] = make_prop_func(var) - An implementation of this method should be provided if the process - has variables that are optional and/or that depend on other - variables defined in this process. + def add_repr(self): + self._cls_dict['__repr__'] = repr_process - To validate values of variables taken independently, it is - prefered to use Variable validators. + def render_docstrings(self): + # self._cls_dict['__doc__'] = "Process-ified class." + raise NotImplementedError("autodoc is not yet implemented.") - See Also - -------- - Variable.validators + def build_class(self): + cls = self._cls - """ - pass # pragma: no cover + # Attach properties (and docstrings) + for name, value in self._cls_dict.items(): + setattr(cls, name, value) - def initialize(self): - """This method will be called once at the beginning of a model run. + return cls - Implementation is optional (by default it does nothing). - """ - pass # pragma: no cover - def run_step(self, *args): - """This method will be called at every time step of a model run. +def process(maybe_cls=None, autodoc=False): + """A class decorator that adds everything needed to use the class + as a process. - It should accepts one argument that corresponds to the time step - duration. + A process represents a logical unit in a computational model. - This must be implemented for all time dependent processes. - """ - raise NotImplementedError( - "class %s has no method 'run_step' implemented" - % type(self).__name__ - ) + A process class usually implements: - def finalize_step(self): - """This method will be called at the end of every time step, i.e, - after `run_step` has been executed for all processes in a model. + - An interface as a set of variables defined as class attributes + (see :func:`variable`, :func:`on_demand`, :func:`foreign` and + :func:`group`). This decorator automatically adds properties to + get/set values for these variables. - Implementation is optional (by default it does nothing). - """ - pass # pragma: no cover + - One or more methods among ``initialize()``, ``run_step()``, + ``finalize_step()`` and ``finalize()``, which are called at different + stages of a simulation and perform some computation based on the + variables defined in the process interface. - def finalize(self): - """This method will be called once at the end of a model run. + - Decorated methods to compute, validate or set a default value for one or + more variables. + + Parameters + ---------- + maybe_cls : class, optional + Allows to apply this decorator to a class either as ``@process`` or + ``@process(*args)``. + autodoc : bool, optional + If True, render the docstrings template and fill the + corresponding sections with variable metadata (default: False). + + """ + def wrap(cls): + attr_cls = _attrify_class(cls) - Implementation is optional (by default does nothing). - """ - pass # pragma: no cover + builder = _ProcessBuilder(attr_cls) - @combomethod - def info(cls_or_self, buf=None): - """info(buf=None) + for var_type in VarType: + builder.add_properties(var_type) - Concise summary of Process variables and metadata. + if autodoc: + builder.render_docstrings() - Parameters - ---------- - buf : object, optional - Writable buffer (default: sys.stdout). + builder.add_repr() - """ - if buf is None: # pragma: no cover - buf = sys.stdout + return builder.build_class() - buf.write(process_info(cls_or_self)) + if maybe_cls is None: + return wrap + else: + return wrap(maybe_cls) + + +def process_info(process, buf=None): + """Concise summary of process variables and simulation stages + implemented. + + Equivalent to __repr__ of a process but accepts either an instance + or a class. + + Parameters + ---------- + process : object or class + Process class or object. + buf : object, optional + Writable buffer (default: sys.stdout). + + """ + if buf is None: # pragma: no cover + buf = sys.stdout + + process = get_process_obj(process) + + buf.write(repr_process(process)) + + +def variable_info(process, var_name, buf=None): + """Get detailed information about a variable. + + Parameters + ---------- + process : object or class + Process class or object. + var_name : str + Variable name. + buf : object, optional + Writable buffer (default: sys.stdout). + + """ + if buf is None: # pragma: no cover + buf = sys.stdout - def __repr__(self): - cls = "'%s.%s'" % (self.__module__, type(self).__name__) - header = "\n" % cls + process = get_process_cls(process) + var = variables_dict(process)[var_name] - return header + process_info(self) + buf.write(var_details(var)) diff --git a/xsimlab/stores.py b/xsimlab/stores.py new file mode 100644 index 00000000..0b143793 --- /dev/null +++ b/xsimlab/stores.py @@ -0,0 +1,21 @@ +from collections import defaultdict +from copy import copy + +import numpy as np + + +class InMemoryOutputStore(object): + """A simple, in-memory store for model outputs. + + It basically consists of a Python dictionary with lists as values, + which are converted to numpy arrays on store read-access. + + """ + def __init__(self): + self._store = defaultdict(list) + + def append(self, key, value): + self._store[key].append(copy(value)) + + def __getitem__(self, key): + return np.array(self._store[key]) diff --git a/xsimlab/tests/conftest.py b/xsimlab/tests/conftest.py index bf4090ee..105fcce6 100644 --- a/xsimlab/tests/conftest.py +++ b/xsimlab/tests/conftest.py @@ -1,187 +1,7 @@ -""" -This module provides a set of Process subclasses and pytest fixtures that are -used across the tests. -""" -from textwrap import dedent - -import pytest -import numpy as np -import xarray as xr - -from xsimlab.variable.base import (Variable, ForeignVariable, VariableGroup, - VariableList, diagnostic) -from xsimlab.process import Process -from xsimlab.model import Model -from xsimlab.xr_accessor import SimlabAccessor -from xsimlab.xr_interface import DatasetModelInterface - - -class ExampleProcess(Process): - """A full example of process interface. - """ - var = Variable((), provided=True) - var_list = VariableList([Variable('x'), Variable([(), 'x'])]) - var_group = VariableGroup('group') - no_var = 'this is not a variable object' - - class Meta: - time_dependent = False - - @diagnostic - def diag(self): - return 1 - - -@pytest.fixture -def process(): - return ExampleProcess() - - -@pytest.fixture(scope='session') -def process_repr(): - return dedent("""\ - Variables: - * diag DiagnosticVariable - * var Variable () - var_group VariableGroup 'group' - var_list VariableList - - Variable ('x') - - Variable (), ('x') - Meta: - time_dependent: False""") - - -class Grid(Process): - x_size = Variable((), optional=True, description='grid size') - x = Variable('x', provided=True) - - class Meta: - time_dependent = False - - def validate(self): - if np.asscalar(self.x_size.value) is None: - self.x_size.value = 5 - - def initialize(self): - self.x.value = np.arange(self.x_size.value) - - -class Quantity(Process): - quantity = Variable('x', description='a quantity') - all_effects = VariableGroup('effect') - - def run_step(self, *args): - self.quantity.change = sum((var.value for var in self.all_effects)) - - def finalize_step(self): - self.quantity.state += self.quantity.change - - @diagnostic - def some_derived_quantity(self): - """some derived quantity.""" - return 1 - - @diagnostic({'units': 'm'}) - def other_derived_quantity(self): - """other derived quantity.""" - return 2 - - -class SomeProcess(Process): - some_param = Variable((), default_value=1, description='some parameter') - x = ForeignVariable(Grid, 'x') - quantity = ForeignVariable(Quantity, 'quantity') - some_effect = Variable('x', group='effect', provided=True) - - # SomeProcess always appears before OtherProcess in a model - copy_param = Variable((), provided=True) - - def initialize(self): - self.copy_param.value = self.some_param.value - - def run_step(self, dt): - self.some_effect.value = self.x.value * self.some_param.value + dt - - def finalize(self): - self.some_effect.rate = 0 - - -class OtherProcess(Process): - x = ForeignVariable(Grid, 'x') - quantity = ForeignVariable(Quantity, 'quantity') - other_param = Variable((), default_value=1, description='other parameter') - other_effect = Variable('x', group='effect', provided=True) - - # OtherProcess should always appear after SomeProcess in a model - copy_param = ForeignVariable(SomeProcess, 'copy_param') - - def run_step(self, dt): - self.other_effect.value = self.x.value * self.copy_param.value - dt - - @diagnostic - def x2(self): - return self.x * 2 - - -class PlugProcess(Process): - meta_param = Variable(()) - some_param = ForeignVariable(SomeProcess, 'some_param', provided=True) - x = ForeignVariable(Grid, 'x') - - def run_step(self, *args): - self.some_param.value = self.meta_param.value - - -@pytest.fixture -def model(): - model = Model({'grid': Grid, - 'some_process': SomeProcess, - 'other_process': OtherProcess, - 'quantity': Quantity}) - return model - - -@pytest.fixture(scope='session') -def model_repr(): - return dedent("""\ - - grid - x_size (in) grid size - some_process - some_param (in) some parameter - other_process - other_param (in) other parameter - quantity - quantity (in) a quantity""") - - -@pytest.fixture -def input_dataset(): - clock_key = SimlabAccessor._clock_key - mclock_key = SimlabAccessor._master_clock_key - svars_key = SimlabAccessor._snapshot_vars_key - - ds = xr.Dataset() - - ds['clock'] = ('clock', [0, 2, 4, 6, 8], - {clock_key: np.uint8(True), mclock_key: np.uint8(True)}) - ds['out'] = ('out', [0, 4, 8], {clock_key: np.uint8(True)}) - - ds['grid__x_size'] = ((), 10, {'description': 'grid size'}) - ds['quantity__quantity'] = ('x', np.zeros(10), - {'description': 'a quantity'}) - ds['some_process__some_param'] = ((), 1, {'description': 'some parameter'}) - ds['other_process__other_param'] = ('clock', [1, 2, 3, 4, 5], - {'description': 'other parameter'}) - - ds['clock'].attrs[svars_key] = 'quantity__quantity' - ds['out'].attrs[svars_key] = ('other_process__other_effect,' - 'some_process__some_effect') - ds.attrs[svars_key] = 'grid__x' - - return ds - - -@pytest.fixture -def ds_model_interface(model, input_dataset): - return DatasetModelInterface(model, input_dataset) +from xsimlab.tests.fixture_process import (example_process_obj, + example_process_repr, + in_var_details, processes_with_store, + example_process_in_model_repr) +from xsimlab.tests.fixture_model import (in_dataset, out_dataset, + no_init_model, model, + simple_model, simple_model_repr) diff --git a/xsimlab/tests/fixture_model.py b/xsimlab/tests/fixture_model.py new file mode 100644 index 00000000..ec9d75e7 --- /dev/null +++ b/xsimlab/tests/fixture_model.py @@ -0,0 +1,162 @@ +from collections import OrderedDict +from textwrap import dedent + +import numpy as np +import xarray as xr +import pytest + +import xsimlab as xs +from xsimlab.xr_accessor import SimlabAccessor + + +@xs.process +class Profile(object): + u = xs.variable(dims='x', description='quantity u', intent='inout') + u_diffs = xs.group('diff') + u_opp = xs.on_demand(dims='x') + + def initialize(self): + self.u_change = np.zeros_like(self.u) + + def run_step(self, *args): + self.u_change[:] = np.sum((d for d in self.u_diffs)) + + def finalize_step(self): + self.u += self.u_change + + def finalize(self): + self.u[:] = 0. + + @u_opp.compute + def _get_u_opposite(self): + return -self.u + + +@xs.process +class InitProfile(object): + n_points = xs.variable(description='nb. of profile points') + u = xs.foreign(Profile, 'u', intent='out') + + def initialize(self): + self.u = np.zeros(self.n_points) + self.u[0] = 1. + + +@xs.process +class Roll(object): + shift = xs.variable(description=('shift profile by a nb. of points'), + attrs={'units': 'unitless'}) + u = xs.foreign(Profile, 'u') + u_diff = xs.variable(dims='x', group='diff', intent='out') + + def run_step(self, *args): + self.u_diff = np.roll(self.u, self.shift) - self.u + + +@xs.process +class Add(object): + offset = xs.variable(description=('offset * dt added every time step ' + 'to profile u')) + u_diff = xs.variable(group='diff', intent='out') + + def run_step(self, dt): + self.u_diff = self.offset * dt + + +@xs.process +class AddOnDemand(object): + offset = xs.variable(description='offset added to profile u') + u_diff = xs.on_demand(group='diff') + + @u_diff.compute + def _compute_u_diff(self): + return self.offset + + +@pytest.fixture +def model(): + return xs.Model({'roll': Roll, + 'add': AddOnDemand, + 'profile': Profile, + 'init_profile': InitProfile}) + + +@pytest.fixture +def no_init_model(): + return xs.Model({'roll': Roll, + 'add': Add, + 'profile': Profile}) + + +@pytest.fixture +def simple_model(): + return xs.Model({'roll': Roll, + 'profile': Profile}) + + +@pytest.fixture(scope='session') +def simple_model_repr(): + return dedent("""\ + + roll + shift [in] shift profile by a nb. of points + profile + u [inout] ('x',) quantity u + """) + + +@pytest.fixture +def in_dataset(): + clock_key = SimlabAccessor._clock_key + mclock_key = SimlabAccessor._master_clock_key + svars_key = SimlabAccessor._output_vars_key + + ds = xr.Dataset() + + ds['clock'] = ('clock', [0, 2, 4, 6, 8], + {clock_key: np.uint8(True), mclock_key: np.uint8(True)}) + ds['out'] = ('out', [0, 4, 8], {clock_key: np.uint8(True)}) + + ds['init_profile__n_points'] = ( + (), 5, {'description': 'nb. of profile points'}) + ds['roll__shift'] = ( + (), 1, + OrderedDict([('description', 'shift profile by a nb. of points'), + ('units', 'unitless')])) + ds['add__offset'] = ( + 'clock', [1, 2, 3, 4, 5], {'description': 'offset added to profile u'}) + + ds['clock'].attrs[svars_key] = 'profile__u' + ds['out'].attrs[svars_key] = ('roll__u_diff,' + 'add__u_diff') + ds.attrs[svars_key] = 'profile__u_opp' + + return ds + + +@pytest.fixture +def out_dataset(in_dataset): + out_ds = in_dataset + + del out_ds.attrs[SimlabAccessor._output_vars_key] + del out_ds.clock.attrs[SimlabAccessor._output_vars_key] + del out_ds.out.attrs[SimlabAccessor._output_vars_key] + out_ds['profile__u_opp'] = ('x', [-10., -10., -10., -10., -11.]) + out_ds['profile_u'] = ( + ('clock', 'x'), + np.array([[1., 0., 0., 0., 0.], + [1., 2., 1., 1., 1.], + [3., 3., 4., 3., 3.], + [6., 6., 6., 7., 6.], + [10., 10., 10., 10., 11.]]), + {'description': 'quantity u'} + ) + out_ds['roll_u_diff'] = ( + ('out', 'x'), + np.array([[-1., 1., 0., 0., 0.], + [0., 0., -1., 1., 0.], + [0., 0., 0., -1., 1.]]) + ) + out_ds['add__u_diff'] = ('out', [1, 3, 4]) + + return out_ds diff --git a/xsimlab/tests/fixture_process.py b/xsimlab/tests/fixture_process.py new file mode 100644 index 00000000..e959798a --- /dev/null +++ b/xsimlab/tests/fixture_process.py @@ -0,0 +1,151 @@ +from textwrap import dedent + +import attr +import pytest + +import xsimlab as xs + + +@xs.process +class SomeProcess(object): + """Just used for foreign variables in ExampleProcess.""" + some_var = xs.variable(group='some_group', intent='out') + some_od_var = xs.on_demand(group='some_group') + + @some_od_var.compute + def compute_some_od_var(self): + return 1 + + +@xs.process +class AnotherProcess(object): + """Just used for foreign variables in ExampleProcess.""" + another_var = xs.variable() + some_var = xs.foreign(SomeProcess, 'some_var') + + +@xs.process +class ExampleProcess(object): + """A process with complete interface for testing.""" + in_var = xs.variable(dims=['x', ('x', 'y')], description='input variable') + out_var = xs.variable(group='example_group', intent='out') + inout_var = xs.variable(intent='inout') + od_var = xs.on_demand() + + in_foreign_var = xs.foreign(SomeProcess, 'some_var') + in_foreign_var2 = xs.foreign(AnotherProcess, 'some_var') + out_foreign_var = xs.foreign(AnotherProcess, 'another_var', intent='out') + in_foreign_od_var = xs.foreign(SomeProcess, 'some_od_var') + + group_var = xs.group('some_group') + + other_attrib = attr.attrib(init=False, cmp=False, repr=False) + other_attr = "this is not a xsimlab variable attribute" + + @od_var.compute + def compute_od_var(self): + return 0 + + +@pytest.fixture +def example_process_obj(): + return ExampleProcess() + + +@pytest.fixture(scope='session') +def example_process_repr(): + return dedent("""\ + + Variables: + in_var [in] ('x',) or ('x', 'y') input variable + out_var [out] + inout_var [inout] + od_var [out] + in_foreign_var [in] <--- SomeProcess.some_var + in_foreign_var2 [in] <--- AnotherProcess.some_var + out_foreign_var [out] ---> AnotherProcess.another_var + in_foreign_od_var [in] <--- SomeProcess.some_od_var + group_var [in] <--- group 'some_group' + Simulation stages: + *no stage implemented* + """) + + +@pytest.fixture(scope='session') +def in_var_details(): + return dedent("""\ + Input variable + + - type : variable + - intent : in + - dims : (('x',), ('x', 'y')) + - group : None + - attrs : {} + """) + + +def _init_process(p_cls, p_name, model, store, store_keys=None, od_keys=None): + p_obj = p_cls() + p_obj.__xsimlab_name__ = p_name + p_obj.__xsimlab_model__ = model + p_obj.__xsimlab_store__ = store + p_obj.__xsimlab_store_keys__ = store_keys or {} + p_obj.__xsimlab_od_keys__ = od_keys or {} + return p_obj + + +@pytest.fixture +def processes_with_store(): + class FakeModel(object): + def __init__(self): + self._processes = {} + + model = FakeModel() + store = {} + + some_process = _init_process( + SomeProcess, 'some_process', model, store, + store_keys={'some_var': ('some_process', 'some_var')} + ) + another_process = _init_process( + AnotherProcess, 'another_process', model, store, + store_keys={'another_var': ('another_process', 'another_var'), + 'some_var': ('some_process', 'some_var')} + ) + example_process = _init_process( + ExampleProcess, 'example_process', model, store, + store_keys={'in_var': ('example_process', 'in_var'), + 'out_var': ('example_process', 'out_var'), + 'inout_var': ('example_process', 'inout_var'), + 'in_foreign_var': ('some_process', 'some_var'), + 'in_foreign_var2': ('some_process', 'some_var'), + 'out_foreign_var': ('another_process', 'another_var'), + 'group_var': [('some_process', 'some_var')]}, + od_keys={'in_foreign_od_var': ('some_process', 'some_od_var'), + 'group_var': [('some_process', 'some_od_var')]} + ) + + model._processes.update({'some_process': some_process, + 'another_process': another_process, + 'example_process': example_process}) + + return some_process, another_process, example_process + + +@pytest.fixture(scope='session') +def example_process_in_model_repr(): + return dedent("""\ + + Variables: + in_var [in] ('x',) or ('x', 'y') input variable + out_var [out] + inout_var [inout] + od_var [out] + in_foreign_var [in] <--- some_process.some_var + in_foreign_var2 [in] <--- some_process.some_var + out_foreign_var [out] ---> another_process.another_var + in_foreign_od_var [in] <--- some_process.some_od_var + group_var [in] <--- group 'some_group' + Simulation stages: + *no stage implemented* + """) diff --git a/xsimlab/tests/test_dot.py b/xsimlab/tests/test_dot.py index 224a87e7..d8c19f1e 100644 --- a/xsimlab/tests/test_dot.py +++ b/xsimlab/tests/test_dot.py @@ -5,7 +5,8 @@ import pytest pytest.importorskip("graphviz") -from xsimlab.dot import to_graphviz, dot_graph, hash_variable +from xsimlab.dot import to_graphviz, dot_graph, _hash_variable +from xsimlab.utils import variables_dict # need to parse elements of graphivz's Graph object @@ -48,57 +49,32 @@ def test_to_graphviz(model): g = to_graphviz(model) actual_nodes = _get_graph_nodes(g) actual_edges = _get_graph_edges(g) - expected_nodes = ['grid', 'some_process', 'other_process', 'quantity'] - expected_edges = [ - ('grid', 'some_process'), - ('some_process', 'other_process'), - ('grid', 'other_process'), - ('some_process', 'quantity'), - ('other_process', 'quantity') - ] + expected_nodes = list(model) + expected_edges = [(dep_p_name, p_name) + for p_name, p_deps in model.dependent_processes.items() + for dep_p_name in p_deps] assert sorted(actual_nodes) == sorted(expected_nodes) assert set(actual_edges) == set(expected_edges) g = to_graphviz(model, show_inputs=True) actual_nodes = _get_graph_nodes(g) actual_edges = _get_graph_edges(g) - expected_nodes = ['grid', 'some_process', 'other_process', 'quantity', - 'x_size', 'some_param', 'other_param', 'quantity'] - expected_edges = [ - ('grid', 'some_process'), - ('some_process', 'other_process'), - ('grid', 'other_process'), - ('some_process', 'quantity'), - ('other_process', 'quantity'), - (hash_variable(model.grid.x_size), 'grid'), - (hash_variable(model.some_process.some_param), 'some_process'), - (hash_variable(model.other_process.other_param), 'other_process'), - (hash_variable(model.quantity.quantity), 'quantity') + expected_nodes += [var_name for _, var_name in model.input_vars] + expected_edges += [ + (_hash_variable(variables_dict(type(model[p_name]))[var_name]), p_name) + for p_name, var_name in model.input_vars ] assert sorted(actual_nodes) == sorted(expected_nodes) assert set(actual_edges) == set(expected_edges) g = to_graphviz(model, show_variables=True) actual_nodes = _get_graph_nodes(g) - expected_nodes = ['grid', 'some_process', 'other_process', 'quantity', - 'x', 'copy_param', 'quantity', 'some_effect', 'x', - 'copy_param', 'other_effect', 'quantity', 'x', 'x2', - 'all_effects', 'other_derived_quantity', - 'some_derived_quantity', '"\\"', - '"\\"'] + expected_nodes = list(model) + [var_name for _, var_name in model.all_vars] assert sorted(actual_nodes) == sorted(expected_nodes) - g = to_graphviz(model, show_only_variable=('quantity', 'quantity')) - assert _get_graph_nodes(g).count('quantity') == 4 - - g = to_graphviz(model, show_only_variable=model.some_process.quantity) - assert _get_graph_nodes(g).count('quantity') == 4 - - g = to_graphviz(model, show_only_variable=('some_process', 'some_effect')) + g = to_graphviz(model, show_only_variable=('profile', 'u')) actual_nodes = _get_graph_nodes(g) - expected_nodes = ['grid', 'some_process', 'other_process', - 'quantity', 'some_effect', 'all_effects', - '"\\"'] + expected_nodes = list(model) + ['u'] * 3 assert sorted(actual_nodes) == sorted(expected_nodes) diff --git a/xsimlab/tests/test_drivers.py b/xsimlab/tests/test_drivers.py new file mode 100644 index 00000000..e0960982 --- /dev/null +++ b/xsimlab/tests/test_drivers.py @@ -0,0 +1,111 @@ +import numpy as np +import pytest +from numpy.testing import assert_array_equal +from xarray.testing import assert_identical + +import xsimlab as xs +from xsimlab.drivers import (_get_dims_from_variable, BaseSimulationDriver, + XarraySimulationDriver) +from xsimlab.stores import InMemoryOutputStore + + +@pytest.fixture +def base_driver(model): + store = {} + out_store = InMemoryOutputStore() + return BaseSimulationDriver(model, store, out_store) + + +@pytest.fixture +def xarray_driver(in_dataset, model): + store = {} + out_store = InMemoryOutputStore() + return XarraySimulationDriver(in_dataset, model, store, out_store) + + +class TestBaseDriver(object): + + def test_bind_store(self, base_driver): + base_driver.store[('init_profile', 'n_points')] = 10 + assert base_driver.model.init_profile.n_points == 10 + + def test_update_store(self, base_driver): + n = [10, 100, 1000] + input_vars = {('init_profile', 'n_points'): n} + base_driver.update_store(input_vars) + + assert base_driver.store[('init_profile', 'n_points')] == n + assert base_driver.store[('init_profile', 'n_points')] is not n + + def test_update_output_store(self, base_driver): + base_driver.store[('init_profile', 'n_points')] = 5 + base_driver.model.init_profile.initialize() + + base_driver.update_output_store([('profile', 'u')]) + + expected = [np.array([1., 0., 0., 0., 0.])] + assert_array_equal( + base_driver.output_store[('profile', 'u')], + expected) + + def test_run_model(self, base_driver): + with pytest.raises(NotImplementedError): + base_driver.run_model() + + +@pytest.mark.parametrize('array,clock,expected' , [ + (np.zeros((2, 2)), None, ('x', 'y')), + (np.zeros((2, 2)), 'clock', ('x',)), + (np.array(0), None, tuple()) +]) +def test_get_dims_from_variable(array, clock, expected): + var = xs.variable(dims=[(), ('x',), ('x', 'y')]) + assert _get_dims_from_variable(array, var, clock) == expected + + +class TestXarraySimulationDriver(object): + + def test_constructor(self, in_dataset, model): + store = {} + out_store = InMemoryOutputStore() + + invalid_ds = in_dataset.drop('clock') + with pytest.raises(ValueError) as excinfo: + XarraySimulationDriver(invalid_ds, model, store, out_store) + assert "Missing master clock" in str(excinfo.value) + + invalid_ds = in_dataset.drop('init_profile__n_points') + with pytest.raises(KeyError) as excinfo: + XarraySimulationDriver(invalid_ds, model, store, out_store) + assert "Missing variables" in str(excinfo.value) + + def test_output_save_steps(self, xarray_driver): + expected = {'clock': np.array([True, True, True, True, True]), + 'out': np.array([True, False, True, False, True])} + + assert xarray_driver.output_save_steps.keys() == expected.keys() + for k in expected: + assert_array_equal(xarray_driver.output_save_steps[k], expected[k]) + + def test_time_step_lengths(self, xarray_driver): + assert_array_equal(xarray_driver._get_time_steps(), [2, 2, 2, 2]) + + def test_split_data_vars_clock(self, xarray_driver): + ds_in, ds_in_clock = xarray_driver._split_clock_inputs() + + assert 'add__offset' in ds_in_clock and 'add__offset' not in ds_in + assert 'roll__shift' in ds_in and 'roll__shift' not in ds_in_clock + + def test_set_input_vars(self, in_dataset, xarray_driver): + in_ds = in_dataset.drop('add__offset') + xarray_driver._set_input_vars(in_ds) + + assert (xarray_driver.store[('init_profile', 'n_points')] == + in_dataset['init_profile__n_points'].data) + assert (xarray_driver.store[('init_profile', 'n_points')] is not + in_dataset['init_profile__n_points'].data) + + def test_run_model(self, in_dataset, out_dataset, xarray_driver): + out_ds_actual = xarray_driver.run_model() + + assert_identical(out_ds_actual, out_dataset) diff --git a/xsimlab/tests/test_formatting.py b/xsimlab/tests/test_formatting.py index 059d7e81..57049332 100644 --- a/xsimlab/tests/test_formatting.py +++ b/xsimlab/tests/test_formatting.py @@ -1,4 +1,9 @@ -from xsimlab.formatting import pretty_print, maybe_truncate, wrap_indent +from textwrap import dedent + +import xsimlab as xs +from xsimlab.formatting import (maybe_truncate, pretty_print, + repr_process, repr_model, + var_details, wrap_indent) def test_maybe_truncate(): @@ -18,3 +23,48 @@ def test_wrap_indent(): expected = 'line1\n line2' assert wrap_indent(text, length=1) == expected + + +def test_var_details(example_process_obj): + var = xs.variable(dims='x', description='a variable') + + var_details_str = var_details(var) + + assert var_details_str.strip().startswith('A variable') + assert "- type : variable" in var_details_str + assert "- intent : in" in var_details_str + assert "- dims : (('x',),)" in var_details_str + + +def test_process_repr(example_process_obj, processes_with_store, + example_process_repr, example_process_in_model_repr): + assert repr_process(example_process_obj) == example_process_repr + + _, _, process_in_model = processes_with_store + assert repr_process(process_in_model) == example_process_in_model_repr + + @xs.process + class Dummy(object): + def initialize(self): + pass + + def run_step(self): + pass + + expected = dedent("""\ + + Variables: + *empty* + Simulation stages: + initialize + run_step + """) + + assert repr_process(Dummy()) == expected + + +def test_model_repr(simple_model, simple_model_repr): + assert repr_model(simple_model) == simple_model_repr + + expected = "\n" + assert repr(xs.Model({})) == expected diff --git a/xsimlab/tests/test_model.py b/xsimlab/tests/test_model.py index a1e9270b..908e94f3 100644 --- a/xsimlab/tests/test_model.py +++ b/xsimlab/tests/test_model.py @@ -1,89 +1,150 @@ import pytest -import numpy as np -from numpy.testing import assert_array_equal -from xsimlab.variable.base import (Variable, ForeignVariable, VariableList, - VariableGroup) -from xsimlab.process import Process -from xsimlab.model import Model -from xsimlab.tests.conftest import (Grid, SomeProcess, OtherProcess, Quantity, - PlugProcess) +import xsimlab as xs +from xsimlab.tests.fixture_model import AddOnDemand, InitProfile + + +class TestModelBuilder(object): + + def test_bind_processes(self, model): + assert model._processes['profile'].__xsimlab_model__ is model + assert model._processes['profile'].__xsimlab_name__ == 'profile' + + @pytest.mark.parametrize('p_name,expected_store_keys,expected_od_keys', [ + ('init_profile', + {'n_points': ('init_profile', 'n_points'), 'u': ('profile', 'u')}, + {} + ), + ('profile', + {'u': ('profile', 'u'), + 'u_diffs': [('roll', 'u_diff')]}, + {'u_diffs': [('add', 'u_diff')], 'u_opp': ('profile', 'u_opp')} + ), + ('roll', + {'shift': ('roll', 'shift'), 'u': ('profile', 'u'), + 'u_diff': ('roll', 'u_diff')}, + {} + ), + ('add', + {'offset': ('add', 'offset')}, + {'u_diff': ('add', 'u_diff')} + ) + ]) + def test_set_process_keys(self, model, p_name, + expected_store_keys, expected_od_keys): + p_obj = model._processes[p_name] + actual_store_keys = p_obj.__xsimlab_store_keys__ + actual_od_keys = p_obj.__xsimlab_od_keys__ + + # key order is not ensured for group variables + if isinstance(expected_store_keys, list): + actual_store_keys = set(actual_store_keys) + expected_store_keys = set(expected_store_keys) + if isinstance(expected_od_keys, list): + actual_od_keys = set(actual_od_keys) + expected_od_keys = set(expected_od_keys) + + assert actual_store_keys == expected_store_keys + assert actual_od_keys == expected_od_keys + + def test_get_all_variables(self, model): + assert all([len(t) == 2 for t in model.all_vars]) + assert all([p_name in model for p_name, _ in model.all_vars]) + assert ('profile', 'u') in model.all_vars + + def test_get_input_variables(self, model): + expected = {('init_profile', 'n_points'), + ('roll', 'shift'), + ('add', 'offset')} + + assert set(model.input_vars) == expected + + def test_get_process_dependencies(self, model): + expected = {'init_profile': [], + 'profile': ['init_profile', 'add', 'roll'], + 'roll': ['init_profile'], + 'add': []} + + actual = model.dependent_processes + + for p_name in expected: + # order of dependencies is not ensured + assert set(actual[p_name]) == set(expected[p_name]) + + @pytest.mark.parametrize('p_name,dep_p_name', [ + ('profile', 'init_profile'), + ('profile', 'add'), + ('profile', 'roll'), + ('roll', 'init_profile') + ]) + def test_sort_processes(self, model, p_name, dep_p_name): + p_ordered = list(model) + assert p_ordered.index(p_name) > p_ordered.index(dep_p_name) + + def test_sort_processes_cycle(self, model): + @xs.process + class Foo(object): + in_var = xs.variable() + out_var = xs.variable(intent='out') + + @xs.process + class Bar(object): + in_foreign = xs.foreign(Foo, 'out_var') + out_foreign = xs.foreign(Foo, 'in_var', intent='out') + + with pytest.raises(RuntimeError) as excinfo: + xs.Model({'foo': Foo, 'bar': Bar}) + assert "Cycle detected" in str(excinfo.value) + + def test_get_stage_processes(self, model): + expected = [model['roll'], model['profile']] + assert model._p_run_step == expected -@pytest.fixture -def model(model): - """Override fixture defined in conftest.py, return a model - with values set for some of its variables. - """ - model.grid.x_size.value = 10 - model.quantity.quantity.state = np.zeros(10) - model.some_process.some_param.value = 1 +class TestModel(object): - return model + def test_constructor(self): + with pytest.raises(TypeError) as excinfo: + xs.Model({'init_profile': InitProfile()}) + assert "values must be classes" in str(excinfo.value) + with pytest.raises(KeyError) as excinfo: + xs.Model({'init_profile': InitProfile}) + assert "Process class 'Profile' missing" in str(excinfo.value) -class TestModel(object): + # test empty model + assert len(xs.Model({})) == 0 - def test_constructor(self, model): - # test invalid processes - with pytest.raises(TypeError): - Model({'not_a_class': Grid()}) + def test_process_dict_vs_attr_access(self, model): + assert model['profile'] is model.profile - class OtherClass(object): - pass + def test_all_vars_dict(self, model): + assert all([p_name in model for p_name in model.all_vars_dict]) + assert all([isinstance(p_vars, list) + for p_vars in model.all_vars_dict.values()]) + assert 'u' in model.all_vars_dict['profile'] - with pytest.raises(TypeError) as excinfo: - Model({'invalid_class': Process}) - assert "is not a subclass" in str(excinfo.value) + def test_input_vars_dict(self, model): + assert all([p_name in model for p_name in model.input_vars_dict]) + assert all([isinstance(p_vars, list) + for p_vars in model.input_vars_dict.values()]) + assert 'n_points' in model.input_vars_dict['init_profile'] - with pytest.raises(TypeError) as excinfo: - Model({'invalid_class': OtherClass}) - assert "is not a subclass" in str(excinfo.value) - - # test process ordering - expected = ['grid', 'some_process', 'other_process', 'quantity'] - assert list(model) == expected - - # test dict-like vs. attribute access - assert model['grid'] is model.grid - - # test cyclic process dependencies - class CyclicProcess(Process): - some_param = ForeignVariable(SomeProcess, 'some_param', - provided=True) - some_effect = ForeignVariable(SomeProcess, 'some_effect') - - processes = {k: type(v) for k, v in model.items()} - processes.update({'cyclic': CyclicProcess}) - - with pytest.raises(ValueError) as excinfo: - Model(processes) - assert "cycle detected" in str(excinfo.value) - - def test_input_vars(self, model): - expected = {'grid': ['x_size'], - 'some_process': ['some_param'], - 'other_process': ['other_param'], - 'quantity': ['quantity']} - actual = {k: list(v.keys()) for k, v in model.input_vars.items()} - assert expected == actual - - def test_is_input(self, model): - assert model.is_input(model.grid.x_size) is True - assert model.is_input(('grid', 'x_size')) is True - assert model.is_input(model.quantity.all_effects) is False - assert model.is_input(('other_process', 'copy_param')) is False - - external_variable = Variable(()) - assert model.is_input(external_variable) is False - - var_list = [Variable(()), Variable(()), Variable(())] - variable_list = VariableList(var_list) - assert model.is_input(variable_list) is False - - variable_group = VariableGroup('group') - variable_group._set_variables({}) - assert model.is_input(variable_group) is False + def test_clone(self, model): + cloned = model.clone() + + for p_name in model: + assert cloned[p_name] is not model[p_name] + + def test_update_processes(self, no_init_model, model): + m = no_init_model.update_processes({'add': AddOnDemand, + 'init_profile': InitProfile}) + assert m == model + + @pytest.mark.parametrize('p_names', ['add', ['add']]) + def test_drop_processes(self, no_init_model, simple_model, p_names): + m = no_init_model.drop_processes(p_names) + assert m == simple_model def test_visualize(self, model): pytest.importorskip('graphviz') @@ -99,64 +160,8 @@ def test_visualize(self, model): assert isinstance(result, ipydisp.Image) result = model.visualize( - show_only_variable=('quantity', 'quantity')) + show_only_variable=('profile', 'u')) assert isinstance(result, ipydisp.Image) - def test_initialize(self, model): - model.initialize() - expected = np.arange(10) - assert_array_equal(model.grid.x.value, expected) - - def test_run_step(self, model): - model.initialize() - model.run_step(100) - - expected = model.grid.x.value * 2 - assert_array_equal(model.quantity.quantity.change, expected) - - def test_finalize_step(self, model): - model.initialize() - model.run_step(100) - model.finalize_step() - - expected = model.grid.x.value * 2 - assert_array_equal(model.quantity.quantity.state, expected) - - def test_finalize(self, model): - model.finalize() - assert model.some_process.some_effect.rate == 0 - - def test_clone(self, model): - cloned = model.clone() - - for (ck, cp), (k, p) in zip(cloned.items(), model.items()): - assert ck == k - assert cp is not p - - def test_update_processes(self, model): - expected = Model({'grid': Grid, - 'plug_process': PlugProcess, - 'some_process': SomeProcess, - 'other_process': OtherProcess, - 'quantity': Quantity}) - actual = model.update_processes({'plug_process': PlugProcess}) - assert list(actual) == list(expected) - - def test_drop_processes(self, model): - - expected = Model({'grid': Grid, - 'some_process': SomeProcess, - 'quantity': Quantity}) - actual = model.drop_processes('other_process') - assert list(actual) == list(expected) - - expected = Model({'grid': Grid, - 'quantity': Quantity}) - actual = model.drop_processes(['some_process', 'other_process']) - assert list(actual) == list(expected) - - def test_repr(self, model, model_repr): - assert repr(model) == model_repr - - expected = "" - assert repr(Model({})) == expected + def test_repr(self, simple_model, simple_model_repr): + assert repr(simple_model) == simple_model_repr diff --git a/xsimlab/tests/test_process.py b/xsimlab/tests/test_process.py index 4ace2687..2978b9f9 100644 --- a/xsimlab/tests/test_process.py +++ b/xsimlab/tests/test_process.py @@ -1,99 +1,159 @@ -from textwrap import dedent from io import StringIO import pytest -from xsimlab.variable.base import Variable -from xsimlab.process import Process -from xsimlab.tests.conftest import ExampleProcess +import xsimlab as xs +from xsimlab.variable import VarIntent, VarType +from xsimlab.process import (ensure_process_decorated, filter_variables, + get_process_cls, get_process_obj, + get_target_variable, NotAProcessClassError, + process_info, variable_info) +from xsimlab.utils import variables_dict +from xsimlab.tests.fixture_process import ExampleProcess, SomeProcess + +def test_ensure_process_decorated(): + class NotAProcess(object): + pass -class TestProcessBase(object): + with pytest.raises(NotAProcessClassError) as excinfo: + ensure_process_decorated(NotAProcess) + assert "is not a process-decorated class" in str(excinfo.value) - def test_new(self): - with pytest.raises(TypeError) as excinfo: - class InvalidProcess(ExampleProcess): - var = Variable(()) - assert "subclassing a subclass" in str(excinfo.value) - with pytest.raises(AttributeError) as excinfo: - class InvalidProcess2(Process): - class Meta: - time_dependent = True - invalid_meta_attr = 'invalid' - assert "invalid attribute" in str(excinfo.value) +def test_get_process_cls(example_process_obj): + assert get_process_cls(ExampleProcess) is ExampleProcess + assert get_process_cls(example_process_obj) is ExampleProcess - # test extract variable objects vs. other attributes - assert getattr(ExampleProcess, 'no_var', False) - assert not getattr(ExampleProcess, 'var', False) - assert set(['var', 'var_list', 'var_group', 'diag']) == ( - set(ExampleProcess._variables.keys())) - # test Meta attributes - assert ExampleProcess._meta == {'time_dependent': False} +def test_get_process_obj(example_process_obj): + assert get_process_obj(example_process_obj) is example_process_obj + assert type(get_process_obj(ExampleProcess)) is ExampleProcess -class TestProcess(object): +@pytest.mark.parametrize('kwargs,expected', [ + ({}, {'in_var', 'out_var', 'inout_var', 'in_foreign_var', + 'in_foreign_var2', 'out_foreign_var', 'in_foreign_od_var', + 'group_var', 'od_var'}), + ({'var_type': 'variable'}, {'in_var', 'out_var', 'inout_var'}), + ({'intent': 'in'}, {'in_var', 'in_foreign_var', 'in_foreign_var2', + 'in_foreign_od_var', 'group_var'}), + ({'intent': 'out'}, {'out_var', 'out_foreign_var', 'od_var'}), + ({'group': 'example_group'}, {'out_var'}), + ({'func': lambda var: ( + var.metadata['var_type'] != VarType.GROUP and + var.metadata['intent'] != VarIntent.OUT)}, + {'in_var', 'inout_var', 'in_foreign_var', 'in_foreign_var2', + 'in_foreign_od_var'}) +]) +def test_filter_variables(kwargs, expected): + assert set(filter_variables(ExampleProcess, **kwargs)) == expected - def test_constructor(self, process): - # test dict-like vs. attribute access - assert process['var'] is process._variables['var'] - assert process.var is process._variables['var'] - # test deep copy variable objects - ExampleProcess._variables['var'].state = 2 - assert process._variables['var'].state != ( - ExampleProcess._variables['var'].state) +@pytest.mark.parametrize('var_name,expected_p_cls,expected_var_name', [ + ('in_var', ExampleProcess, 'in_var'), + ('in_foreign_var', SomeProcess, 'some_var'), + ('in_foreign_var2', SomeProcess, 'some_var') # test foreign of foreign +]) +def test_get_target_variable(var_name, expected_p_cls, expected_var_name): + var = variables_dict(ExampleProcess)[var_name] + expected_var = variables_dict(expected_p_cls)[expected_var_name] - # test assign process to diagnostics - assert process['diag']._process_obj is process + actual_p_cls, actual_var = get_target_variable(var) - def test_clone(self, process): - cloned_process = process.clone() - assert process['var'] is not cloned_process['var'] + if expected_p_cls is ExampleProcess: + assert actual_p_cls is None + else: + assert actual_p_cls is expected_p_cls - def test_variables(self, process): - assert set(['var', 'var_list', 'var_group', 'diag']) == ( - set(process.variables.keys())) + assert actual_var is expected_var - def test_meta(self, process): - assert process.meta == {'time_dependent': False} - def test_name(self, process): - assert process.name == "ExampleProcess" +@pytest.mark.parametrize('p_cls,var_name,prop_is_read_only', [ + (ExampleProcess, 'in_var', True), + (ExampleProcess, 'in_foreign_var', True), + (ExampleProcess, 'group_var', True), + (ExampleProcess, 'od_var', True), + (ExampleProcess, 'inout_var', False), + (ExampleProcess, 'out_var', False), + (ExampleProcess, 'out_foreign_var', False) +]) +def test_process_properties_readonly(p_cls, var_name, prop_is_read_only): + if prop_is_read_only: + assert getattr(p_cls, var_name).fset is None + else: + assert getattr(p_cls, var_name).fset is not None - process._name = "my_process" - assert process.name == "my_process" - def test_run_step(self, process): - with pytest.raises(NotImplementedError) as excinfo: - process.run_step(1) - assert "no method" in str(excinfo.value) +def test_process_properties_errors(): + with pytest.raises(ValueError) as excinfo: + @xs.process + class Process1(object): + invalid_var = xs.foreign(ExampleProcess, 'group_var') - def test_info(self, process, process_repr): - for cls_or_obj in [ExampleProcess, process]: - buf = StringIO() - cls_or_obj.info(buf=buf) - actual = buf.getvalue() - assert actual == process_repr + assert "links to group variable" in str(excinfo.value) - class EmptyProcess(Process): + with pytest.raises(ValueError) as excinfo: + @xs.process + class Process2(object): + invalid_var = xs.foreign(ExampleProcess, 'out_var', intent='out') + + assert "both have intent='out'" in str(excinfo.value) + + with pytest.raises(KeyError) as excinfo: + @xs.process + class Process3(object): + var = xs.on_demand() + + assert "No compute method found" in str(excinfo.value) + + +def test_process_properties_docstrings(in_var_details): + # order of lines in string is not ensured (printed from a dictionary) + to_lines = lambda details_str: sorted(details_str.split('\n')) + + assert to_lines(ExampleProcess.in_var.__doc__) == to_lines(in_var_details) + + +def test_process_properties_values(processes_with_store): + some_process, another_process, example_process = processes_with_store + + assert example_process.od_var == 0 + assert example_process.in_foreign_od_var == 1 + + example_process.inout_var = 2 + assert example_process.inout_var == 2 + + example_process.out_foreign_var = 3 + assert another_process.another_var == 3 + + some_process.some_var = 4 + assert another_process.some_var == 4 + assert example_process.in_foreign_var == 4 + assert example_process.in_foreign_var2 == 4 + + assert set(example_process.group_var) == {1, 4} + + +def test_process_decorator(): + with pytest.raises(NotImplementedError): + @xs.process(autodoc=True) + class Dummy(object): pass - expected = dedent("""\ - Variables: - *empty* - Meta: - time_dependent: True""") - - buf = StringIO() - EmptyProcess.info(buf=buf) - actual = buf.getvalue() - assert actual == expected - - def test_repr(self, process, process_repr): - expected = '\n'.join( - ["", - process_repr] - ) - assert repr(process) == expected + +def test_process_info(example_process_obj, example_process_repr): + buf = StringIO() + process_info(example_process_obj, buf=buf) + + assert buf.getvalue() == example_process_repr + + +def test_variable_info(in_var_details): + buf = StringIO() + variable_info(ExampleProcess, 'in_var', buf=buf) + + # order of lines in string is not ensured (printed from a dictionary) + to_lines = lambda details_str: sorted(details_str.split('\n')) + + assert to_lines(buf.getvalue()) == to_lines(in_var_details) diff --git a/xsimlab/tests/test_stores.py b/xsimlab/tests/test_stores.py new file mode 100644 index 00000000..8939d494 --- /dev/null +++ b/xsimlab/tests/test_stores.py @@ -0,0 +1,19 @@ +import numpy as np +from numpy.testing import assert_array_equal + +from xsimlab.stores import InMemoryOutputStore + + +def test_in_memory_output_store(): + out_store = InMemoryOutputStore() + key = ('some_process', 'some_var') + + arr = np.array([1, 2, 3]) + out_store.append(key, arr) + arr[:] = [4, 5, 6] + out_store.append(key, arr) + + expected = np.array([[1, 2, 3], + [4, 5, 6]]) + + assert_array_equal(out_store[key], expected) diff --git a/xsimlab/tests/test_utils.py b/xsimlab/tests/test_utils.py index 89633d93..ce3f651e 100644 --- a/xsimlab/tests/test_utils.py +++ b/xsimlab/tests/test_utils.py @@ -1,6 +1,25 @@ +import attr import pytest from xsimlab import utils +from xsimlab.tests.fixture_process import ExampleProcess + + +def test_variables_dict(): + assert all([isinstance(var, attr.Attribute) + for var in utils.variables_dict(ExampleProcess).values()]) + + assert 'other_attrib' not in utils.variables_dict(ExampleProcess) + + +def test_has_method(): + assert utils.has_method(ExampleProcess(), 'compute_od_var') + assert not utils.has_method(ExampleProcess(), 'invalid_meth') + + +def test_maybe_to_list(): + assert utils.maybe_to_list([1]) == [1] + assert utils.maybe_to_list(1) == [1] def test_import_required(): diff --git a/xsimlab/tests/test_variable.py b/xsimlab/tests/test_variable.py index 1d85bd42..e1965677 100644 --- a/xsimlab/tests/test_variable.py +++ b/xsimlab/tests/test_variable.py @@ -1,247 +1,34 @@ -from collections import OrderedDict - import pytest -import xarray as xr - -from xsimlab.variable.base import (Variable, ForeignVariable, - DiagnosticVariable, VariableList, - ValidationError) -from xsimlab.variable.custom import (NumberVariable, FloatVariable, - IntegerVariable) -from xsimlab.tests.conftest import SomeProcess, OtherProcess, Quantity - - -class TestVariable(object): - - def test_constructor(self): - # verify allowed_dims - for allowed_dims in (tuple(), list(), ''): - var = Variable(allowed_dims) - assert var.allowed_dims == ((),) - - for allowed_dims in ('x', ['x'], ('x')): - var = Variable(allowed_dims) - assert var.allowed_dims == (('x',),) - - var = Variable(('x', 'y')) - assert var.allowed_dims == (('x', 'y'),) - - var = Variable([(), 'x', ('x', 'y')]) - assert var.allowed_dims == ((), ('x',), ('x', 'y')) - - def test_validators(self): - # verify default validators + user supplied validators - validator_func = lambda xr_var: xr_var is not None - - class MyVariable(Variable): - default_validators = [validator_func] - - var = MyVariable((), validators=[validator_func]) - assert var.validators == [validator_func, validator_func] - - def test_validate_dimensions(self): - var = Variable([(), 'x', ('x', 'y')]) - - with pytest.raises(ValidationError) as excinfo: - var.validate_dimensions(('x', 'z')) - assert 'invalid dimensions' in str(excinfo.value) - - var.validate_dimensions(('time', 'x'), ignore_dims=['time']) - - def test_to_xarray_variable(self): - attrs = {'units': 'm'} - description = 'x var' - xr_var_attrs = attrs.copy() - xr_var_attrs.update({'description': description}) - - var = Variable('x', description=description, attrs=attrs) - xr_var = var.to_xarray_variable(('x', [1, 2])) - expected_xr_var = xr.Variable('x', data=[1, 2], attrs=xr_var_attrs) - xr.testing.assert_identical(xr_var, expected_xr_var) - - var = Variable((), default_value=1) - - xr_var = var.to_xarray_variable(2) - expected_xr_var = xr.Variable((), data=2) - xr.testing.assert_identical(xr_var, expected_xr_var) - - # test default value - xr_var = var.to_xarray_variable(None) - expected_xr_var = xr.Variable((), data=1) - xr.testing.assert_identical(xr_var, expected_xr_var) - - # test variable name - xr_var = var.to_xarray_variable([1, 2]) - expected_xr_var = xr.Variable('this_variable', data=[1, 2]) - expected_xr_var = expected_xr_var.to_index_variable() - xr.testing.assert_identical(xr_var, expected_xr_var) - - def test_repr(self): - var = Variable([(), 'x', ('x', 'y')]) - expected_repr = "" - assert repr(var) == expected_repr - - -class TestForeignVariable(object): - - @pytest.fixture - def some_process(self): - """A instance of the process in which the original variable is - declared. - """ - return SomeProcess() - - @pytest.fixture - def foreign_var_cls(self): - """A foreign variable with no Process instance assigned.""" - return ForeignVariable(SomeProcess, 'some_param') - - @pytest.fixture - def foreign_var(self, some_process): - """A foreign variable with an assigned instance of SomeProcess.""" - fvar = ForeignVariable(SomeProcess, 'some_param') - fvar._other_process_obj = some_process - return fvar - - def test_ref_process(self, foreign_var, foreign_var_cls, some_process): - assert foreign_var.ref_process is some_process - assert foreign_var_cls.ref_process is SomeProcess - - def test_ref_var(self, foreign_var, some_process): - assert foreign_var.ref_var is some_process.some_param - - def test_properties(self, foreign_var, some_process): - for prop in ('state', 'value', 'rate', 'change'): - # test foreign getter - setattr(some_process.some_param, prop, 1) - assert getattr(foreign_var, prop) == 1 - - # test foreign setter - setattr(foreign_var, prop, 2) - assert getattr(some_process.some_param, prop) == 2 - - def test_repr(self, foreign_var, foreign_var_cls): - expected_repr = "" - assert repr(foreign_var) == expected_repr - assert repr(foreign_var_cls) == expected_repr - - -class TestDiagnosticVariable(object): - - @pytest.fixture - def quantity(self): - """An instance of the Quantity process that defines some diagnostics.""" - proc = Quantity() - proc.some_derived_quantity.assign_process_obj(proc) - proc.other_derived_quantity.assign_process_obj(proc) - return proc - - def test_decorator(self, quantity): - assert isinstance(quantity.some_derived_quantity, DiagnosticVariable) - assert isinstance(quantity.other_derived_quantity, DiagnosticVariable) - - assert quantity.some_derived_quantity.description == ( - "some derived quantity.") - assert quantity.other_derived_quantity.attrs == {'units': 'm'} - - def test_state(self, quantity): - assert quantity.some_derived_quantity.state == 1 - assert quantity.other_derived_quantity.state == 2 - - def test_call(self, quantity): - assert quantity.some_derived_quantity() == 1 - assert quantity.other_derived_quantity() == 2 - - def test_repr(self, quantity): - expected_repr = "" - assert repr(quantity.some_derived_quantity) == expected_repr - assert repr(quantity.other_derived_quantity) == expected_repr - - -class TestVariableList(object): - - def test_constructor(self): - var_list = VariableList([Variable(()), Variable(('x'))]) - assert isinstance(var_list, tuple) - - with pytest.raises(ValueError) as excinfo: - _ = VariableList([2, Variable(())]) - assert "found variables mixed" in str(excinfo.value) - - -class TestVariableGroup(object): - - def test_iter(self): - some_process = SomeProcess() - other_process = OtherProcess() - quantity = Quantity() - - with pytest.raises(ValueError) as excinfo: - _ = list(quantity.all_effects) - assert "cannot retrieve variables" in str(excinfo.value) - - processes_dict = OrderedDict([('some_process', some_process), - ('other_process', other_process), - ('quantity', quantity)]) - quantity.all_effects._set_variables(processes_dict) - - expected = [some_process.some_effect, other_process.other_effect] - for var, proc in zip(quantity.all_effects, processes_dict.values()): - var._other_process_obj = proc - - fvar_list = [var.ref_var for var in quantity.all_effects] - assert fvar_list == expected - - def test_repr(self): - quantity = Quantity() - - expected_repr = "" - assert repr(quantity.all_effects) == expected_repr - - -class TestNumberVariable(object): - - def test_validate(self): - var = NumberVariable((), bounds=(0, 1)) - for data in (-1, [-1, 0], [-1, 1], [0, 2], 2): - xr_var = var.to_xarray_variable(data) - with pytest.raises(ValidationError) as excinfo: - var.validate(xr_var) - assert "out of bounds" in str(excinfo.value) - - for ib in [(True, False), (False, True), (False, False)]: - var = NumberVariable((), bounds=(0, 1), inclusive_bounds=ib) - xr_var = var.to_xarray_variable([0, 1]) - with pytest.raises(ValidationError) as excinfo: - var.validate(xr_var) - assert "out of bounds" in str(excinfo.value) - -class TestFloatVariable(object): +from xsimlab.tests.fixture_process import ExampleProcess +from xsimlab.variable import _as_dim_tuple, foreign - def test_validators(self): - var = FloatVariable(()) - for val in [1, 1.]: - xr_var = xr.Variable((), val) - var.run_validators(xr_var) +@pytest.mark.parametrize("dims,expected", [ + ((), ((),)), + ([], ((),)), + ('', ((),)), + (('x'), (('x',),)), + (['x'], (('x',),)), + ('x', (('x',),)), + (('x', 'y'), (('x', 'y'),)), + ([(), 'x', ('x', 'y')], ((), ('x',), ('x', 'y'))) +]) +def test_as_dim_tuple(dims, expected): + assert _as_dim_tuple(dims) == expected - xr_var = xr.Variable((), '1') - with pytest.raises(ValidationError) as excinfo: - var.run_validators(xr_var) - assert "invalid dtype" in str(excinfo.value) +def test_as_dim_tuple_invalid(): + invalid_dims = ['x', 'y', ('x', 'y'), ('y', 'x')] -class TestIntegerVariable(object): + with pytest.raises(ValueError) as excinfo: + _as_dim_tuple(invalid_dims) + assert "following combinations" in str(excinfo) + assert "('x',), ('y',) and ('x', 'y'), ('y', 'x')" in str(excinfo) - def test_validators(self): - var = IntegerVariable(()) - xr_var = xr.Variable((), 1) - var.run_validators(xr_var) +def test_foreign(): + with pytest.raises(ValueError) as excinfo: + foreign(ExampleProcess, 'some_var', intent='inout') - for val in [1., '1']: - xr_var = xr.Variable((), val) - with pytest.raises(ValidationError) as excinfo: - var.run_validators(xr_var) - assert "invalid dtype" in str(excinfo.value) + assert "intent='inout' is not supported" in str(excinfo.value) diff --git a/xsimlab/tests/test_xr_accessor.py b/xsimlab/tests/test_xr_accessor.py index 49ecd0dc..2e259059 100644 --- a/xsimlab/tests/test_xr_accessor.py +++ b/xsimlab/tests/test_xr_accessor.py @@ -3,7 +3,9 @@ import numpy as np from xsimlab import xr_accessor, create_setup -from xsimlab.xr_accessor import _maybe_get_model_from_context +from xsimlab.xr_accessor import (as_variable_key, + _flatten_inputs, _flatten_outputs, + _maybe_get_model_from_context) def test_filter_accessor(): @@ -14,11 +16,66 @@ def test_filter_accessor(): assert 'x' in filtered.coords and 'y' not in filtered.coords +def test_get_model_from_context(model): + with pytest.raises(TypeError) as excinfo: + _maybe_get_model_from_context(None) + assert "No model found in context" in str(excinfo.value) + + with model as m: + assert _maybe_get_model_from_context(None) is m + + with pytest.raises(TypeError) as excinfo: + _maybe_get_model_from_context('not a model') + assert "is not an instance of xsimlab.Model" in str(excinfo.value) + + +def test_as_variable_key(): + assert as_variable_key(('foo', 'bar')) == ('foo', 'bar') + assert as_variable_key('foo__bar') == ('foo', 'bar') + assert as_variable_key('foo_bar__baz') == ('foo_bar', 'baz') + + with pytest.raises(ValueError) as excinfo: + as_variable_key('foo__bar__baz') + assert "not a valid input variable" in str(excinfo.value) + + with pytest.raises(ValueError) as excinfo: + as_variable_key('foo__') + assert "not a valid input variable" in str(excinfo.value) + + +@pytest.mark.parametrize('input_vars,expected', [ + ({('foo', 'bar'): 1}, {('foo', 'bar'): 1}), + ({'foo__bar': 1}, {('foo', 'bar'): 1}), + ({'foo': {'bar': 1}}, {('foo', 'bar'): 1}) +]) +def test_flatten_inputs(input_vars, expected): + assert _flatten_inputs(input_vars) == expected + + +@pytest.mark.parametrize('output_vars,expected', [ + ({'clock': 'foo__bar'}, {'clock': [('foo', 'bar')]}), + ({'clock': ('foo', 'bar')}, {'clock': [('foo', 'bar')]}), + ({'clock': [('foo', 'bar')]}, {'clock': [('foo', 'bar')]}), + ({'clock': [('foo__bar')]}, {'clock': [('foo', 'bar')]}), + ({'clock': {'foo': 'bar'}}, {'clock': [('foo', 'bar')]}), + ({'clock': {'foo': ['bar', 'baz']}}, + {'clock': [('foo', 'bar'), ('foo', 'baz')]}) +]) +def test_flatten_outputs(output_vars, expected): + assert _flatten_outputs(output_vars) == expected + + +def test_flatten_outputs_error(): + with pytest.raises(ValueError) as excinfo: + _flatten_outputs({'clock': 2}) + assert "Cannot interpret" in str(excinfo.value) + + class TestSimlabAccessor(object): _clock_key = xr_accessor.SimlabAccessor._clock_key _master_clock_key = xr_accessor.SimlabAccessor._master_clock_key - _snapshot_vars_key = xr_accessor.SimlabAccessor._snapshot_vars_key + _output_vars_key = xr_accessor.SimlabAccessor._output_vars_key def test_clock_coords(self): ds = xr.Dataset( @@ -125,42 +182,25 @@ def test_set_snapshot_clock(self): ds.xsimlab._set_snapshot_clock('snap_clock', data=[0, 3, 8], auto_adjust=False) - def test_set_input_vars(self, model): - ds = xr.Dataset() + def test_set_input_vars(self, model, in_dataset): + in_vars = {('init_profile', 'n_points'): 5, + ('roll', 'shift'): 1, + ('add', 'offset'): ('clock', [1, 2, 3, 4, 5])} - with pytest.raises(KeyError) as excinfo: - ds.xsimlab._set_input_vars(model, 'invalid_process', var=1) - assert "no process named" in str(excinfo.value) + ds = xr.Dataset(coords={'clock': [0, 2, 4, 6, 8]}) + ds.xsimlab._set_input_vars(model, in_vars) - with pytest.raises(ValueError) as excinfo: - ds.xsimlab._set_input_vars(model, 'some_process', some_param=0, - invalid_var=1) - assert "not valid input variables" in str(excinfo.value) - - ds.xsimlab._set_input_vars(model, 'quantity', - quantity=('x', np.zeros(10))) - expected = xr.DataArray(data=np.zeros(10), dims='x') - assert "quantity__quantity" in ds - xr.testing.assert_equal(ds['quantity__quantity'], expected) - - # test time and parameter dimensions - ds.xsimlab._set_input_vars(model, model.some_process, some_param=[1, 2]) - expected = xr.DataArray(data=[1, 2], dims='some_process__some_param', - coords={'some_process__some_param': [1, 2]}) - xr.testing.assert_equal(ds['some_process__some_param'], expected) - del ds['some_process__some_param'] - - ds['clock'] = ('clock', [0, 1], {self._master_clock_key: 1}) - ds.xsimlab._set_input_vars(model, 'some_process', - some_param=('clock', [1, 2])) - expected = xr.DataArray(data=[1, 2], dims='clock', - coords={'clock': [0, 1]}) - xr.testing.assert_equal(ds['some_process__some_param'], expected) - - # test optional - ds.xsimlab._set_input_vars(model, 'grid') - expected = xr.DataArray(data=5) - xr.testing.assert_equal(ds['grid__x_size'], expected) + for vname in ('init_profile__n_points', 'roll__shift', 'add__offset'): + # xr.testing.assert_identical also checks attrs of coordinates + # (not needed here) + xr.testing.assert_equal(ds[vname], in_dataset[vname]) + assert ds[vname].attrs == in_dataset[vname].attrs + + in_vars[('not_an', 'input_var')] = None + + with pytest.raises(KeyError) as excinfo: + ds.xsimlab._set_input_vars(model, in_vars) + assert "not valid key(s)" in str(excinfo.value) def test_update_clocks(self, model): ds = xr.Dataset() @@ -193,7 +233,7 @@ def test_update_clocks(self, model): ) assert ds.xsimlab.master_clock_dim == 'clock' - ds.clock.attrs[self._snapshot_vars_key] = 'quantity__quantity' + ds.clock.attrs[self._output_vars_key] = 'profile__u' ds = ds.xsimlab.update_clocks( model=model, @@ -204,91 +244,78 @@ def test_update_clocks(self, model): ) assert 'units' in ds.clock.attrs assert 'calendar' in ds.clock.attrs - assert ds.clock.attrs[self._snapshot_vars_key] == 'quantity__quantity' + assert ds.clock.attrs[self._output_vars_key] == 'profile__u' - def test_update_vars(self, model, input_dataset): - ds = input_dataset.xsimlab.update_vars( + def test_update_vars(self, model, in_dataset): + ds = in_dataset.xsimlab.update_vars( model=model, - input_vars={'some_process': {'some_param': 2}}, - snapshot_vars={'out': {'other_process': 'other_effect'}} + input_vars={('roll', 'shift'): 2}, + output_vars={'out': ('profile', 'u')} ) - var = 'some_process__some_param' - assert not ds[var].equals(input_dataset[var]) - assert not ds['out'].identical(input_dataset['out']) - def test_filter_vars(self, model, input_dataset): - alt_model = model.drop_processes(['other_process']) + assert not ds['roll__shift'].equals(in_dataset['roll__shift']) + assert not ds['out'].identical(in_dataset['out']) - ds = input_dataset.xsimlab.filter_vars(model=alt_model) - assert 'other_process__other_param' not in ds - assert sorted(ds.xsimlab.clock_coords) == ['clock', 'out'] - expected = 'some_process__some_effect' - assert ds.out.attrs[self._snapshot_vars_key] == expected + def test_filter_vars(self, simple_model, in_dataset): + in_dataset['not_a_xsimlab_model_input'] = 1 - def test_set_snapshot_vars(self, model): + filtered_ds = in_dataset.xsimlab.filter_vars(model=simple_model) + + assert 'add__offset' not in filtered_ds + assert 'not_a_xsimlab_model_input' not in filtered_ds + assert sorted(filtered_ds.xsimlab.clock_coords) == ['clock', 'out'] + assert filtered_ds.out.attrs[self._output_vars_key] == 'roll__u_diff' + + def test_set_output_vars(self, model): ds = xr.Dataset() ds['clock'] = ('clock', [0, 2, 4, 6, 8], {self._clock_key: 1, self._master_clock_key: 1}) - ds['snap_clock'] = ('snap_clock', [0, 4, 8], {self._clock_key: 1}) + ds['out'] = ('out', [0, 4, 8], {self._clock_key: 1}) ds['not_a_clock'] = ('not_a_clock', [0, 1]) with pytest.raises(KeyError) as excinfo: - ds.xsimlab._set_snapshot_vars(model, None, invalid_process='var') - assert "no process named" in str(excinfo.value) - - with pytest.raises(KeyError) as excinfo: - ds.xsimlab._set_snapshot_vars(model, None, quantity='invalid_var') - assert "has no variable" in str(excinfo.value) - - ds.xsimlab._set_snapshot_vars(model, None, grid='x') - assert ds.attrs[self._snapshot_vars_key] == 'grid__x' + ds.xsimlab._set_output_vars(model, None, [('invalid', 'var')]) + assert "not valid key(s)" in str(excinfo.value) - ds.xsimlab._set_snapshot_vars(model, 'clock', - some_process='some_effect', - quantity='quantity') - expected = {'some_process__some_effect', 'quantity__quantity'} - actual = set(ds['clock'].attrs[self._snapshot_vars_key].split(',')) - assert actual == expected + ds.xsimlab._set_output_vars(model, None, [('profile', 'u_opp')]) + assert ds.attrs[self._output_vars_key] == 'profile__u_opp' - ds.xsimlab._set_snapshot_vars(model, 'snap_clock', - other_process=('other_effect', 'x2')) - expected = {'other_process__other_effect', 'other_process__x2'} - actual = set(ds['snap_clock'].attrs[self._snapshot_vars_key].split(',')) - assert actual == expected + ds.xsimlab._set_output_vars(model, 'out', + [('roll', 'u_diff'), ('add', 'u_diff')]) + expected = 'roll__u_diff,add__u_diff' + assert ds['out'].attrs[self._output_vars_key] == expected with pytest.raises(ValueError) as excinfo: - ds.xsimlab._set_snapshot_vars(model, 'not_a_clock', - quantity='quantity') + ds.xsimlab._set_output_vars(model, 'not_a_clock', + [('profile', 'u')]) assert "not a valid clock" in str(excinfo.value) - def test_snapshot_vars(self, model): + def test_output_vars(self, model): ds = xr.Dataset() ds['clock'] = ('clock', [0, 2, 4, 6, 8], {self._clock_key: 1, self._master_clock_key: 1}) - ds['snap_clock'] = ('snap_clock', [0, 4, 8], {self._clock_key: 1}) - # snapshot clock with no snapshot variable (attribute) set - ds['snap_clock2'] = ('snap_clock2', [0, 8], {self._clock_key: 1}) - - ds.xsimlab._set_snapshot_vars(model, None, grid='x') - ds.xsimlab._set_snapshot_vars(model, 'clock', quantity='quantity') - ds.xsimlab._set_snapshot_vars(model, 'snap_clock', - other_process=('other_effect', 'x2')) - - expected = {None: set([('grid', 'x')]), - 'clock': set([('quantity', 'quantity')]), - 'snap_clock': set([('other_process', 'other_effect'), - ('other_process', 'x2')])} - actual = {k: set(v) for k, v in ds.xsimlab.snapshot_vars.items()} - assert actual == expected - - def test_run(self, model, input_dataset): - # safe mode True: model cloned -> values not set in original model - _ = input_dataset.xsimlab.run(model=model) - assert model.quantity.quantity.value is None - - # safe mode False: model not cloned -> values set in original model - _ = input_dataset.xsimlab.run(model=model, safe_mode=False) - assert model.quantity.quantity.value is not None + ds['out'] = ('out', [0, 4, 8], {self._clock_key: 1}) + # snapshot clock with no output variable (attribute) set + ds['out2'] = ('out2', [0, 8], {self._clock_key: 1}) + + ds.xsimlab._set_output_vars(model, None, [('profile', 'u_opp')]) + ds.xsimlab._set_output_vars(model, 'clock', [('profile', 'u')]) + ds.xsimlab._set_output_vars(model, 'out', + [('roll', 'u_diff'), ('add', 'u_diff')]) + + expected = {None: [('profile', 'u_opp')], + 'clock': [('profile', 'u')], + 'out': [('roll', 'u_diff'), ('add', 'u_diff')]} + assert ds.xsimlab.output_vars == expected + + def test_run(self, model, in_dataset): + # safe mode True: ensure model is cloned + _ = in_dataset.xsimlab.run(model=model, safe_mode=True) + assert model.profile.__xsimlab_store__ is None + + # safe mode False: model not cloned -> original model is used + _ = in_dataset.xsimlab.run(model=model, safe_mode=False) + assert model.profile.u is not None def test_run_multi(self): ds = xr.Dataset() @@ -297,7 +324,7 @@ def test_run_multi(self): ds.xsimlab.run_multi() -def test_create_setup(model, input_dataset): +def test_create_setup(model, in_dataset): expected = xr.Dataset() actual = create_setup(model=model) xr.testing.assert_identical(actual, expected) @@ -305,33 +332,18 @@ def test_create_setup(model, input_dataset): ds = create_setup( model=model, input_vars={ - 'grid': {'x_size': 10}, - 'quantity': {'quantity': ('x', np.zeros(10))}, - 'some_process': {'some_param': 1}, - 'other_process': {'other_param': ('clock', [1, 2, 3, 4, 5])} + 'init_profile': {'n_points': 5}, + ('roll', 'shift'): 1, + 'add__offset': ('clock', [1, 2, 3, 4, 5]) }, clocks={ 'clock': {'data': [0, 2, 4, 6, 8]}, 'out': {'data': [0, 4, 8]}, }, master_clock='clock', - snapshot_vars={ - 'clock': {'quantity': 'quantity'}, - 'out': {'some_process': 'some_effect', - 'other_process': 'other_effect'}, - None: {'grid': 'x'} + output_vars={ + 'clock': 'profile__u', + 'out': [('roll', 'u_diff'), ('add', 'u_diff')], + None: {'profile': 'u_opp'} }) - xr.testing.assert_identical(ds, input_dataset) - - -def test_get_model_from_context(model): - with pytest.raises(TypeError) as excinfo: - _maybe_get_model_from_context(None) - assert "no model found in context" in str(excinfo.value) - - with model as m: - assert _maybe_get_model_from_context(None) is m - - with pytest.raises(TypeError) as excinfo: - _maybe_get_model_from_context('not a model') - assert "is not an instance of xsimlab.Model" in str(excinfo.value) + xr.testing.assert_identical(ds, in_dataset) diff --git a/xsimlab/tests/test_xr_interface.py b/xsimlab/tests/test_xr_interface.py deleted file mode 100644 index 73f977ad..00000000 --- a/xsimlab/tests/test_xr_interface.py +++ /dev/null @@ -1,132 +0,0 @@ -import pytest - -import numpy as np -import xarray as xr - -from xsimlab.xr_accessor import SimlabAccessor -from xsimlab.xr_interface import DatasetModelInterface - - -class TestDatasetModelInterface(object): - - def test_constructor(self, model, input_dataset): - ds = xr.Dataset() - with pytest.raises(ValueError) as excinfo: - DatasetModelInterface(model, ds) - assert "missing master clock dimension" in str(excinfo.value) - - invalid_ds = input_dataset.drop('quantity__quantity') - with pytest.raises(KeyError) as excinfo: - DatasetModelInterface(model, invalid_ds) - assert "missing data variables" in str(excinfo.value) - - def test_set_model_inputs(self, input_dataset, ds_model_interface): - ds = input_dataset.drop('other_process__other_param') - ds_model_interface.set_model_inputs(ds) - model = ds_model_interface.model - - assert model.grid.x_size.value == 10 - np.testing.assert_array_equal(model.quantity.quantity.value, - np.zeros(10)) - assert model.some_process.some_param.value == 1 - assert model.other_process.other_param.value is None - - def test_split_data_vars_clock(self, ds_model_interface): - ds_clock, ds_no_clock = ds_model_interface.split_data_vars_clock() - assert 'other_process__other_param' in ds_clock - assert 'other_process__other_param' not in ds_no_clock - - def test_time_step_lengths(self, ds_model_interface): - np.testing.assert_array_equal(ds_model_interface.time_step_lengths, - [2, 2, 2, 2]) - - def test_init_snapshots(self, ds_model_interface): - ds_model_interface.init_snapshots() - - expected = {('quantity', 'quantity'), ('some_process', 'some_effect'), - ('other_process', 'other_effect'), ('grid', 'x')} - assert set(ds_model_interface.snapshot_values) == expected - - expected = {'clock': np.array([True, True, True, True, True]), - 'out': np.array([True, False, True, False, True])} - assert ds_model_interface.snapshot_save.keys() == expected.keys() - for k in expected: - np.testing.assert_array_equal(ds_model_interface.snapshot_save[k], - expected[k]) - - def test_take_snapshot_var(self, ds_model_interface): - ds_model_interface.init_snapshots() - ds_model_interface.set_model_inputs(ds_model_interface.dataset) - - key = ('quantity', 'quantity') - ds_model_interface.take_snapshot_var(key) - expected = np.zeros(10) - actual = ds_model_interface.snapshot_values[key][0] - np.testing.assert_array_equal(actual, expected) - - # ensure snapshot array is a copy - actual[0] = 1 - assert actual[0] != ds_model_interface.model.quantity.quantity.value[0] - - @pytest.mark.parametrize( - 'istep,expected_len', - [(0, [1, 1, 1, 0]), (1, [1, 0, 0, 0]), (-1, [1, 1, 1, 1])] - ) - def test_take_snapshots(self, ds_model_interface, istep, expected_len): - ds_model_interface.init_snapshots() - ds_model_interface.set_model_inputs(ds_model_interface.dataset) - - keys = [('quantity', 'quantity'), ('some_process', 'some_effect'), - ('other_process', 'other_effect'), ('grid', 'x')] - - ds_model_interface.take_snapshots(istep) - for k, length in zip(keys, expected_len): - assert len(ds_model_interface.snapshot_values[k]) == length - - def test_snapshot_to_xarray_variable(self, ds_model_interface): - ds_model_interface.init_snapshots() - ds_model_interface.set_model_inputs(ds_model_interface.dataset) - ds_model_interface.model.initialize() - - ds_model_interface.take_snapshots(0) - - expected = xr.Variable('x', np.zeros(10), - {'description': 'a quantity'}) - actual = ds_model_interface.snapshot_to_xarray_variable( - ('quantity', 'quantity'), clock='clock') - xr.testing.assert_identical(actual, expected) - - ds_model_interface.take_snapshots(-1) - - expected = xr.Variable(('clock', 'x'), np.zeros((2, 10))) - actual = ds_model_interface.snapshot_to_xarray_variable( - ('quantity', 'quantity'), clock='clock') - xr.testing.assert_equal(actual, expected) - - expected = xr.Variable('x', np.arange(10)) - actual = ds_model_interface.snapshot_to_xarray_variable(('grid', 'x')) - xr.testing.assert_equal(actual, expected) - - def test_run_model(self, input_dataset, ds_model_interface): - out_ds = ds_model_interface.run_model() - - expected = input_dataset.copy() - del expected.attrs[SimlabAccessor._snapshot_vars_key] - del expected.clock.attrs[SimlabAccessor._snapshot_vars_key] - del expected.out.attrs[SimlabAccessor._snapshot_vars_key] - expected['grid__x'] = ('x', np.arange(10), {'description': ''}) - expected['quantity__quantity'] = ( - ('clock', 'x'), - np.arange(0, 10, 2)[:, None] * np.arange(10) * 1., - {'description': 'a quantity'} - ) - expected['some_process__some_effect'] = ( - ('out', 'x'), np.tile(np.arange(2, 12), 3).reshape(3, 10), - {'description': ''} - ) - expected['other_process__other_effect'] = ( - ('out', 'x'), np.tile(np.arange(-2, 8), 3).reshape(3, 10), - {'description': ''} - ) - - xr.testing.assert_identical(out_ds, expected) diff --git a/xsimlab/utils.py b/xsimlab/utils.py index f13d56a5..67dab1e5 100644 --- a/xsimlab/utils.py +++ b/xsimlab/utils.py @@ -3,11 +3,31 @@ """ import threading -from collections import Mapping, KeysView, ItemsView, ValuesView -from functools import wraps +from collections import (Mapping, KeysView, ItemsView, ValuesView, + OrderedDict) from contextlib import suppress from importlib import import_module +from attr import fields_dict + + +def variables_dict(process_cls): + """Get all xsimlab variables declared in a process. + + Exclude attr.Attribute objects that are not xsimlab-specific. + """ + return OrderedDict((k, v) + for k, v in fields_dict(process_cls).items() + if 'var_type' in v.metadata) + + +def has_method(obj, meth): + return callable(getattr(obj, meth, False)) + + +def maybe_to_list(obj): + return obj if isinstance(obj, list) else [obj] + def import_required(mod_name, error_msg): """Attempt to import a required dependency. @@ -19,20 +39,6 @@ def import_required(mod_name, error_msg): raise RuntimeError(error_msg) -class combomethod(object): - def __init__(self, method): - self.method = method - - def __get__(self, obj=None, objtype=None): - @wraps(self.method) - def _wrapper(*args, **kwargs): - if obj is not None: - return self.method(obj, *args, **kwargs) - else: - return self.method(objtype, *args, **kwargs) - return _wrapper - - class AttrMapping(object): """A class similar to `collections.abc.Mapping`, which also allows getting keys with attribute access. @@ -52,6 +58,7 @@ class AttrMapping(object): https://www.python.org/ """ + # TODO: use abc.ABCMeta now that metaclasses are not used anymore? _initialized = False def __init__(self, mapping=None): diff --git a/xsimlab/variable.py b/xsimlab/variable.py new file mode 100644 index 00000000..99062918 --- /dev/null +++ b/xsimlab/variable.py @@ -0,0 +1,269 @@ +from enum import Enum +import itertools + +import attr +from attr._make import _CountingAttr as CountingAttr_ + + +class VarType(Enum): + VARIABLE = 'variable' + ON_DEMAND = 'on_demand' + FOREIGN = 'foreign' + GROUP = 'group' + + +class VarIntent(Enum): + IN = 'in' + OUT = 'out' + INOUT = 'inout' + + +class _CountingAttr(CountingAttr_): + """A hack to add a custom 'compute' decorator for on-request computation + of on_demand variables. + """ + + def compute(self, method): + self.metadata['compute'] = method + + return method + + +def _as_dim_tuple(dims): + """Return a tuple from one or more combination(s) of dimension labels + given in `dims` either as a tuple, str or list. + + Also ensure that the number of dimensions for each item in the + sequence is unique, e.g., dims=[('x', 'y'), ('y', 'x')] is + ambiguous and thus not allowed. + + """ + if not len(dims): + dims = [()] + elif isinstance(dims, str): + dims = [(dims,)] + elif isinstance(dims, list): + dims = [tuple([d]) if isinstance(d, str) else tuple(d) + for d in dims] + else: + dims = [dims] + + # check ndim uniqueness could be simpler but provides detailed error msg + fget_ndim = lambda dims: len(dims) + dims_sorted = sorted(dims, key=fget_ndim) + ndim_groups = [list(g) + for _, g in itertools.groupby(dims_sorted, fget_ndim)] + + if len(ndim_groups) != len(dims): + invalid_dims = [g for g in ndim_groups if len(g) > 1] + invalid_msg = ' and '.join( + ', '.join(str(d) for d in group) for group in invalid_dims + ) + raise ValueError("the following combinations of dimension labels " + "are ambiguous for a variable: {}" + .format(invalid_msg)) + + return tuple(dims) + + +def variable(dims=(), intent='in', group=None, default=attr.NOTHING, + validator=None, description='', attrs=None): + """Create a variable. + + Variables store useful metadata such as dimension labels, a short + description, a default value, validators or custom, + user-provided metadata. + + Variables are the primitives of the modeling framework, they + define the interface of each process in a model. + + Variables should be declared exclusively as class attributes in + process classes (i.e., classes decorated with :func:`process`). + + Parameters + ---------- + dims : str or tuple or list, optional + Dimension label(s) of the variable. An empty tuple + corresponds to a scalar variable (default), a string or a 1-length + tuple corresponds to a 1-d variable and a n-length tuple corresponds to + a n-d variable. A list of str or tuple items may also be provided if + the variable accepts different numbers of dimensions. + This should not include a time dimension, which may always be added. + intent : {'in', 'out', 'inout'}, optional + Defines whether the variable is an input (i.e., the process needs the + variable's value for its computation), an output (i.e., the process + computes a value for the variable) or both an input/output (i.e., the + process may update the value of the variable). + (default: input). + group : str, optional + Variable group. + default : any, optional + Single default value for the variable, ignored when ``intent='out'`` + (default: NOTHING). A default value may also be set using a decorator. + validator : callable or list of callable, optional + Function that is called at simulation initialization (and possibly at + other times too) to check the value given for the variable. + The function must accept three arguments: + + - the process instance (access other variables) + - the variable object (access metadata) + - a passed value (check input). + + The function is expected to throw an exception in case of invalid + value. + If a ``list`` is passed, its items are treated as validators and must + all pass. + The validator can also be set using decorator notation. + description : str, optional + Short description of the variable. + attrs : dict, optional + Dictionnary of additional metadata (e.g., standard_name, + units, math_symbol...). + + """ + metadata = {'var_type': VarType.VARIABLE, + 'dims': _as_dim_tuple(dims), + 'intent': VarIntent(intent), + 'group': group, + 'attrs': attrs or {}, + 'description': description} + + return attr.attrib(metadata=metadata, default=default, validator=validator, + init=False, cmp=False, repr=False) + + +def on_demand(dims=(), group=None, description='', attrs=None): + """Create a variable that is computed on demand. + + Instead of being computed systematically at every step of a simulation + or at initialization, its value is only computed (or re-computed) + each time when it is needed. + + Like other variables, such variable should be declared in a + process class. Additionally, it requires its own method to compute + its value, which must be defined in the same class and decorated + (e.g., using `@myvar.compute` if the name of the variable is + `myvar`). + + An on-demand variable is always an output variable (i.e., intent='out'). + + Its computation usually involves other variables, although this is + not required. + + These variables may be useful, e.g., for model diagnostics. + + Parameters + ---------- + dims : str or tuple or list, optional + Dimension label(s) of the variable. An empty tuple + corresponds to a scalar variable (default), a string or a 1-length + tuple corresponds to a 1-d variable and a n-length tuple corresponds to + a n-d variable. A list of str or tuple items may also be provided if + the variable accepts different numbers of dimensions. + This should not include a time dimension, which may always be added. + group : str, optional + description : str, optional + Short description of the variable. + attrs : dict, optional + Dictionnary of additional metadata (e.g., standard_name, + units, math_symbol...). + + See Also + -------- + :func:`variable` + + """ + metadata = {'var_type': VarType.ON_DEMAND, + 'dims': _as_dim_tuple(dims), + 'intent': VarIntent.OUT, + 'group': group, + 'attrs': attrs or {}, + 'description': description} + + return _CountingAttr( + default=attr.NOTHING, + validator=None, + repr=False, + cmp=False, + hash=None, + init=False, + converter=None, + metadata=metadata, + type=None, + ) + + +def foreign(other_process_cls, var_name, intent='in'): + """Create a reference to a variable that is defined in another + process class. + + Parameters + ---------- + other_process_cls : class + Class in which the variable is defined. + var_name : str + Name of the corresponding variable declared in `other_process_cls`. + intent : {'in', 'out'}, optional + Defines whether the foreign variable is an input (i.e., the process + needs the variable's value for its computation), an output (i.e., the + process computes a value for the variable). + (default: input). + + See Also + -------- + :func:`variable` + + Notes + ----- + Unlike for :func:`variable`, ``intent='inout'`` is not supported + here (i.e., the process may not update the value of a foreign + variable) as it would result in ambiguous process ordering in a + model. + + """ + if intent == 'inout': + raise ValueError("intent='inout' is not supported for " + "foreign variables") + + description = ("Reference to variable {!r} " + "defined in class {!r}" + .format(var_name, other_process_cls.__name__)) + + metadata = {'var_type': VarType.FOREIGN, + 'other_process_cls': other_process_cls, + 'var_name': var_name, + 'intent': VarIntent(intent), + 'description': description} + + return attr.attrib(metadata=metadata, init=False, cmp=False, repr=False) + + +def group(name): + """Create a special variable which value returns an iterable of values of + variables in a model that all belong to the same group. + + Access to the variable values is read-only (i.e., intent='in'). + + Good examples of using group variables are processes that + aggregate (e.g., sum, product, mean) the values of variables that + are defined in various other processes in a model. + + Parameters + ---------- + group : str + Name of the group. + + See Also + -------- + :func:`variable` + + """ + description = ("Iterable of all variables that " + "belong to group {!r}".format(name)) + + metadata = {'var_type': VarType.GROUP, + 'group': name, + 'intent': VarIntent.IN, + 'description': description} + + return attr.attrib(metadata=metadata, init=False, cmp=False, repr=False) diff --git a/xsimlab/variable/__init__.py b/xsimlab/variable/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/xsimlab/variable/base.py b/xsimlab/variable/base.py deleted file mode 100644 index 3ae11529..00000000 --- a/xsimlab/variable/base.py +++ /dev/null @@ -1,460 +0,0 @@ -# coding: utf-8 -""" -Base classes for Variable objects. - -""" -import itertools -from collections import Iterable, OrderedDict - -from xarray.core.variable import as_variable - - -class ValidationError(ValueError): - """An error while validating data.""" - pass - - -class AbstractVariable(object): - """Abstract class for all variables. - - This class aims at providing a common parent class - for all regular, diagnostic, foreign and undefined variables. - - """ - def __init__(self, provided=False, description='', attrs=None, - group=None): - self.provided = provided - self.description = description - self.attrs = attrs or {} - self.group = group - - def __repr__(self): - return "" % type(self).__name__ - - -class Variable(AbstractVariable): - """Base class that represents a variable in a process or a model. - - `Variable` objects store useful metadata such as dimension labels, - a short description, a default value or other user-provided metadata. - - Variables allow to convert any given value to a `xarray.Variable` object - after having perfomed some checks. - - In processes, variables are instantiated as class attributes. They - represent fundamental elements of a process interface (see - :class:`Process`) and by extension a model interface. - Some attributes such as `provided` and `optional` also contribute to - the definition of the interface. - - """ - default_validators = [] # Default set of validators - - def __init__(self, allowed_dims, provided=False, optional=False, - default_value=None, validators=(), group=None, - description='', attrs=None): - """ - Parameters - ---------- - allowed_dims : str or tuple or list - Dimension label(s) allowed for the variable. An empty tuple - corresponds to a scalar variable, a string or a 1-length tuple - corresponds to a 1-d variable and a n-length tuple corresponds to a - n-d variable. A list of str or tuple items may also be provided if - the variable accepts different numbers of dimensions. - This should not include a time dimension, which is always allowed. - provided : bool, optional - Defines whether a value for the variable is required (False) - or provided (True) by the process in which it is defined - (default: False). - If `provided=True`, then the variable in a process/model won't - be considered as an input of that process/model. - optional : bool, optional - If True, a value may not be required for the variable - (default: False). Ignored when `provided` is True. - default_value : object, optional - Single default value for the variable (default: None). It - will be automatically broadcasted to all of its dimensions. - Ignored when `provided` is True. - validators : tuple or list, optional - A list of callables that take an `xarray.Variable` object and - raises a `ValidationError` if it doesn’t meet some criteria. - It may be useful for custom, advanced validation that - can be reused for different variables. - group : str, optional - Variable group. - description : str, optional - Short description of the variable (ideally one-line). - attrs : dict, optional - Dictionnary of additional metadata (e.g., standard_name, - units, math_symbol...). - - """ - super(Variable, self).__init__(provided=provided, group=group, - description=description, - attrs=attrs) - - if not len(allowed_dims): - allowed_dims = [()] - elif isinstance(allowed_dims, str): - allowed_dims = [(allowed_dims,)] - elif isinstance(allowed_dims, list): - allowed_dims = [tuple([d]) if isinstance(d, str) else tuple(d) - for d in allowed_dims] - else: - allowed_dims = [allowed_dims] - self.allowed_dims = tuple(allowed_dims) - - self.optional = optional - self.default_value = default_value - self._validators = list(validators) - self._state = None - self._rate = None - self._change = None - - @property - def validators(self): - return list(itertools.chain(self.default_validators, self._validators)) - - def run_validators(self, xr_variable): - for vfunc in self.validators: - vfunc(xr_variable) - - def validate(self, xr_variable): - pass # pragma: no cover - - def validate_dimensions(self, dims, ignore_dims=None): - """Validate given dimensions for this variable. - - Parameters - ---------- - dims : tuple - Dimensions given for the variable. - ignore_dims : tuple, optional - Dimensions that are ignored during the validation process. - Typically, it may correspond to a time dimension (time steps) - and/or a grid-search or parameter-space dimension for this - variable itself. - - Raises - ------ - ValidationError - If the given dimensions are not valid, i.e., if they doesn't - correspond to allowed dimensions for this variable. - - """ - dims_dict = OrderedDict([(d, None) for d in dims]) - - if ignore_dims is not None: - for d in ignore_dims: - dims_dict.pop(d, None) - - clean_dims = tuple(dims_dict) - test_dims = [d for d in self.allowed_dims if d == clean_dims] - - if not test_dims: - raise ValidationError("invalid dimensions %s\n" - "allowed dimensions are %s" - % (dims, self.allowed_dims)) - - def to_xarray_variable(self, value): - """Convert the input value to an `xarray.Variable` object. - - Parameters - ---------- - value : object - The input value can be in the form of a single value, - an array-like, a ``(dims, data[, attrs])`` tuple, another - `xarray.Variable` object or a `xarray.DataArray` object. - if None, the `default_value` attribute is used to set the value. - - Returns - ------- - variable : `xarray.Variable` - A xarray Variable object whith data corresponding to the input (or - default) value and with attributes ('description' and other - key:value pairs found in `Variable.attrs`). - - """ - if value is None: - value = self.default_value - - # in case where value is a 1-d array without dimension name, - # dimension name is set to 'this_variable' and has to be renamed - # later by the name of the variable in a process/model. - xr_variable = as_variable(value, name='this_variable') - - xr_variable.attrs.update(self.attrs) - if self.description: - xr_variable.attrs['description'] = self.description - - return xr_variable - - @property - def state(self): - """State value of the variable, i.e., the instant value at a given - time or simply the value if the variable is not time dependent. - """ - return self._state - - @state.setter - def state(self, value): - self._state = value - - value = state - - @property - def rate(self): - """Rate value of the variable, i.e., the rate of change in time - (time derivative). - """ - return self._rate - - @rate.setter - def rate(self, value): - self._rate = value - - @property - def change(self): - """Change value of the variable, i.e., the rate of change in time - (time derivative) integrated over the time step. - """ - return self._change - - @change.setter - def change(self, value): - self._change = value - - def __repr__(self): - dims_str = ', '.join(['(%s)' % ', '.join(['%r' % d for d in dims]) - for dims in self.allowed_dims]) - return ("" % (type(self).__name__, dims_str)) - - -class ForeignVariable(AbstractVariable): - """Reference to a variable that is defined in another `Process` class. - - """ - def __init__(self, other_process, var_name, provided=False): - """ - Parameters - ---------- - other_process : str or class - Class or class name in which the variable is defined. - var_name : str - Name of the corresponding class attribute in `other_process`. - The value of this class attribute must be a `Variable` object. - provided : bool, optional - Defines whether a value for the variable is required (False) or - provided (True) by the process in which this reference is - defined (default: False). - - """ - super(ForeignVariable, self).__init__(provided=provided) - - self._other_process_cls = other_process - self._other_process_obj = None - self.var_name = var_name - - @property - def ref_process(self): - """The process where the original variable is defined. - - Returns either the Process class or a Process instance attached to - a model. - """ - if self._other_process_obj is None: - return self._other_process_cls - - return self._other_process_obj - - @property - def ref_var(self): - """Returns the original Variable object.""" - return self.ref_process.variables[self.var_name] - - @property - def state(self): - """State value of the original Variable object.""" - return self.ref_var._state - - @state.setter - def state(self, value): - self.ref_var.state = value - - value = state - - @property - def rate(self): - """Rate value of the original Variable object.""" - return self.ref_var._rate - - @rate.setter - def rate(self, value): - self.ref_var.rate = value - - @property - def change(self): - """Change value of the original Variable object.""" - return self.ref_var._change - - @change.setter - def change(self, value): - self.ref_var.change = value - - def __repr__(self): - if self._other_process_obj is None: - ref_process_name = self._other_process_cls.__name__ - else: - ref_process_name = self.ref_process.name - - ref_str = "%s.%s" % (ref_process_name, self.var_name) - - return "" % (type(self).__name__, ref_str) - - -class DiagnosticVariable(AbstractVariable): - """Variable for model diagnostic purpose only. - - The value of a diagnostic variable is computed on the fly during a - model run (there is no initialization nor update of any state). - - A diagnostic variable is defined inside a `Process` subclass, but - it shouldn't be created directly as a class attribute. - Instead it should be defined by applying the `@diagnostic` decorator - on a method of that class. - - Diagnostic variables declared in a process should never be referenced - in other processes as foreign variable. - - The diagnostic variables declared in a process are computed after the - execution of all processes in a model at the end of a time step. - - """ - def __init__(self, func, description='', attrs=None): - super(DiagnosticVariable, self).__init__( - provided=True, description=description, attrs=attrs - ) - - self._func = func - self._process_obj = None - - def assign_process_obj(self, process_obj): - self._process_obj = process_obj - - @property - def state(self): - """State value of this variable (read-only), i.e., the instant value - at a given time or simply the value if the variable is time - independent. - """ - return self._func(self._process_obj) - - value = state - - def __call__(self): - return self.state - - -def diagnostic(attrs_or_function=None, attrs=None): - """Applied to a method of a `Process` subclass, this decorator - allows registering that method as a diagnostic variable. - - The method's docstring is used as a description of the - variable (it should be short, one-line). - - Parameters - ---------- - attrs : dict (optional) - Variable metadata (e.g., standard_name, units, math_symbol...). - - Examples - -------- - .. code-block:: python - - @diagnostic - def slope(self): - '''topographic slope''' - return self._compute_slope() - - @diagnostic({'units': '1/m'}) - def curvature(self): - '''terrain curvature''' - return self._compute_curvature() - - """ - func = None - if callable(attrs_or_function): - func = attrs_or_function - elif isinstance(attrs_or_function, dict): - attrs = attrs_or_function - - def _add_diagnostic_attrs(function): - function._diagnostic = True - function._diagnostic_attrs = attrs - return function - - if func is not None: - return _add_diagnostic_attrs(func) - else: - return _add_diagnostic_attrs - - -class VariableList(tuple): - """A tuple of only `Variable` or `ForeignVariable` objects.""" - def __new__(cls, variables): - var_list = [var for var in variables - if isinstance(var, (Variable, ForeignVariable))] - - if len(var_list) != len(variables): - raise ValueError("found variables mixed with objects of other " - "types in %s" % variables) - - return tuple.__new__(cls, var_list) - - -class VariableGroup(Iterable): - """An Iterable of `ForeignVariable` objects for all variables in a Model - that belong to the same group. - - Using `VariableGroup` is useful in cases when we want to reuse - the same process in different contexts, i.e., with processes that may be - different from one model to another. Good examples are processes that - aggregate (e.g., sum, product, mean) variables defined in other processes. - - """ - def __init__(self, group): - """ - Parameters - ---------- - group : str - Name of the group. - - """ - self._variables = None - - # TODO: inherit also from AbstractVariable? - self.group = group - self.provided = False - self.description = '' - self.attrs = {} - - def _set_variables(self, processes): - """Retrieve all variables in `processes` that belong to this group.""" - self._variables = [] - for proc in processes.values(): - for var_name, var in proc._variables.items(): - if isinstance(var, VariableGroup): - continue - if var.group is not None and var.group == self.group: - foreign_var = ForeignVariable(proc.__class__, var_name) - self._variables.append(foreign_var) - - def __iter__(self): - if self._variables is None: - raise ValueError("cannot retrieve variables of group %r, " - "no model assigned yet." % self.group) - return (v for v in self._variables) - - def __repr__(self): - return "" % (type(self).__name__, self.group) diff --git a/xsimlab/variable/custom.py b/xsimlab/variable/custom.py deleted file mode 100644 index f815b828..00000000 --- a/xsimlab/variable/custom.py +++ /dev/null @@ -1,93 +0,0 @@ -""" -Custom Variable sub-classes. - -""" - -from functools import partial - -import numpy as np - -from .base import Variable, ValidationError - - -def dtype_validator(variable, expected_dtypes): - if not isinstance(expected_dtypes, (list, tuple)): - expected_dtypes = [expected_dtypes] - - test_dtype = any([np.issubdtype(variable.dtype, dtype) - for dtype in expected_dtypes]) - - if not test_dtype: - raise ValidationError( - "invalid dtype, expected one between %s, found %r)" - % ([np.dtype(dtype) for dtype in expected_dtypes], variable.dtype)) - - -floating_validator = partial(dtype_validator, - expected_dtypes=[np.floating, np.integer]) -integer_validator = partial(dtype_validator, expected_dtypes=np.integer) - - -class NumberVariable(Variable): - """A variable that accept numbers as values.""" - - def __init__(self, allowed_dims, bounds=(None, None), - inclusive_bounds=(True, True), **kwargs): - """ - Parameters - ---------- - allowed_dims : str or tuple or list - Dimension label(s) allowed for the variable. An empty tuple - corresponds to a scalar variable, a string or a 1-length tuple - corresponds to a 1-d variable and a n-length tuple corresponds to a - n-d variable. A list of str or tuple items may also be provided if - the variable accepts different numbers of dimensions. - This should not include a time dimension, which is always allowed. - bounds : tuple or None, optional - (lower, upper) value bounds (default: no bounds). - inclusive_bounds : tuple, optional - Whether the given (lower, upper) bounds are inclusive or not. - Default: (True, True). - **kwargs - Keyword arguments of Variable. - - See Also - -------- - Variable - - """ - super(NumberVariable, self).__init__(allowed_dims, **kwargs) - self.bounds = bounds - self.inclusive_bounds = inclusive_bounds - - def _check_bounds(self, xr_variable): - vmin, vmax = self.bounds - incmin, incmax = self.inclusive_bounds - - tmin = ((vmin is not None) - and (xr_variable < vmin if incmin else xr_variable <= vmin)) - tmax = ((vmax is not None) - and (xr_variable > vmax if incmax else xr_variable >= vmax)) - - if np.any(tmin) or np.any(tmax): - smin = '[' if incmin else ']' - smax = ']' if incmax else '[' - strbounds = '{}{}, {}{}'.format(smin, vmin, vmax, smax) - raise ValidationError("found value(s) out of bounds %s" - % strbounds) - - def validate(self, xr_variable): - self._check_bounds(xr_variable) - super(NumberVariable, self).validate(xr_variable) # pragma: no cover - - -class FloatVariable(NumberVariable): - """A variable that accepts floating point numbers as values.""" - - default_validators = [floating_validator] - - -class IntegerVariable(NumberVariable): - """A variable that accepts integer numbers as values.""" - - default_validators = [integer_validator] diff --git a/xsimlab/xr_accessor.py b/xsimlab/xr_accessor.py index 6fd83907..a4696129 100644 --- a/xsimlab/xr_accessor.py +++ b/xsimlab/xr_accessor.py @@ -2,14 +2,13 @@ xarray extensions (accessors). """ -from collections import defaultdict - import numpy as np -from xarray import Dataset, register_dataset_accessor +from xarray import as_variable, Dataset, register_dataset_accessor -from .process import Process +from .drivers import XarraySimulationDriver from .model import Model -from .xr_interface import DatasetModelInterface +from .stores import InMemoryOutputStore +from .utils import variables_dict @register_dataset_accessor('filter') @@ -34,7 +33,7 @@ def _maybe_get_model_from_context(model): try: return Model.get_context() except TypeError: - raise TypeError("no model found in context") + raise TypeError("No model found in context") if not isinstance(model, Model): raise TypeError("%s is not an instance of xsimlab.Model" % model) @@ -42,24 +41,102 @@ def _maybe_get_model_from_context(model): return model +def as_variable_key(key): + """Returns ``key`` as a tuple of the form + ``('process_name', 'var_name')``. + + If ``key`` is given as a string, then process name and variable + name must be separated unambiguously by '__' (double underscore) + and must not be empty. + + """ + key_tuple = None + + if isinstance(key, tuple) and len(key) == 2: + key_tuple = key + + elif isinstance(key, str): + key_split = key.split('__') + if len(key_split) == 2: + p_name, var_name = key_split + if p_name and var_name: + key_tuple = (p_name, var_name) + + if key_tuple is None: + raise ValueError("{!r} is not a valid input variable key".format(key)) + + return key_tuple + + +def _flatten_inputs(input_vars): + """Returns ``input_vars`` as a flat dictionary where keys are tuples in + the form ``(process_name, var_name)``. Raises an error if the + given format appears to be invalid. + + """ + flatten_vars = {} + + for key, val in input_vars.items(): + if isinstance(key, str) and isinstance(val, dict): + for var_name, var_value in val.items(): + flatten_vars[(key, var_name)] = var_value + + else: + flatten_vars[as_variable_key(key)] = val + + return flatten_vars + + +def _flatten_outputs(output_vars): + """Returns ``output_vars`` as a flat dictionary where keys are clock + names (or None) and values are lists of tuples in the form + ``(process_name, var_name)``. + + """ + flatten_vars = {} + + for clock, out_vars in output_vars.items(): + if isinstance(out_vars, dict): + var_list = [] + for p_name, var_names in out_vars.items(): + if isinstance(var_names, str): + var_list.append((p_name, var_names)) + else: + var_list += [(p_name, vname) for vname in var_names] + + elif isinstance(out_vars, (tuple, str)): + var_list = [as_variable_key(out_vars)] + + elif isinstance(out_vars, list): + var_list = [as_variable_key(k) for k in out_vars] + + else: + raise ValueError("Cannot interpret {!r} as valid output " + "variable key(s)".format(out_vars)) + + flatten_vars[clock] = var_list + + return flatten_vars + + @register_dataset_accessor('xsimlab') class SimlabAccessor(object): - """simlab extension to :class:`xarray.Dataset`.""" + """Simlab extension to :class:`xarray.Dataset`.""" - _clock_key = '_xsimlab_snapshot_clock' - _master_clock_key = '_xsimlab_master_clock' - _snapshot_vars_key = '_xsimlab_snapshot_vars' + _clock_key = '__xsimlab_output_clock__' + _master_clock_key = '__xsimlab_master_clock__' + _output_vars_key = '__xsimlab_output_vars__' - def __init__(self, xarray_obj): - self._obj = xarray_obj + def __init__(self, ds): + self._ds = ds self._master_clock_dim = None @property def clock_coords(self): """Dictionary of :class:`xarray.DataArray` objects corresponding to - clock coordinates (including master clock and snapshot clocks). + clock coordinates. """ - return {k: coord for k, coord in self._obj.coords.items() + return {k: coord for k, coord in self._ds.coords.items() if self._clock_key in coord.attrs} @property @@ -75,7 +152,7 @@ def master_clock_dim(self): if self._master_clock_dim is not None: return self._master_clock_dim else: - for c in self._obj.coords.values(): + for c in self._ds.coords.values(): if c.attrs.get(self._master_clock_key, False): dim = c.dims[0] self._master_clock_dim = dim @@ -83,17 +160,17 @@ def master_clock_dim(self): return None def _set_master_clock_dim(self, dim): - if dim not in self._obj.coords: + if dim not in self._ds.coords: raise KeyError("Dataset has no %r dimension coordinate. " "To create a new master clock dimension, " "use Dataset.xsimlab.update_clock." % dim) if self.master_clock_dim is not None: - self._obj[self.master_clock_dim].attrs.pop(self._master_clock_key) + self._ds[self.master_clock_dim].attrs.pop(self._master_clock_key) - self._obj[dim].attrs[self._clock_key] = np.uint8(True) - self._obj[dim].attrs[self._master_clock_key] = np.uint8(True) + self._ds[dim].attrs[self._clock_key] = np.uint8(True) + self._ds[dim].attrs[self._master_clock_key] = np.uint8(True) self._master_clock_dim = dim def _set_clock_data(self, dim, data, start, end, step, nsteps): @@ -124,15 +201,15 @@ def _set_clock_data(self, dim, data, start, end, step, nsteps): def _set_master_clock(self, dim, data=None, start=0., end=None, step=None, nsteps=None, units=None, calendar=None): - if dim in self._obj.dims: + if dim in self._ds.dims: raise ValueError("dimension %r already exists" % dim) - self._obj[dim] = self._set_clock_data(dim, data, start, end, - step, nsteps) + self._ds[dim] = self._set_clock_data(dim, data, start, end, + step, nsteps) if units is not None: - self._obj[dim].attrs['units'] = units + self._ds[dim].attrs['units'] = units if calendar is not None: - self._obj[dim].attrs['calendar'] = calendar + self._ds[dim].attrs['calendar'] = calendar self._set_master_clock_dim(dim) @@ -145,7 +222,7 @@ def _set_snapshot_clock(self, dim, data=None, start=0., end=None, clock_data = self._set_clock_data(dim, data, start, end, step, nsteps) - da_master_clock = self._obj[self.master_clock_dim] + da_master_clock = self._ds[self.master_clock_dim] if auto_adjust: kwargs = {'method': 'nearest'} @@ -156,120 +233,90 @@ def _set_snapshot_clock(self, dim, data=None, start=0., end=None, kwargs.update(indexer) da_snapshot_clock = da_master_clock.sel(**kwargs) - self._obj[dim] = da_snapshot_clock.rename({self.master_clock_dim: dim}) + self._ds[dim] = da_snapshot_clock.rename({self.master_clock_dim: dim}) + # .sel copies variable attributes - self._obj[dim].attrs.pop(self._master_clock_key) + self._ds[dim].attrs.pop(self._master_clock_key) for attr_name in ('units', 'calendar'): attr_value = da_master_clock.attrs.get(attr_name) if attr_value is not None: - self._obj[dim].attrs[attr_name] = attr_value + self._ds[dim].attrs[attr_name] = attr_value - def _set_input_vars(self, model, process, **inputs): - if isinstance(process, Process): - process = process.name - if process not in model: - raise KeyError("no process named %r found in current model" - % process) + def _set_input_vars(self, model, input_vars): + invalid_inputs = set(input_vars) - set(model.input_vars) + if invalid_inputs: + raise KeyError( + "{} is/are not valid key(s) for input variables in model {}" + .format(', '.join([str(k) for k in invalid_inputs]), model) + ) - process_inputs = model.input_vars[process] + for (p_name, var_name), data in input_vars.items(): + p_obj = model[p_name] + var = variables_dict(type(p_obj))[var_name] + + xr_var_name = p_name + '__' + var_name + xr_var = as_variable(data) + + if var.metadata['description']: + xr_var.attrs['description'] = var.metadata['description'] + xr_var.attrs.update(var.metadata['attrs']) + + self._ds[xr_var_name] = xr_var + + def _set_output_vars(self, model, clock, output_vars): + invalid_outputs = set(output_vars) - set(model.all_vars) + if invalid_outputs: + raise KeyError( + "{} is/are not valid key(s) for variables in model {}" + .format(', '.join([str(k) for k in invalid_outputs]), model) + ) + + output_vars_str = ','.join([p_name + '__' + var_name + for (p_name, var_name) in output_vars]) + + if clock is None: + self._ds.attrs[self._output_vars_key] = output_vars_str - invalid_inputs = set(inputs) - set(process_inputs) - if invalid_inputs: - raise ValueError("%s are not valid input variables of %r" - % (', '.join([name for name in invalid_inputs]), - process)) - - # convert to xarray variables and validate the given dimensions - xr_variables = {} - for name, var in model.input_vars[process].items(): - xr_var = var.to_xarray_variable(inputs.get(name)) - var.validate_dimensions(xr_var.dims, - ignore_dims=(self.master_clock_dim, - 'this_variable')) - xr_variables[name] = xr_var - - # validate at the process level - # first assign values to a cloned process object to avoid conflicts - process_obj = model._processes[process].clone() - for name, xr_var in xr_variables.items(): - process_obj[name].value = xr_var.values - process_obj.validate() - - # maybe set optional variables, and validate each variable - for name, xr_var in xr_variables.items(): - var = process_obj[name] - if var.value is not xr_var.values: - xr_var = var.to_xarray_variable(var.value) - xr_variables[name] = xr_var - var.run_validators(xr_var) - var.validate(xr_var) - - # add variables to dataset if all validation tests passed - # also rename the 'this_variable' dimension if present - for name, xr_var in xr_variables.items(): - xr_var_name = process + '__' + name - rename_dict = {'this_variable': xr_var_name} - dims = tuple(rename_dict.get(dim, dim) for dim in xr_var.dims) - xr_var.dims = dims - self._obj[xr_var_name] = xr_var - - def _set_snapshot_vars(self, model, clock_dim, **process_vars): - xr_vars_list = [] - - for proc_name, vars in sorted(process_vars.items()): - if proc_name not in model: - raise KeyError("no process named %r found in current model" - % proc_name) - process = model[proc_name] - if isinstance(vars, str): - vars = [vars] - for var_name in vars: - if process.variables.get(var_name, None) is None: - raise KeyError("process %r has no variable %r" - % (proc_name, var_name)) - xr_vars_list.append(proc_name + '__' + var_name) - - snapshot_vars = ','.join(xr_vars_list) - - if clock_dim is None: - self._obj.attrs[self._snapshot_vars_key] = snapshot_vars - else: - if clock_dim not in self.clock_coords: - raise ValueError("%r coordinate is not a valid clock " - "coordinate. " % clock_dim) - coord = self.clock_coords[clock_dim] - coord.attrs[self._snapshot_vars_key] = snapshot_vars - - def _get_snapshot_vars(self, name, obj): - vars_str = obj.attrs.get(self._snapshot_vars_key, '') - if vars_str: - return {name: [tuple(s.split('__')) - for s in vars_str.split(',')]} else: - return {} + if clock not in self.clock_coords: + raise ValueError("{!r} coordinate is not a valid clock " + "coordinate.".format(clock)) + coord = self.clock_coords[clock] + coord.attrs[self._output_vars_key] = output_vars_str + + def _maybe_update_output_vars(self, clock, ds_or_coord, output_vars): + out_attr = ds_or_coord.attrs.get(self._output_vars_key) + + if out_attr is not None: + output_vars[clock] = [as_variable_key(k) + for k in out_attr.split(',')] @property - def snapshot_vars(self): - """Returns a dictionary of snapshot clock dimension names as keys and - snapshot variable names - i.e. lists of (process name, variable name) + def output_vars(self): + """Returns a dictionary of clock dimension names (or None) as keys and + output variable names - i.e. lists of ``('p_name', 'var_name')`` tuples - as values. + """ - snapshot_vars = {} - for cname, coord in self._obj.coords.items(): - snapshot_vars.update(self._get_snapshot_vars(cname, coord)) - snapshot_vars.update(self._get_snapshot_vars(None, self._obj)) - return snapshot_vars + output_vars = {} + + for clock, clock_coord in self.clock_coords.items(): + self._maybe_update_output_vars(clock, clock_coord, output_vars) + + self._maybe_update_output_vars(None, self._ds, output_vars) + + return output_vars def update_clocks(self, model=None, clocks=None, master_clock=None): """Update clock coordinates. - Drop all clock coordinates (if any) and add a new set of master and - snapshot clock coordinates. - Also copy all snapshot-specific attributes of the replaced coordinates. + Add clock coordinates (after dropped all existing clock + coordinates). Output variable attributes are propagate to + the replaced coordinates. - More details about the values allowed for the parameters below can be - found in the doc of :meth:`xsimlab.create_setup`. + More details about the values allowed for the parameters below + can be found in the doc of :meth:`xsimlab.create_setup`. Parameters ---------- @@ -278,8 +325,8 @@ def update_clocks(self, model=None, clocks=None, master_clock=None): clocks : dict of dicts, optional Used to create one or several clock coordinates. master_clock : str or dict, optional - Name (and units/calendar) of the clock coordinate (dimension) to - use as master clock. + Name (and units/calendar) of the clock coordinate + (dimension) to use as master clock. Returns ------- @@ -293,7 +340,7 @@ def update_clocks(self, model=None, clocks=None, master_clock=None): """ model = _maybe_get_model_from_context(model) - ds = self._obj.drop(self.clock_coords) + ds = self._ds.drop(self.clock_coords) attrs_master_clock = {} @@ -323,21 +370,14 @@ def update_clocks(self, model=None, clocks=None, master_clock=None): for dim, kwargs in clocks.items(): ds.xsimlab._set_snapshot_clock(dim, **kwargs) - for dim, var_list in self.snapshot_vars.items(): - var_dict = defaultdict(list) - for proc_name, var_name in var_list: - var_dict[proc_name].append(var_name) - - if dim is None or dim in ds: - ds.xsimlab._set_snapshot_vars(model, dim, **var_dict) + for clock, var_keys in self.output_vars.items(): + if clock is None or clock in ds: + ds.xsimlab._set_output_vars(model, clock, var_keys) return ds - def update_vars(self, model=None, input_vars=None, snapshot_vars=None): - """Update model input values and/or snapshot variable names. - - Add or replace all input values (resp. snapshot variable names) per - given process (resp. clock coordinate). + def update_vars(self, model=None, input_vars=None, output_vars=None): + """Update model input values and/or output variable names. More details about the values allowed for the parameters below can be found in the doc of :meth:`xsimlab.create_setup`. @@ -346,10 +386,11 @@ def update_vars(self, model=None, input_vars=None, snapshot_vars=None): ---------- model : :class:`xsimlab.Model` object, optional Reference model. If None, tries to get model from context. - input_vars : dict of dicts, optional - Model input values given per process. - snapshot_vars : dict of dicts, optional - Model variables to save as simulation snapshots, given per + input_vars : dict, optional + Model input values (may be grouped per process name, as dict of + dicts). + output_vars : dict, optional + Model variables to save as simulation output, given per clock coordinate. Returns @@ -365,24 +406,25 @@ def update_vars(self, model=None, input_vars=None, snapshot_vars=None): """ model = _maybe_get_model_from_context(model) - ds = self._obj.copy() + ds = self._ds.copy() if input_vars is not None: - for proc_name, vars in input_vars.items(): - ds.xsimlab._set_input_vars(model, proc_name, **vars) + ds.xsimlab._set_input_vars(model, _flatten_inputs(input_vars)) - if snapshot_vars is not None: - for dim, proc_vars in snapshot_vars.items(): - ds.xsimlab._set_snapshot_vars(model, dim, **proc_vars) + if output_vars is not None: + for clock, out_vars in _flatten_outputs(output_vars).items(): + ds.xsimlab._set_output_vars(model, clock, out_vars) return ds def filter_vars(self, model=None): """Filter Dataset content according to Model. - Keep only data variables and coordinates that correspond to inputs of - the model (keep clock coordinates too). Also update snapshot-specific - attributes so that their values all correspond to processes and + Keep only data variables and coordinates that correspond to + inputs of the model (keep clock coordinates too). + + Also update xsimlab-specific attributes so that output + variables given per clock only refer to processes and variables defined in the model. Parameters @@ -403,28 +445,28 @@ def filter_vars(self, model=None): """ model = _maybe_get_model_from_context(model) + # drop variables drop_variables = [] - for xr_var_name in self._obj: + for xr_var_name in self._ds.variables: if xr_var_name in self.clock_coords: continue + try: - proc_name, var_name = xr_var_name.split('__') + p_name, var_name = xr_var_name.split('__') except ValueError: - continue + # not a xsimlab model input: make sure to remove it + p_name, var_name = ('', xr_var_name) - if not model.is_input((proc_name, var_name)): + if (p_name, var_name) not in model.input_vars: drop_variables.append(xr_var_name) - ds = self._obj.drop(drop_variables) + ds = self._ds.drop(drop_variables) - for dim, var_list in self.snapshot_vars.items(): - var_dict = defaultdict(list) - for proc_name, var_name in var_list: - if model.get(proc_name, {}).get(var_name, False): - var_dict[proc_name].append(var_name) - - ds.xsimlab._set_snapshot_vars(model, dim, **var_dict) + # update output variable attributes + for clock, out_vars in self.output_vars.items(): + new_out_vars = [key for key in out_vars if key in model.all_vars] + ds.xsimlab._set_output_vars(model, clock, new_out_vars) return ds @@ -443,7 +485,7 @@ def run(self, model=None, safe_mode=True): Returns ------- output : Dataset - Another Dataset with both model inputs and outputs (snapshots). + Another Dataset with both model inputs and outputs. """ model = _maybe_get_model_from_context(model) @@ -451,9 +493,12 @@ def run(self, model=None, safe_mode=True): if safe_mode: model = model.clone() - ds_model_interface = DatasetModelInterface(model, self._obj) - out_ds = ds_model_interface.run_model() - return out_ds + store = {} + output_store = InMemoryOutputStore() + + driver = XarraySimulationDriver(self._ds, model, store, output_store) + + return driver.run_model() def run_multi(self): """Run multiple models. @@ -470,12 +515,13 @@ def run_multi(self): def create_setup(model=None, clocks=None, master_clock=None, - input_vars=None, snapshot_vars=None): + input_vars=None, output_vars=None): """Create a specific setup for model runs. - This convenient function creates a new :class:`xarray.Dataset` object with - model input values, time steps and model output variables (including - snapshot times) as data variables, coordinates and attributes. + This convenient function creates a new :class:`xarray.Dataset` + object with everything needed to run a model (i.e., input values, + time steps, output variables to save at given times) as data + variables, coordinates and attributes. Parameters ---------- @@ -493,22 +539,39 @@ def create_setup(model=None, clocks=None, master_clock=None, A dictionary with at least a 'dim' key can be provided instead, it allows setting time units and calendar (CF-conventions) with 'units' and 'calendar' keys. - input_vars : dict of dicts, optional - Model inputs values given per process. The structure of the dict of - dicts looks like ``{'process_name': {'var_name': value, ...}, ...}``. + input_vars : dict, optional + Dictionary with values given for model inputs. Entries of the + dictionary may look like: + + - ``'foo': {'bar': value, ...}`` or + - ``('foo', 'bar'): value`` or + - ``'foo__bar': value`` + + where ``foo`` is the name of a existing process in the model and + ``bar`` is the name of an (input) variable declared in that process. + Values are anything that can be easily converted to :class:`xarray.Variable` objects, e.g., single values, array-like, - (dims, data, attrs) tuples or xarray objects. - snapshot_vars : dict of dicts, optional - Model variables to save as simulation snapshots, given per clock - coordinate. The structure of the dict of dicts looks like - ``{'dim': {'process_name': 'var_name', ...}, ...}``. - 'dim' must correspond to the dimension of a clock coordinate or None - for snapshots that only have to be taken once at the end of the - simulation. - To take snapshots for multiple variables that belong to the same - process, a tuple of multiple variable names can be given instead of a - string. + ``(dims, data, attrs)`` tuples or xarray objects. + output_vars : dict, optional + Dictionary with model variable names to save as simulation output, + given per clock coordinate. Entries of the given dictionary may + look like: + + - ``'dim': {'foo': 'bar'}`` or + - ``'dim': {'foo': ('bar', 'baz')}`` or + - ``'dim': ('foo', 'bar')`` or + - ``'dim': [('foo', 'bar'), ('foo', 'baz')]`` or + - ``'dim': 'foo__bar'`` or + - ``'dim': ['foo__bar', 'foo__baz']`` + + where ``foo`` is the name of a existing process in the model and + ``bar``, ``baz`` are the names of variables declared in that process. + + If ``'dim'`` corresponds to the dimension of a clock coordinate, + new output values will be saved at each time given by the coordinate + labels. if None is given instead, only one value will be saved at the + end of the simulation. Returns ------- @@ -516,7 +579,7 @@ def create_setup(model=None, clocks=None, master_clock=None, A new Dataset object with model inputs as data variables or coordinates (depending on their given value) and clock coordinates. The names of the input variables also include the name of their process - (i.e., 'process_name__var_name'). + (i.e., 'foo__bar'). Notes ----- @@ -541,11 +604,7 @@ def create_setup(model=None, clocks=None, master_clock=None, with the labels of the master clock coordinate. Otherwise raise a KeyError if labels are not valid. (DataArray.sel is used internally). - Inputs of ``model`` for which no value is given are still added as variables - in the returned Dataset, using their default value (if any). It requires - that their process are provided as keys of ``input_vars``, though. - - Snapshot variable names are added in Dataset as specific attributes + Output variable names are added in Dataset as specific attributes (global and/or clock coordinate attributes). """ @@ -555,6 +614,6 @@ def create_setup(model=None, clocks=None, master_clock=None, .xsimlab.update_clocks(model=model, clocks=clocks, master_clock=master_clock) .xsimlab.update_vars(model=model, input_vars=input_vars, - snapshot_vars=snapshot_vars)) + output_vars=output_vars)) return ds diff --git a/xsimlab/xr_interface.py b/xsimlab/xr_interface.py deleted file mode 100644 index 95b2e643..00000000 --- a/xsimlab/xr_interface.py +++ /dev/null @@ -1,197 +0,0 @@ -import numpy as np -import xarray as xr - - -def _get_dims_from_variable(array, variable): - """Given an array of values (snapshot) and a (xarray-simlab) Variable - object, Return dimension labels for the array.""" - for dims in variable.allowed_dims: - if len(dims) == array.ndim: - return dims - return tuple() - - -class DatasetModelInterface(object): - """Interface between xarray.Dataset and Model. - - It is used to: - - - set model inputs using the variables of a Dataset object, - - run model simulation stages, - - take snapshots for given model variables (defined in attributes of - Dataset) following one or several clocks (i.e., Dataset coordinates), - - convert the snapshots back into xarray.Variable objects and return a - new xarray.Dataset object. - - """ - def __init__(self, model, dataset): - self.model = model - self.dataset = dataset - - self.master_clock_dim = dataset.xsimlab.master_clock_dim - if self.master_clock_dim is None: - raise ValueError("missing master clock dimension / coordinate ") - - self.check_model_inputs_in_dataset() - - def check_model_inputs_in_dataset(self): - """Check if all model inputs have their corresponding data variables - in Dataset. - """ - missing_data_vars = [] - - for proc_name, vars in self.model.input_vars.items(): - for var_name, var in vars.items(): - xr_var_name = proc_name + '__' + var_name - if xr_var_name not in self.dataset.data_vars: - missing_data_vars.append(xr_var_name) - - if missing_data_vars: - raise KeyError("missing data variables %s in Dataset" - % missing_data_vars) - - def set_model_inputs(self, dataset): - """Set model inputs values from a given Dataset object (may be a subset - of self.dataset).""" - for proc_name, vars in self.model.input_vars.items(): - for var_name, var in vars.items(): - xr_var_name = proc_name + '__' + var_name - xr_var = dataset.get(xr_var_name) - if xr_var is not None: - var.value = xr_var.values.copy() - - def split_data_vars_clock(self): - """Separate in Dataset between data variables that have the master clock - dimension and those that don't. - """ - ds_clock = self.dataset.filter( - lambda v: self.master_clock_dim in v.dims - ) - ds_no_clock = self.dataset.filter( - lambda v: self.master_clock_dim not in v.dims - ) - return ds_clock, ds_no_clock - - @property - def time_step_lengths(self): - """Return a DataArray with time-step durations.""" - clock_coord = self.dataset[self.master_clock_dim] - return clock_coord.diff(self.master_clock_dim).values - - def init_snapshots(self): - """Initialize snapshots for model variables given in attributes of - Dataset. - """ - self.snapshot_vars = self.dataset.xsimlab.snapshot_vars - - self.snapshot_values = {} - for vars in self.snapshot_vars.values(): - self.snapshot_values.update({v: [] for v in vars}) - - self.snapshot_save = { - clock: np.in1d(self.dataset[self.master_clock_dim].values, - self.dataset[clock].values) - for clock in self.snapshot_vars if clock is not None - } - - def take_snapshot_var(self, key): - """Take a snapshot of a given model variable (i.e., a copy of the value - of its `state` property). - """ - proc_name, var_name = key - model_var = self.model._processes[proc_name]._variables[var_name] - self.snapshot_values[key].append(np.array(model_var.state)) - - def take_snapshots(self, istep): - """Take snapshots at a given step index.""" - for clock, vars in self.snapshot_vars.items(): - if clock is None: - if istep == -1: - for key in vars: - self.take_snapshot_var(key) - elif self.snapshot_save[clock][istep]: - for key in vars: - self.take_snapshot_var(key) - - def snapshot_to_xarray_variable(self, key, clock=None): - """Convert snapshots taken for a specific model variable to an - xarray.Variable object. - """ - proc_name, var_name = key - variable = self.model._processes[proc_name]._variables[var_name] - - array_list = self.snapshot_values[key] - first_array = array_list[0] - - if len(array_list) == 1: - data = first_array - else: - data = np.stack(array_list) - - dims = _get_dims_from_variable(first_array, variable) - if clock is not None and len(array_list) > 1: - dims = (clock,) + dims - - attrs = variable.attrs.copy() - attrs['description'] = variable.description - - return xr.Variable(dims, data, attrs=attrs) - - def get_output_dataset(self): - """Build a new output Dataset from the input Dataset and - all snapshots taken during a model run. - """ - from .xr_accessor import SimlabAccessor - - xr_variables = {} - - for clock, vars in self.snapshot_vars.items(): - for key in vars: - var_name = '__'.join(key) - xr_variables[var_name] = self.snapshot_to_xarray_variable( - key, clock=clock - ) - - out_ds = self.dataset.update(xr_variables, inplace=False) - - for clock in self.snapshot_vars: - if clock is None: - attrs = out_ds.attrs - else: - attrs = out_ds[clock].attrs - attrs.pop(SimlabAccessor._snapshot_vars_key) - - return out_ds - - def run_model(self): - """Run the model. - - The is the main function of the interface. It set model inputs - from the input Dataset, run the simulation stages one after - each other, possibly sets time-dependent values provided for - model inputs (if any) before each time step, take snaphots - between the 'run_step' and the 'finalize_step' stages, and - finally returns a new Dataset with all the inputs and the - snapshots. - - """ - ds_clock, ds_no_clock = self.split_data_vars_clock() - ds_clock_any = bool(ds_clock.data_vars) - - self.init_snapshots() - self.set_model_inputs(ds_no_clock) - self.model.initialize() - - for istep, dt in enumerate(self.time_step_lengths): - if ds_clock_any: - ds_step = ds_clock.isel(**{self.master_clock_dim: istep}) - self.set_model_inputs(ds_step) - - self.model.run_step(dt) - self.take_snapshots(istep) - self.model.finalize_step() - - self.take_snapshots(-1) - self.model.finalize() - - return self.get_output_dataset()