Getting started

Installation

Quick installation via pip

Warning

You should only install RoGeR this way if you want to get going as quickly as possible, and do not plan to access or modify the model source code. The recommended way to install RoGeR is by checking out the repository (see below).

If you already have Python installed, the quickest way to get a working RoGeR installation is to run

$ pip install roger

or, optionally:

$ pip install roger[jax]

to use RoGeR with JAX.

Checking out the repository and using Conda (multi-platform)

  1. Download and install Miniconda. If you are using Windows, you may use the Anaconda prompt to execute the following steps.

  2. Clone the RoGeR repository

    $ git clone https://github.com/Hydrology-IFH/roger.git
    

    (or any other version of RoGeR).

    If you do not have git installed, you can do so via conda install git.

  3. Create a new conda environment for RoGeR, and install all relevant dependencies by running

    $ conda env create -f conda-environment.yml
    

    from the RoGeR root directory.

  4. To use RoGeR, just activate your new conda environment via

    $ conda activate roger
    

Checking out the repository and using pip (Linux / OSX)

  1. Ensure you have a working Python 3.x installation.

  2. Clone our repository:

    $ git clone https://github.com/Hydrology-IFH/roger.git
    

    (or any other version of RoGeR), or use

    $ pip download roger
    

    to download a tarball of the latest version (needs to be unpacked).

  3. Install RoGeR (preferably in a virtual environment) via

    $ pip install -e ./roger
    

    You might have to add the --user flag to pip install if you are using your system interpreter. The -e flag ensures that changes to the code are immediately reflected without reinstalling.

  4. Optionally, install JAX via

    $ pip install -e ./roger[jax]
    

Setting up a model

To run RoGeR, you need to set up a model - i.e., specify which settings and model domain you want to use. This is done by subclassing the RoGeR setup base class in a setup script that is written in Python. You should have a look at the pre-implemented model setups in the repository’s models folder, or use the roger copy-model command to copy one into your current folder. A good place to start is the SVAT model:

$ roger copy-setup svat

By working through the existing models, you should quickly be able to figure out how to write your own simulation. Just keep in mind this general advice:

  • You can (and should) use any (external) Python tools you want in your pre-processing or model setup. Before implementing a certain functionality, you should check whether it is already provided by a common library. Especially the SciPy module family provides countless implementations of common scientific functions (and SciPy is installed along with RoGeR).

  • You have to decorate your methods with @roger_routine. Only RoGeR routines are able to modify the model state object, which is passed as the first argument. The current numerical backend is available from the roger.core.operators module:

    from roger import RogerSetup, roger_routine
    from roger.core.operators import numpy as npx
    
    class MyRogerSetup(RogerSetup):
        ...
        @roger_routine
        def my_function(self, state):
            arr = npx.array([1, 2, 3, 4]) # "npx" uses either NumPy or JAX
    
  • If you are curious about the general process how a model is set up and ran, you should read the source code of roger.RogerSetup (especially the setup() and run() methods). This is also the best way to find out about the order in which routines are called.

  • Out of all functions that need to be implemented by your subclass of roger.RogerSetup, the only one that is called in every time step is set_forcing() (at the beginning of each iteration). This implies that, to achieve optimal performance, you should consider moving calculations that are constant in time to other functions.

  • There is another type of decorator called @roger_kernel. A kernel is a pure function that may be compiled to machine code by JAX. Kernels typically execute much faster, but are more restrictive to implement, as they cannot interact with the model state directly.

    A common pattern in large setups is to implement set_forcing() as a kernel for optimal performance.

Running RoGeR

After adapting your setup script, you are ready to run your first simulation. Just execute the following:

$ python my_setup.py

See also

The RoGeR command line interface accepts a large number of options to configure your run; see Command line tools.

Note

You are not required to use the command line, and you are welcome to include your simulation class into other Python files and call it dynamically or interactively (e.g. in an IPython session). All you need to do is to call the setup() and run() methods of your roger.RogerSetup object.

Reading RoGeR output

All output is handled by the available diagnostics. The most basic diagnostic, collect, writes some model variables to netCDF files in regular intervals (and puts them into your current working directory).

NetCDF is a binary format that is widely adopted in the geophysical modeling community. There are various packages for reading, visualizing and processing netCDF files (such as ncview and ferret), and bindings for many programming languages (such as C, Fortran, MATLAB, and Python).

For post-processing in Python, we recommend that you use xarray:

import xarray as xr

ds = xr.open_dataset("SVAT.rate.nc", engine="h5netcdf")

# plot macropore infiltration
inf_mp = ds.inf_mp.isel(x=0, y=0)
inf_mp.plot()

Re-starting from a previous run

Restart data (in HDF5 format) is written at the end of each simulation or after a regular time interval if the setting restart_frequency is set to a finite value. To use this restart file as initial conditions for another simulation, you will have to point restart_input_filename of the new simulation to the corresponding restart file. This can also be given via the command line (as all settings):

$ roger run my_setup.py -s restart_input_filename /path/to/restart_file.h5

Running RoGeR on multiple processes via MPI

Note

This assumes that you are familiar with running applications through MPI, and is most useful on large architectures like a compute cluster. For smaller architectures, it is usually easier to stick to the thread-based parallelism of JAX.

Running RoGeR through MPI requires some additional dependencies. For optimal performance, you will need to install mpi4py, h5py, and mpi4jax, linked to your MPI library.

After you have installed everything, you can start RoGeR on multiple processes like so::

$ mpirun -np 4 python my_setup.py -n 2 2

In this case, RoGeR would run on 4 processes, each process computing one-quarter of the domain. The arguments of the -n flag specify the number of domain partitions in x and y-direction, respectively.

See also

For more information, see Running RoGeR on a cluster.

Enhancing RoGeR

RoGeR was written with a strong focus on extensibility. If you already know some Python and have worked with NumPy, you are pretty much ready to write your own extension. The model code is located in the roger subfolder, while all of the numerical routines are located in roger/core.

We believe that the best way to learn how RoGeR works is to read its source code. Starting from the RoGeR base class, you should be able to work your way through the flow of the program, and figure out where to add your modifications. If you installed RoGeR through pip -e or setup.py develop, all changes you make will immediately be reflected when running the code.

In case you want to add additional output capabilities or compute additional quantities without changing the main solution of the simulation, you should consider adding a custom diagnostic.

A convenient way to implement your modifications is to create your own fork of RoGeR on GitHub, and submit a pull request if you think your modifications could be useful for the RoGeR community.

See also

More information is available in our developer guide.