The Blankenstein test project¶
The Blankenstein test project is the default project of SWIM designed for learning and testing. It is initialised using typical GIS data with the m.swim module for GRASS GIS. This tutorial shows how use swimpy with the Blankenstein project as a test and learning example.
Prerequisites and installation¶
For this tutorial you need to have the following software installed:
Python (version 3.x is recommended) together with some basic knowledge
A manager for virtual python environments is recommended such as virtualenv or pyenv
A python IDE is recommended, such as the language-independent and free VS Code
The SWIM model
GRASS module m.swim
For installation of swimpy see the separate installation page.
Project initialisation¶
To initialise the Blankenstein project, open a command line (ideally within a python IDE), go to the SWIM directory and initialise the project, i.e. run SWIM to have some default input and output files to work with:
cd /path/to/swim/project
make
Now we can start python, load the swimpy module, and initialise the test project:
[1]:
# hidden cell to setup
import swimpy, os
%matplotlib inline
project_path = os.path.join(os.path.dirname(swimpy.__file__), '../tests/project')
os.chdir(project_path)
if not os.path.exists('swimpy'):
p = swimpy.project.setup()
[2]:
import swimpy
project = swimpy.Project("./blankenstein_parameters.nml")
The swimpy.Project() call initialises a project instance (here called project). As argument it takes either a path to a swimpy project directory with a single <parameter>.nml file or the path to a specific .nml file. This file is a Fortran Namelist file and contains the configuration parameters of a SWIM project.
The project object represents our model setup and provides a large number of methods and project variables. For instance, one can derive the project, input, output directories, etc.
[3]:
project.resourcedir
project.inputpath
project.outputpath
project.swim
[3]:
'/home/tobias/apps/swimpy_redesign/tests/project/./swim'
Other important project attributes are discussed along this tutorial.
Configuration parameters¶
The project’s configuration parameters inside the Fortran Namelist file, in this case blankenstein_parameters.nml, can be easily accessed and changed:
[4]:
# show parameters
project.config_parameters
[4]:
<config_parameters: blankenstein_parameters.nml>
f90nml.Namelist (
catchment_parameters: Namelist (bsubcatch: True)
landuse_parameters: Namelist ()
crop_parameters: Namelist (iwb: 35)
erosion_parameters: Namelist ()
evapotranspiration_parameters: Namelist (iemeth: 2, radiation_switch: 1)
groundwater_parameters: Namelist ()
input_parameters: Namelist ()
nutrient_parameters: Namelist ()
output_parameters: Namelist ()
river_parameters: Namelist (tlgw: 1)
snow_parameters: Namelist ()
soil_parameters: Namelist ()
subbasin_parameters: Namelist (brunoffdat: True)
time_parameters: Namelist (iyr: 1991)
vegetation_parameters: Namelist (rzmaxup: 7.0, bdormancy: True)
reservoir_parameters: Namelist (brsvmodule: True)
management_parameters: Namelist (bwam_module: True)
)
[5]:
# change parameter
project.config_parameters(iyr=1995)
project.config_parameters
[5]:
<config_parameters: blankenstein_parameters.nml>
f90nml.Namelist (
catchment_parameters: Namelist (bsubcatch: True)
landuse_parameters: Namelist ()
crop_parameters: Namelist (iwb: 35)
erosion_parameters: Namelist ()
evapotranspiration_parameters: Namelist (iemeth: 2, radiation_switch: 1)
groundwater_parameters: Namelist ()
input_parameters: Namelist ()
nutrient_parameters: Namelist ()
output_parameters: Namelist ()
river_parameters: Namelist (tlgw: 1)
snow_parameters: Namelist ()
soil_parameters: Namelist ()
subbasin_parameters: Namelist (brunoffdat: True)
time_parameters: Namelist (iyr: 2000)
vegetation_parameters: Namelist (rzmaxup: 7.0, bdormancy: True)
reservoir_parameters: Namelist (brsvmodule: True)
management_parameters: Namelist (bwam_module: True)
)
Note how this automatically updates blankenstein_parameters.nml! You should also be aware that for parameters that do not appear in the list, default values are automatically used by SWIM.
You can also call the parameter groups individually:
[6]:
project.time_parameters
[6]:
ParamGroupNamelist([('iyr', 2000)])
[7]:
# this also updates blankenstein_parameters.nml
project.time_parameters(nbyr=2)
project.time_parameters
[7]:
ParamGroupNamelist([('iyr', 2000), ('nbyr', 5)])
Note, however, that this will not update the parameter file:
[8]:
project.time_parameters['nbyr'] = 5
But you can update the file explicitly with:
[9]:
project.config_parameters.write()
# you can also write to a new file
project.config_parameters.write('test.nml')
You can also set either individual parameters or whole parameter groups back to default values or just show default values:
[10]:
project.config_parameters.defaults
[10]:
Namelist([('time_parameters', Namelist([('iyr', 2000), ('nbyr', 10)])),
('subbasin_parameters',
Namelist([('climate_input_file', 'climate.csv'),
('brunoffdat', False),
('discharge_input_file', 'discharge.csv'),
('tp5_default', 15.0),
('tp6_default', 22.0),
('tpnyr_default', 54.0),
('obmx',
[31.4400005,
32.7099991,
34.5099983,
34.7299995,
33.9300003,
31.4599991,
28.6599998,
29.0699997,
30.7600002,
30.5599995,
29.9799995,
30.2700005]),
('obmn',
[7.51000023,
8.72000027,
10.3400002,
11.3199997,
11.8199997,
10.6599998,
10.4300003,
10.6400003,
9.40999985,
10.5200005,
9.34000015,
7.88999987]),
('wim',
[7.0,
7.0,
9.0,
9.0,
10.0,
10.0,
10.0,
10.0,
9.0,
9.0,
7.0,
7.0]),
('prw',
[0.0299999993,
0.589999974,
0.0599999987,
0.430000007,
0.0900000036,
0.479999989,
0.140000001,
0.569999993,
0.209999993,
0.560000002,
0.319999993,
0.5,
0.389999986,
0.409999996,
0.430000007,
0.50999999,
0.310000002,
0.419999987,
0.119999997,
0.49000001,
0.0799999982,
0.560000002,
0.0500000007,
0.629999995]),
('rst',
[0.200000003,
0.200000003,
0.899999976,
1.29999995,
4.19999981,
7.5999999,
10.6999998,
10.3000002,
7.4000001,
4.30000019,
1.29999995,
0.300000012])])),
('catchment_parameters', Namelist([('bsubcatch', False)])),
('evapotranspiration_parameters',
Namelist([('ec1', 0.135000005),
('ecal0', 1.0),
('thc0', 1.0),
('idvwk', 0),
('iemeth', 0),
('pit', 58.1300011),
('radiation_switch', 0)])),
('soil_parameters',
Namelist([('ab', 0.0208299998),
('cnum1', 2.0),
('cnum3', 2.0),
('ekc0', 1.0),
('icn', 0),
('ml', 10),
('psp', 0.5),
('rtn', 0.150000006),
('sccor0', 1.0),
('stinco', 0.899999976),
('soil_input_dir', 'input/soils')])),
('groundwater_parameters',
Namelist([('abf0', 0.5), ('gwq0', 0.200000003), ('bff0', 0.0)])),
('reservoir_parameters', Namelist([('brsvmodule', False)])),
('vegetation_parameters',
Namelist([('co2ref', 0.0),
('co2sce', 0.0),
('epco', 1.0),
('ialpha', 0),
('ibeta', 0),
('ic3c4', 0.0),
('rzmaxup', 0.0),
('ub', 3.06500006),
('bdormancy', False)])),
('crop_parameters',
Namelist([('cnum2', 1.0),
('icc', 51),
('idlef', 0),
('ipo', 20),
('isba', 22),
('iwb', 36),
('iwr', 42),
('iww', 45),
('mfe', 7),
('mop', 7),
('nrotyrs', 3)])),
('landuse_parameters',
Namelist([('landuse_input_file', 'landuse.csv'), ('iicep', 1)])),
('snow_parameters',
Namelist([('tsnfall0', 0.0),
('smrate0', 1.0),
('gmrate0', 10.0),
('prcor', 1.0),
('snow1', 0.0),
('xgrad1', 0.0),
('tgrad1', 0.0),
('ulmax0', 1.0),
('rnew', 0.0799999982),
('tmelt0', 0.0),
('bsnowmodule', True)])),
('nutrient_parameters',
Namelist([('degngrw', 0.300000012),
('degnsub', 0.300000012),
('degnsur', 0.0199999996),
('degpsur', 0.0199999996),
('retngrw', 15000.0),
('retnsub', 365.0),
('retnsur', 5.0),
('retpsur', 20.0)])),
('management_parameters',
Namelist([('management_users_input_dir', 'input/water_users'),
('management_input_file', 'management.csv'),
('bwam_module', False)])),
('river_parameters',
Namelist([('roc2_0', 9.0),
('roc4_0', 9.0),
('chnnc0', 1.0),
('chwc0', 1.0),
('prf', 1.0),
('roc1', 0.0),
('roc3', 0.0),
('spcon', 0.0),
('spexp', 1.0),
('storc1', 0.5),
('tlgw', 0),
('tlrch', 1.0),
('evrch', 1.0)])),
('erosion_parameters', Namelist([('chcc0', 1.0), ('chxkc0', 1.0)])),
('output_parameters',
Namelist([('nns', 30),
('nsb', 30),
('nvrch', 18),
('nvsub', 30),
('output_dir', 'output'),
('output_write_interval', 'M'),
('output_float_format', 'f12.4'),
('output_space_index_format', 'i6'),
('output_default_format', 'csv'),
('master_logfile', 'swim.log'),
('log_stderr_level', 'warning'),
('log_stdout_level', 'info'),
('log_file_level', 'info')])),
('input_parameters', Namelist([('input_dir', 'input/')]))])
[11]:
project.vegetation_parameters.defaults
[11]:
Namelist([('co2ref', 0.0),
('co2sce', 0.0),
('epco', 1.0),
('ialpha', 0),
('ibeta', 0),
('ic3c4', 0.0),
('rzmaxup', 0.0),
('ub', 3.06500006),
('bdormancy', False)])
[12]:
# this updates blankenstein_parameters.nml!
project.vegetation_parameters.set_default('rzmaxup')
project.vegetation_parameters
[12]:
ParamGroupNamelist([('rzmaxup', 0.0), ('bdormancy', True)])
For convenience you can get start and end dates of the simulation with:
[13]:
project.config_parameters.start_date
[13]:
datetime.date(2000, 1, 1)
[14]:
project.config_parameters.end_date
[14]:
datetime.date(2009, 12, 31)
Input files¶
The contents of all input files are accessible as project attributes via project.<filename> (<filename> without file extension.), e.g.:
[15]:
# contents of input/catchment.csv
project.catchment
[15]:
| catchment_id | ecal | thc | roc2 | roc4 | cncor | sccor | tsnfall | tmelt | smrate | gmrate | bff | abf | delay | revapc | rchrgc | revapmn | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| station_id | |||||||||||||||||
| BLANKENSTEIN | 1 | 1.0 | 1.0 | 2.0 | 4.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.4 | 10 | 1.0 | 0.01 | 50 | 0.0 | 0.0 | 0.0 |
| HOF | 2 | 1.0 | 1.0 | 2.0 | 4.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.4 | 10 | 1.0 | 0.01 | 50 | 0.0 | 0.0 | 0.0 |
The data is represented by a pandas DataFrame. After editing the input file is updated automatically. However, the write() method may also be called explicitly (e.g. to write to a different file). Editing works as follows:
[16]:
# get value
project.catchment.loc['HOF']['ecal']
[16]:
1.0
[17]:
# edit examples, note how catchment.csv is updated
project.catchment(HOF={'ecal': 1.2, 'delay': 20})
project.catchment(roc2=1, roc4=2)
edits = {'BLANKENSTEIN': {'smrate': 0.3, 'thc': 1.1},
'HOF': {'smrate': 0.5, 'thc': 1.2}}
project.catchment(**edits)
[17]:
| catchment_id | ecal | thc | roc2 | roc4 | cncor | sccor | tsnfall | tmelt | smrate | gmrate | bff | abf | delay | revapc | rchrgc | revapmn | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| station_id | |||||||||||||||||
| BLANKENSTEIN | 1 | 1.0 | 1.1 | 1 | 2 | 1.0 | 1.0 | 0.0 | 0.0 | 0.3 | 10 | 1.0 | 0.01 | 50 | 0.0 | 0.0 | 0.0 |
| HOF | 2 | 1.2 | 1.2 | 1 | 2 | 1.0 | 1.0 | 0.0 | 0.0 | 0.5 | 10 | 1.0 | 0.01 | 20 | 0.0 | 0.0 | 0.0 |
Climate input¶
TODO
GRASS interface¶
Some input files are directly linked to GRASS data and therefore the corresponding project attributes contain additional features. This includes hydrotope, subbasin, subbasin_routing, and catchment.
First, certain GRASS settings need to be defined. In a swimpy project this is typically realised in <project>/swimpy/settings.py and includes the following variables:
grass_dbPath to GRASS project database;grass_locationName of GRASS location, i.e. directory insidegrass_db;grass_mapsetName of Mapset inside GRASS location;grassbinOptional: name of GRASS binary, default isgrass;grass_overwriteOptional,bool: existing maps are overwritten when executing GRASS commands from within swimpy.
Note that this is required by the modelmanager grass plugin that is used internally.
All of the input files with GRASS interface can be updated from GRASS data using the update() method. Internally this executes the GRASS modules m.swim.* that are responsible for the spatial preprocessing of SWIM.
For instance, the following command runs m.swim.hydrotopes and updates input file hydrotope.csv:
[18]:
project.hydrotope.update(verbose=False)
Parameters to the m.swim.* modules have to be given in the swimpy/settings.py as a Python dictionary named grass_setup. For the Blankenstein tutorial it looks like this:
grass_setup = dict(subbasin_id = "subbasins", subbasins = "subbasins",
elevation="elevation@PERMANENT",
stations="stations@PERMANENT",
upthresh=50, lothresh=1.6, streamthresh=200,
minmainstreams=50, contours=200,
predefined="reservoirs@PERMANENT",
landuse_id="landuse@PERMANENT",
soil_id="soil@PERMANENT")
If you want to run update() with different parameter values or with additional optional parameters, e.g. for testing, you can specify them directly, e.g. project.hydrotope.update(contours=100).
Note that project.subbasin.update() runs the whole m.swim.* preprocessing chain and updates all involved input files (hydrotope.csv, subbasin.csv, subbasin_routing.csv, and catchment.csv). If you only want to run m.swim.subbasins you can do so via project.subbasin.create().
WARNING: Do not apply GRASS functions from Python in a mapset where a GRASS session is already running! This will produce an error.
Output files¶
An overview of output files can be given with attribute output_files:
[19]:
project.output_files
[19]:
<output_files: input/output.nml>
Files with variables in directory 'output':
dict {
subbasin_label_daily_selected_stations_discharge: [discharge]
subbasin_daily_river_discharge: [discharge, river_runoff]
hydrotope_monthly_gis: [etp, eta, groundwater_recharge, precipitation, surface_runoff]
hydrotope_annual_gis: [etp, eta, groundwater_recharge, precipitation, surface_runoff, crop_yield, glacier_weq]
catchment_daily_bad_prn: [snowfall_weq, precipitation, tmean, surface_runoff, subsurface_runoff, percolation, groundwater_recharge, soil_water_index, snow_depth_weq, glacier_weq]
hydrotope_label_daily_crop_out: [vegetation_water_stress, vegetation_temperature_stress, heat_unit_fraction, biomass_total, leaf_area_index, root_depth]
hydrotope_label_annual_cropyld: [crop_yield]
hydrotope_label_daily_htp_prn: [precipitation, surface_runoff, subsurface_runoff, percolation, etp, transpiration, soil_evaporation, eta, soil_water_index, leaf_area_index, biomass_total, root_depth, vegetation_water_stress, heat_unit_fraction, soil_water_content]
}
This is, by default, connected to the Fortran Namelist input/output.nml where the different output files are defined by name, space, time, and a list of variables. Herein, name can be freely chosen, space may be one of hydrotope_label, hydrotope, subbasin_label, subbasin, or catchment and time one of daily, monthly, or annual. The variables can be chosen as implemented in SWIM. For more details, see the SWIM manual. By default,
a SWIM run stores output files as output/<space>_<time>_<name>.csv with columns time, <space> (e.g. hydrotope IDs), and the defined variables.
Generic output parameters, such as output directory, etc., are defined in project.config_parameters('output_parameters'), see defaults:
[20]:
project.config_parameters.defaults['output_parameters']
[20]:
Namelist([('nns', 30),
('nsb', 30),
('nvrch', 18),
('nvsub', 30),
('output_dir', 'output'),
('output_write_interval', 'M'),
('output_float_format', 'f12.4'),
('output_space_index_format', 'i6'),
('output_default_format', 'csv'),
('master_logfile', 'swim.log'),
('log_stderr_level', 'warning'),
('log_stdout_level', 'info'),
('log_file_level', 'info')])
New output files can be defined directly in input/output.nml or via swimpy (which immediately updates input/output.nml):
[21]:
# space: hydrotope, time: monthly, name: testevap,
# variables: etp, eta
project.output_files(hydrotope_monthly_testevap=['etp', 'eta'])
Data from output files can be accessed as project attribute:
[22]:
# Data of output/hydrotope_annual_gis.csv
project.hydrotope_annual_gis
[22]:
| variable | crop_yield | ... | surface_runoff | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hydrotope | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ... | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 |
| time | |||||||||||||||||||||
| 1991 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 17212.2324 | 19070.6367 | 17870.6953 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 13596.5225 | 0.0 | 0.0 | 13596.5225 |
| 1992 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 24460.3848 | 25620.9336 | 24620.2266 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 15540.0762 | 0.0 | 0.0 | 15540.0762 |
| 1993 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22603.8867 | 22661.7090 | 22611.9570 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 14608.4375 | 0.0 | 0.0 | 14608.4375 |
| 1994 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 21975.0820 | 23983.8184 | 22624.8770 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 16330.0938 | 0.0 | 0.0 | 16330.0938 |
| 1995 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 21861.9512 | 21964.5332 | 21872.5938 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 15165.6904 | 0.0 | 0.0 | 15165.6904 |
| 1996 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 18816.7988 | 18816.8535 | 18816.8027 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12823.5654 | 0.0 | 0.0 | 12823.5654 |
| 1997 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22561.8008 | 22561.8125 | 22561.8008 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 14806.8408 | 0.0 | 0.0 | 14806.8408 |
| 1998 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22799.5391 | 22799.5859 | 22799.5391 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 15160.4570 | 0.0 | 0.0 | 15160.4570 |
| 1999 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23100.4199 | 23136.3262 | 23102.9297 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 15690.5752 | 0.0 | 0.0 | 15690.5752 |
| 2000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 23239.3340 | 23239.8203 | 23239.6602 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 16536.8750 | 0.0 | 0.0 | 16536.8750 |
10 rows × 1274 columns
The data is represented as pd.DataFrame with associated indexing methods, e.g.:
[23]:
project.subbasin_daily_river_discharge.loc['2000-12-27']['river_runoff']
[23]:
subbasin
1 0.0224
2 0.0157
3 0.0133
4 4.2791
5 0.0157
6 0.0151
7 0.0000
8 0.0166
9 0.0000
10 0.0854
11 0.0867
Name: 2000-12-27, dtype: float64
TODO: plot method
Output data can also be exported to GRASS via to_grass() method. This creates individual raster files for selected timesteps and variables. Depending on the output file this can be realised on the catchment, subbasin, or hydrotope level as follows:
[24]:
# 4 raster files in GRASS at hydrotope level
project.hydrotope_annual_gis.to_grass(
variable=['surface_runoff', 'crop_yield'],
timestep=['1995', '1996'],
prefix='swim_hydrotope_output')
Created raster swim_hydrotope_output_1995_surface_runoff
Lösche raster <swim_hydrotope_output_1995_surface_runoff__int>
Created raster swim_hydrotope_output_1996_surface_runoff
Lösche raster <swim_hydrotope_output_1996_surface_runoff__int>
Created raster swim_hydrotope_output_1995_crop_yield
Lösche raster <swim_hydrotope_output_1995_crop_yield__int>
Created raster swim_hydrotope_output_1996_crop_yield
Lösche raster <swim_hydrotope_output_1996_crop_yield__int>
Default TGIS driver / database set to:
driver: sqlite
database: $GISDBASE/$LOCATION_NAME/$MAPSET/tgis/sqlite.db
WARNUNG: Temporal database connection defined as:
/home/tobias/apps/swimpy_redesign/tests/grassdb/utm32n/swim/tgis/sqlite.db
But database file does not exist.
Creating temporal database:
/home/tobias/apps/swimpy_redesign/tests/grassdb/utm32n/swim/tgis/sqlite.db
0 100
0 100
Created space-time raster dataset swim_hydrotope_output_surface_runoff
0 100
0 100
Created space-time raster dataset swim_hydrotope_output_crop_yield
Run SWIM and store results¶
To run SWIM with the current setup simply do:
[1]:
run = project.run(save = True, tags = "test01", notes = "A first test run",
files = ['subbasin_label_daily_selected_stations_discharge'])
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/home/tobias/apps/swimpy_redesign/docs/tutorial.ipynb Zelle 60 in <cell line: 1>()
----> <a href='vscode-notebook-cell:/home/tobias/apps/swimpy_redesign/docs/tutorial.ipynb#Y113sZmlsZQ%3D%3D?line=0'>1</a> run = project.run(save = True, tags = "test01", notes = "A first test run",
<a href='vscode-notebook-cell:/home/tobias/apps/swimpy_redesign/docs/tutorial.ipynb#Y113sZmlsZQ%3D%3D?line=1'>2</a> files = ['subbasin_label_daily_selected_stations_discharge'])
NameError: name 'project' is not defined
This runs SWIM and, as save = True (the default), stores information about the run together with the specified tags and notes (optional) in the browser database inside the swimpy directory. This can be useful to keep track of subsequent model runs and compare results or parameters. In this example we also archived output file subbasin_label_daily_selected_stations_discharge.csv inside the swimpy directory.
Some run statistics is accessible via the run object, e.g.:
[ ]:
run.notes
[ ]:
run.run_time
As well as saved output files (i.e. only those given in run(files=[...])!):
[ ]:
run.subbasin_label_daily_selected_stations_discharge
Previous saved runs can be derived, for instance, via:
run = project.browser.runs.last()
run = project.browser.runs.first()
run = project.browser.runs.get(id=2) # saved run number 2
For more information on the run() method see also save_run() which is called inside run() and to which arguments can be passed.
If you want to run SWIM on a cluster as a job (so far it works with slurm as on the PIK cluster), adjust the cluster_slurmargs dictionary in settings.py as needed and run the model with project.run(cluster='job_name').
More flexibility is offered via the cluster argument of project.run() or the project.cluster attribute. To prepare a slum job there are the following possibilities:
[ ]:
project.cluster('testjob', 'run', dryrun=True, somearg=123)
project.run(cluster=dict(jobname='runtestjob', dryrun=True))
project.cluster.submit_job('submit_job_test',
'import swimpy; swimpy.Project().run()',
workdir='project/', dryrun=True)
This creates Python jobscripts testjob.py and runtestjob.py in swimpy/cluster/ and submit_job_test.py in the project directory. Have a look at the files to understand how the command works. Note that dryrun=False (default!) would submit the job right away. Besides, project.cluster() internally calls project.cluster.submit_job() with some preprocessing.
It is also possible to conduct multiple SWIM runs in parallel:
[ ]:
# apply SWIM with different values for parameter smrate
args = [dict(smrate=i) for i in [0.1, 0.3, 0.6]]
runs = project.cluster.run_parallel(
clones=3, args=args, preprocess='catchment',
prefix='test', parallelism='mp')
Observe how SWIM runs three times on your machine on different CPU cores (e.g. via Shell command ps -A -o pid,psr,pcpu,%mem,cmd | grep swim). To create 3 jobs on the cluster use parallelism='jobs'.
Note that args (i.e. the value of smrate) has to be defined relative to preprocess, i.e. in this case project.catchment. To change a parameter in a different input file try, for instance, project.cluster.run_parallel(args=[{'rzmaxup': 5.0}], preprocess='config_parameters').
Working with the command-line interface¶
Instead of using swimpy in Python it is also possible to use its functionalities via the command line. All project functions are available as swimpy arguments including help. However, note that this only works inside an initialised swimpy project directory!
[ ]:
cd path/to/swimproject
swimpy setup # initialise
swimpy -h # all available functions
TODO …
Check changes in output¶
Imagine you changed certain parameters or even the source code of SWIM and you wonder if and how this might influence your output. One quick check is the output_sums test:
[ ]:
# define current output as benchmark
swimpy test output_sums -t create
# run swim again after changes
./swim <config>.nml
# compare new output with benchmark
swimpy test output_sums -t compare