Package: py-modelrunner
py-modelrunnerThis package provides python classes for handling and running physical simulations.
The main aim is to easily wrap simulation code and deal with input and output automatically.
The package also facilitates submitting simulations to high performance computing
environments and it provides functions for running parameter scans.InstallationThe package can simply be cloned from github, but it is also available onpipandconda:pipinstallpy-modelrunnerUsageThis package has multiple purposes that are described in more detail below. Additional
examples can be found in theexamplesfolder.Minimal exampleAssume you have written a python simulation in form of a simple script that defines a
function with several arguments, like sodefmain(a:float=1,b:int=2,negate:bool=False):res=a**bifnegate:res*=-1returnresThemodelrunnerpackage now allows you to wrap a convenient command line interface
around this simple function. Assuming the script is saved in a file calledscript.py,
callingpython -m modelrunner script.py -hshows the follwing helpusage: script.py [-h] [--a VALUE] [--b VALUE] [--negate] [--json JSON] [-o PATH]

optional arguments:
  -h, --help            show this help message and exit
  --json JSON           JSON-encoded parameter values. Overwrites other parameters. (default: None)
  -o PATH, --output PATH
                        Path to output file. If omitted, no output file is created. (default: None)

  --a VALUE             Parameter `a` (default: 1)
  --b VALUE             Parameter `b` (default: 2)
  --negate              Parameter `negate` (default: False)Consequently, the function can be called usingpython -m modelrunner script.py --a 2 --b 3 --negate -o result.yaml,
which produces a fileresult.yamlwith the following content:info:time:# TIMESTAMPmodel:class:maindescription:nullname:mainparameters:a:2.0b:3negate:trueresult:-8.0This file not only contains the result, but also metainformation including the
parameters to run the simulation and the time when it was started.Creating modelsThe package introduces a base classModelBasethat describes the bare structure all
models are supposed to have.
Custom models can be created by inheriting fromModelBaseand defining suitable
parameters:frommodelrunnerimportModelBaseclassMyModel(ModelBase):# define custom model# defines supported parameters with default valuesparameters_default={"a":1,"b":2}def__call__(self):"""calculate the actual model"""returnself.parameters["a"]*self.parameters["b"]model=MyModel({"a":3})The last line actually creates an instance of the model with custom parameters.Alternatively, a model can also be defined from a simple function:frommodelrunnerimportmake_model@make_modeldefmultiply(a=1,b=2):returna*bmodel=multiply(a=3)The main aim of defining models like this is to provide a unified interface for
running models for the subsequent sections.Run models from command lineModels can be run with different parameters. In both examples shown above, the model
can be run from within the python code by simply calling the model instance:model().
In the cases shown above, these calls will simply return6.In typical numerical simulations, models need to be evaluated for many different
parameters. The packages facilitates this by providing a special interface to set
arguments from the command line. To show this, either one of the model definitions
given above can be saved as a python filemodel.py. Using the special callpython -m modelrunner model.pyprovides a command line interface for adjusting model parameters.
The supported parameters can be obtained with the following command$python-mmodelrunnermodel.py--helpusage: model.py [-h] [--a VALUE] [--b VALUE] [-o PATH] [--json JSON]optional arguments:-h, --help            show this help message and exit-o PATH, --output PATHPath to output file. If omitted, no output file is created. (default: None)--json JSON           JSON-encoded parameter values. Overwrites other parameters. (default: None)--a VALUE             Parameter `a` (default: 1)--b VALUE             Parameter `b` (default: 2)This can be helpful to call a model automatically and save the result. For instance, by
callingpython -m modelrunner model.py -h --a 3 -o result.yaml, we obtain a fileresult.yamlthat
looks something like this:model:class:multiplyname:multiplyparameters:a:3b:2result:6Other supported output formats include JSON (extension.json) and HDF (extension.hdf).Submit models to an HPC queueThe package also provides methods to submit scripts to an high performance compute (HPC)
system.
A simple full script displaying this readsfrommodelrunnerimportmake_model,submit_job@make_modeldefmultiply(a=1,b=2):returna*bif__name__=="__main__":submit_job(__file__,parameters={'a':2},output="data.hdf5",method="foreground")Here, theoutputargument specifies a file to which the results are written, whilemethodchooses how the script is submitted.In particular, this method allows submitting the same script with multiple different
parameters to conduct a parameter study:frommodelrunnerimportmake_model,submit_job@make_modeldefmultiply(a=1,b=2):returna*bif__name__=="__main__":forainrange(5):submit_job(__file__,parameters={'a':a},output=f"data_{a}.hdf5",method="foreground")Note that the safe-guardif __name__ == "__main__"is absolutely crucial to ensure that
jobs are only submitted during the initial run and not when the file is imported again
when the actual jobs start. It is also important to choose unique file names for theoutputflag since otherwise different jobs overwrite each others data.We also support submitting multiple jobs of a parameter study:frommodelrunnerimportmake_model,submit_jobs@make_modeldefmultiply(a=1,b=2):returna*bif__name__=="__main__":submit_jobs(__file__,parameters={'a':range(5)},output_folder="data",method="foreground")Finally, the packages also offers a method to submit a model script to the cluster using
a simple command:python3 -m modelrunner.run script.py. This command also offers multiple options
that can be adjusted using command line arguments:usage: python -m modelrunner.run [-h] [-n NAME] [-p JSON] [-o PATH] [-f] [-m METHOD] [-t PATH] script

Run a script as a job

positional arguments:
  script                The script that should be run

optional arguments:
  -h, --help            show this help message and exit
  -n NAME, --name NAME  Name of job
  -p JSON, --parameters JSON
                        JSON-encoded dictionary of parameters for the model
  -o PATH, --output PATH
                        Path to output file
  -f, --force           Overwrite data if it already exists
  -m METHOD, --method METHOD
                        Method for job submission
  -t PATH, --template PATH
                        Path to template file for submission scriptCollating resultsFinally, the package also provides some rudimentary support for collection results from
many different simulations that have been run in parallel. In particular, the classResultCollectionprovides a class methodfrom_folderto scan a folder for result files.
For instance, the data from the multiple jobs ran above can be collected usingfrommodelrunnerimportResultCollectionresults=ResultCollection.from_folder(".",pattern="data_*.hdf5")print(results.dataframe)This example should print all results using a pandas Dataframe, where each row
corresponds to a separate simulation.DevelopmentThe package is in an early phase and breaking changes are thus likely.