Note

Last update 04/05/2021

Sharing model configurations

A key goal of SuperflexPy is to facilitate collaboration between research groups, and to help compare and improve modelling solutions. To this end, users can share model configurations that can be imported and run by other users. Note that models built with SuperflexPy are Python objects that, once initialized, can be imported into other scripts.

A user who wishes to share their model configuration with the community can create a Python script (with a descriptive name) that initializes the model (without running it) and “upload” it to the GitHub repository in the folder superflexpy/implementation/models/. This “upload” requires the following steps: (1) fork the SuperflexPy repository, (2) add the script to the local fork of the repository, and (3) make a pull request to the original repository (see Software organization and contribution for further details). The contributed code will be checked by the repository maintainers. Assuming all checks are passed the newly incorporated code will be incorporated in the following release of SuperflexPy and thus made available to other SuperflexPy users.

The user will maintain authorship on the contributed code, which will be released with the same License as SuperflexPy. It is good practice to include unit tests to enable users to ensure the new code is operating as expected (see Automated testing).

Practical example with M4

We illustrate of how to distribute SuperflexPy models to colleagues using as an example the model Model M4 from Kavetski and Fenicia, WRR, 2011.

First, we create the file m4_sf_2011.py that contains the code to initialize the model

 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
from superflexpy.implementation.root_finders.pegasus import PegasusPython
from superflexpy.implementation.numerical_approximators.implicit_euler import ImplicitEulerPython
from superflexpy.implementation.elements.hbv import UnsaturatedReservoir, PowerReservoir
from superflexpy.framework.unit import Unit

root_finder = PegasusPython()
numeric_approximator = ImplicitEulerPython(root_finder=root_finder)

ur = UnsaturatedReservoir(
    parameters={'Smax': 50.0, 'Ce': 1.0, 'm': 0.01, 'beta': 2.0},
    states={'S0': 25.0},
    approximation=numeric_approximator,
    id='UR'
)

fr = PowerReservoir(
    parameters={'k': 0.1, 'alpha': 1.0},
    states={'S0': 10.0},
    approximation=numeric_approximator,
    id='FR'
)

model = Unit(
    layers=[
        [ur],
        [fr]
    ],
    id='M4'
)

Then we incorporate the file m4_sf_2011.py into the SuperflexPy repository in the folder superflexpy/implementation/models/ following the steps illustrated in the previous section (fork, change, and pull request).

Once the next release of SuperflexPy is available, the M4 model implementation will be available in the updated installed package. General users can then use this new model in their own application, by importing it as shown below.

1
2
3
4
5
6
7
from superflexpy.implementation.models.m4_sf_2011 import model

model.set_input([P, E])
model.set_timestep(1.0)
model.reset_states()

output = model.get_output()

Sharing models “privately” with other users

Model configurations can be shared “privately” between research groups without waiting for a new release of the framework.

This can be done by creating a my_new_model.py file that initializes the model and then sharing the file “privately” with other users.

The recipients of the new file can then save it on their machines and use local importing. Assuming that the script that the recipients use to run the model is in the same folder as the file initializing the model, the new model can be used as follows

1
2
3
4
5
6
7
from .my_new_model import model

model.set_input([P, E])
model.set_timestep(1.0)
model.reset_states()

output = model.get_output()

Note the local import in line 1.

As we believe in the F.A.I.R. principles, we encourage modelers to share their models with the whole community, using the procedure detailed earlier.

Dumping objects with Pickle

Python offers the module Pickle to serialize objects to binary files. This approach enables the distribution of binary files, but has the disadvantage of lacking transparency in the model structure.