Run ensemble RHESSys model on HPC through CyberGIS Computing Service

Introduction

RHESSys (Regional Hydro-Ecological Simulation System) is a GIS-based, terrestrial ecohydrologic modeling framework designed to simulate carbon, water and nutrient fluxes at the watershed scale. RHESSys models the temporal and spatial variability of ecosystem processes and interactions at a daily time step over multiple years by combining a set of physically based process models and a methodology for partitioning and parameterizing the landscape. Detailed model algorithms are available in Tague and Band (2004)8%3C1:RRHSSO%3E2.0.CO;2).

This notebook demonstrates how to configure an ensemble RHESSys simulation with pyRHESSys, submit it to a HPC resource for execution through CyberGIS Computing Service, visualize model outputs with various tooks integrated in the CyberGIS-Jupyter for Water (CJW).

Watershed: Coweeta Subbasin 18, NC

The model used here is based off of a pre-built RHESSys model for the Coweeta Subbasin 18 (0.124 $km^2$), a subbasins in Coweeta watershed (16 $km^2$), from the Coweeta Long Term Ecological Research (LTER) Program.

Set up local RHESSys model run

Extract prebuilt model files

In [1]:
import tempfile
import shutil, os
workspace_dir = os.path.join(os.getcwd(), 'workspace')
!mkdir -p {workspace_dir}
proj_folder_name = "CoweetaSub18_30m"
unzip_dir = tempfile.mkdtemp(dir=workspace_dir)
proj_folder = os.path.join(unzip_dir, proj_folder_name)
model_folder = os.path.join(unzip_dir, proj_folder_name, "model")
!mkdir -p {model_folder}
!unzip -o {proj_folder_name}.zip -d {model_folder}
output_folder = os.path.join(model_folder, "output")
!mkdir -p {output_folder}
Archive:  CoweetaSub18_30m.zip
   creating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/cwt.tmin  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/cwt.rain  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/cwt.tmax  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/cwt.base  
   creating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/zone_setting1.def  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/stratum_deciduous.def  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/landuse_setting1.def  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/soil_sandy_loam_12.def  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/stratum_evergreen.def  
 extracting: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/basin_basin.def  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/soil_loam_9.def  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/hill_setting1.def  
   creating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/flows/
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/flows/subflow.txt  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/flows/surfflow.txt  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/lulcFrac10m.csv  
   creating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/obs/
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/obs/climate_coweeta_ws18.csv  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/obs/streamflow_coweeta_ws18.csv  
   creating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/.DS_Store  
 extracting: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/__keep_folder.txt  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/soil_cat_mukey.csv  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/soil_mukey_rhessys.csv  
   creating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/tecfiles/
 extracting: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/tecfiles/tec_daily.txt  
   creating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/worldfiles/
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/worldfiles/worldfile  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/worldfiles/worldfile.csv  
  inflating: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/worldfiles/worldfile.hdr  

Localize paths referenced in model files

In [2]:
import os, sys
def replace_string(file, current_string, new_string):
    if not os.path.isfile(file):
        print ("Error on replace_string, not a regular file: "+file)
        sys.exit(1)
    f1=open(file,'r').read()
    f2=open(file,'w')
    m=f1.replace(current_string,new_string)
    f2.write(m)

original_path = "<BASEDIR>"
replace_string(os.path.join(model_folder,"worldfiles/worldfile.hdr"), original_path, proj_folder)
replace_string(os.path.join(model_folder,"clim/cwt.base"), original_path, proj_folder)

Use pyRHESSys to configure and provision initial values for the model

In [3]:
# import pyrhessys library 
import pyrhessys as pr
import os, shutil
PROJECT_NAME = "CoweetaSub18_30m"
CURRENT_PATH = os.getcwd()
#PROJECT_DIR = os.path.join(CURRENT_PATH, PROJECT_NAME)
PROJECT_DIR = proj_folder
# Define RHESsys model iput directory
MODEL_DIR = os.path.join(PROJECT_DIR, 'model')
# Get RHESSys executable full path
EXECUTABLE = os.popen('which rhessysEC.7.2').read().split("\n")[0]
# create pyRHESSys Simulation Object
r = pr.Simulation(EXECUTABLE, MODEL_DIR)
# Set simulation period
start_date = '2003 01 01 01'
end_date = '2005 12 31 01'
# Set Initial parameter values
r.parameters['version'] = 'rhessysEC.7.2'
r.parameters['start_date'] = start_date
r.parameters['end_date'] = end_date
r.parameters['gw1'] = '0.0432482895012945'
r.parameters['gw2'] = '0.137155388656538'
r.parameters['s1'] = '1.0'
r.parameters['s2'] = '0.4'
r.parameters['s3'] = '1.6'
r.parameters['snowEs'] = '1.17543162591755'
r.parameters['snowTs'] = '0.527982610510662'
r.parameters['sv1'] = '3.0'
r.parameters['sv2'] = '90.0'
r.parameters['svalt1'] = '0.928032172983822'
r.parameters['svalt2'] = '0.955452497987305'
r.parameters['locationid'] = '0'
# Create a initial parameters json file
import json
with open(os.path.join(model_folder, 'init_parameters.json'), 'w') as outfile:
    json.dump(r.parameters, outfile)
f = open(os.path.join(model_folder, 'init_parameters.json'), 'r')
data = json.load(f)
data
Out[3]:
{'version': 'rhessysEC.7.2',
 'start_date': '2003 01 01 01',
 'end_date': '2005 12 31 01',
 'gw1': '0.0432482895012945',
 'gw2': '0.137155388656538',
 's1': '1.0',
 's2': '0.4',
 's3': '1.6',
 'snowEs': '1.17543162591755',
 'snowTs': '0.527982610510662',
 'sv1': '3.0',
 'sv2': '90.0',
 'svalt1': '0.928032172983822',
 'svalt2': '0.955452497987305',
 'locationid': '0',
 'basin_id': 1,
 'hillslope_id': 1,
 'zone_id': 1,
 'patch_id': 1}

Execute a single local run on Jupyter

In [4]:
r.run("local")
r.status
cd /data/cigi/cjw-easybuild/easybuild/software/RHESSysEastCoast/7.2.0-foss-2019b/bin; ./rhessysEC.7.2 -st 2003 01 01 01 -ed 2005 12 31 01 -b -gwtoriparian -t /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/tecfiles/tec_daily.txt -w /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/worldfiles/worldfile -whdr /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/worldfiles/worldfile.hdr -r /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/flows/subflow.txt /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/flows/surfflow.txt -pre /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run -gw 0.0432482895012945 0.137155388656538 -s 1.0 0.4 1.6 -snowEs 1.17543162591755 -snowTs 0.527982610510662 -sv 3.0 90.0 -svalt 0.928032172983822 0.955452497987305
starting: 2003 1 1 1

 Running with hillslope gw routed to riparian areas
 gw scalers 0.000000 0.137155 0.043248
Reading specified world file header /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/worldfiles/worldfile.hdr
Reading /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/basin_basin.def
Reading /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/hill_setting1.def
Reading /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/zone_setting1.def
soil,9,7.376043,84.694725,0.440652
soil,12,7.305377,208.407352,0.149043
Reading /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/landuse_setting1.def
Reading /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/stratum_deciduous.def
Reading /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/defs/stratum_evergreen.def

Constructed fire defaults

Constructing base stations
 Reading Base station 101 [278391.710000 3882439.500000 638.000000, 2.000000 22.900000]
checking annua /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/na
checking monthly /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/na
checking daily /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/cwt
 Non critical sequences 0
checking hourly /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/clim/na

 Finished constructing base stations

 Constructing world 1

 Constructing basins
	Reading surface routing table
hillslope riparian: 2158 0.000000
hillslope riparian: 2157 0.000000
hillslope riparian: 2160 0.000000
hillslope riparian: 2159 0.000000
hillslope riparian: 2155 0.000000
hillslope riparian: 2156 0.000000
Year 2003
Year 2004
time cost = 95 seconds

Out[4]:
'Success'

Plot local run output

In [5]:
# check SUMMA output file 
name_list = os.listdir(output_folder)
full_list = [os.path.join(output_folder,i) for i in name_list if i.endswith(".daily")]
sorted_list = sorted(full_list)
# change the format 
sim_start_date = start_date.replace(" ", "-")
sim_end_date = end_date.replace(" ", "-")
import pandas as pd
sim_output = []
name_lists = []
for lists in sorted_list:
    plot_data = pd.read_csv(os.path.join(output_folder, lists.split("/")[-1].split("_")[0] +'_run_basin.daily'), delimiter=" ")
    name_lists.append(lists.split("/")[-1].split("_")[0])
    date_index = pd.date_range(sim_start_date, sim_end_date, freq='1D')
    plot_data.insert(loc=0, column='Date', value=date_index[:-1].values)
    plot_data.set_index('Date')
    sim_output.append(plot_data)
In [6]:
import seaborn as sns
import matplotlib.pyplot as plt
def plot_output(sim_data, sim_date_col_name, name_list, num_config, sim_output_variable, pre_trim: int=0, post_trim: int=-1):
    LINE_STYLES = ['solid', 'dashed', 'dashdot', 'dashdot', 'dotted']
    NUM_STYLES = len(LINE_STYLES)

    sns.reset_orig()  # get default matplotlib styles back
    clrs = sns.color_palette("bright", n_colors=num_config)  # a list of RGB tuples
    fig, ax = plt.subplots(1,figsize=(15,7),linewidth=3.0)
    for i in range(num_config):
        lines = ax.plot(sim_data[i][sim_date_col_name][pre_trim:post_trim].values, sim_data[i][sim_output_variable][pre_trim:post_trim].values)
        lines[0].set_color(clrs[i])
        lines[0].set_linestyle(LINE_STYLES[i%NUM_STYLES])
    y_axis = "Total Stream Outflow (mm)"
    # add x, y label
    ax.set_xlabel('Date', fontsize=15)
    ax.set_ylabel(y_axis, fontsize=15)
    # show up the legend
    ax.tick_params(labelsize=15)
    ax.grid('on')
    fig.legend(labels=name_list, bbox_to_anchor=(0.9, 0.9), loc='upper left')
    plt.show()
plot_output(sim_output, 'Date', name_lists, len(sim_output), 'streamflow', pre_trim =100, post_trim=-1)

Set up ensemble RHESSys model

Change file path referenced in local model to placeholder <BASEDIR> (to be localized on HPC)

In [7]:
# remove old output files
! rm -rvf {output_folder}/*
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/__keep_folder.txt'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_basin.daily'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_basin.hourly'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_basin.monthly'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_basin.yearly'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_hill_setting1_hillslope.params'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_landuse_setting1_landuse.params'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_stratum_deciduous_stratum.params'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_stratum_evergreen_stratum.params'
removed '/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/model/output/rhessys_run_zone_setting1_zone.params'
In [8]:
new_path = "<BASEDIR>"
replace_string(os.path.join(model_folder,"worldfiles/worldfile.hdr"), proj_folder, new_path)
replace_string(os.path.join(model_folder,"clim/cwt.base"), proj_folder, new_path)
In [9]:
%%writefile installTestCases_local.sh
#!/bin/bash

# install the test cases that can be run with the ./runTestCases.sh
# the script creates the necessary output directories and sets the
# paths in the model input files.

# check whether the settings, output and/or testCases_data directories already
# exist to prevent overwriting directories in which a user may have made changes
if [ -d model/clim_copy -o -d model/worldfiles_copy ]
    then
        echo 'settings, output and/or testCases_data directories already exist.'
        echo 'Please remove or move the settings, output and testCases_data'
        echo 'directories to prevent overwriting'
        exit 1
fi
#cp -rp ${DIR}_org ${DIR}
# create the paths for the output files
#mkdir -p output

# modify the paths in the model input file
# we create a new directories to preserve copies of the original files in case
# something goes wrong
BASEDIR=`pwd`
for DIR in model/clim model/worldfiles
    do
        cp -rp ${DIR} ${DIR}_copy
        for file in `grep -l '<BASEDIR>' -R ${DIR}`
            do
                sed "s|<BASEDIR>|${BASEDIR}|" $file > junk
                mv junk $file
            done
		rm -rf model/clim_copy model/clim, model/worldfiles_copy
    done
echo "TestCases installed"
Writing installTestCases_local.sh
In [10]:
shutil.copy('installTestCases_local.sh', proj_folder)
Out[10]:
'/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/tmp7wop17ea/CoweetaSub18_30m/installTestCases_local.sh'

Build ensemble using pyRHESSys

  • S1: (m) decay of saturated hydraulic conductivity with depth
  • S2: (K) controls conductivity over the surface
  • SV1: (m) vertical decay of hydraulic conductivity with depth
  • SV2: (K) vertical conductivity at the surface
In [11]:
# create safe_arange to limit certain length of number
import numpy as np
def safe_arange(start, stop, step):
    a = np.arange(start, stop, step)
    result =[]
    for i in a:
        par = round(i, 10)
        result = np.append(result, par)
    return result
# set start value, end value, interval value for each parameters
param_options = {
   's1' : safe_arange(0.01,  20.0, 10.0),
   's2' : safe_arange(1.0,  100.0, 50.0),
   'sv1': safe_arange(0.01,  20.0, 10.0),
   'sv2': safe_arange(1.0,  100.0, 50.0),
}
# create ensemble combination using parameter setting as config and check the number of ensemble combination
config = pr.ensemble.parameter_product(param_options)
len(config)
Out[11]:
16
In [12]:
import json
with open(os.path.join(proj_folder, 'rhessys_options.json'), 'w') as outfile:
    json.dump(config, outfile)

# check ensemble parameters    
print("Number of ensemble runs: {}".format(len(config)))
print(json.dumps(config, indent=4, sort_keys=True)[:800])
print("...")
Number of ensemble runs: 16
{
    "++s1=0.01++s2=1.0++sv1=0.01++sv2=1.0++": {
        "parameters": {
            "s1": 0.01,
            "s2": 1.0,
            "sv1": 0.01,
            "sv2": 1.0
        }
    },
    "++s1=0.01++s2=1.0++sv1=0.01++sv2=51.0++": {
        "parameters": {
            "s1": 0.01,
            "s2": 1.0,
            "sv1": 0.01,
            "sv2": 51.0
        }
    },
    "++s1=0.01++s2=1.0++sv1=10.01++sv2=1.0++": {
        "parameters": {
            "s1": 0.01,
            "s2": 1.0,
            "sv1": 10.01,
            "sv2": 1.0
        }
    },
    "++s1=0.01++s2=1.0++sv1=10.01++sv2=51.0++": {
        "parameters": {
            "s1": 0.01,
            "s2": 1.0,
            "sv1": 10.01,
            "sv2": 51.0
        }
    },
    "++s1=0.01++s2=51.0++sv1=0.01++sv2=1.0++": {
     
...

Submit ensemble model to HPC through CyberGIS Computing Service

In [13]:
from job_supervisor_client import *
communityRHESSysSession = Session('rhessys', isJupyter=True)
communityRHESSysJob = communityRHESSysSession.job() # create new job
communityRHESSysJob.upload(proj_folder)
📃 created session constructor file [job_supervisor_constructor_rhessys.json]
Out[13]:
{'file': '1630338963xdtv'}
In [14]:
communityRHESSysJob.submit(payload={
    "node": 16,
    "machine": "keeling"
})
✅ job registered with ID: 163033896392v8
Out[14]:
<job_supervisor_client.Job.Job at 0x7f2ee9bef910>

Montior job status

In [15]:
communityRHESSysJob.events(liveOutput=True)
📮Job ID: 163033896392v8
📍Destination: rhessys

types message time
JOB_QUEUED job [163033896392v8] is queued, waiting for registration 2021-08-30T15:56:03.276Z
JOB_REGISTERED job [163033896392v8] is registered with the supervisor, waiting for initialization2021-08-30T15:56:04.054Z
RHESSys_HPC_CONNECTEDconnected to HPC 2021-08-30T15:56:19.862Z
RHESSys_HPC_SUBMITTEDsubmitted RHESSys job to HPC 2021-08-30T15:56:19.862Z
JOB_INITIALIZED initialized RHESSys job in HPC job queue with remote_id 347567 2021-08-30T15:56:19.862Z
JOB_ENDED RHESSys job with remote_id 347567 completed 2021-08-30T15:59:29.640Z

Retrieve ensemble output

In [16]:
job_dir = os.path.join(workspace_dir, "{}".format(communityRHESSysJob.id))
!mkdir -p {job_dir}/output
communityRHESSysJob.download(job_dir)
file successfully downloaded under: /home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/163033896392v8.zip
Out[16]:
'/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/163033896392v8.zip'
In [17]:
!cd {job_dir} && unzip -d output *.zip

# check output directory
output_path = os.path.join(job_dir, "output")
# check SUMMA output file 
name_list = os.listdir(output_path)
full_list = [os.path.join(output_path,i) for i in name_list if i.endswith(".daily")]
sorted_list = sorted(full_list)

for f in sorted_list:
    print(f)
print("Number of daily output files: {}".format(len(sorted_list)))
Archive:  163033896392v8.zip
  inflating: output/++s1=0.01++s2=1.0++sv1=0.01++sv2=1.0++_basin.daily  
  inflating: output/++s1=0.01++s2=1.0++sv1=0.01++sv2=51.0++_basin.daily  
  inflating: output/++s1=0.01++s2=1.0++sv1=10.01++sv2=1.0++_basin.daily  
  inflating: output/++s1=0.01++s2=1.0++sv1=10.01++sv2=51.0++_basin.daily  
  inflating: output/++s1=0.01++s2=51.0++sv1=0.01++sv2=1.0++_basin.daily  
  inflating: output/++s1=0.01++s2=51.0++sv1=0.01++sv2=51.0++_basin.daily  
  inflating: output/++s1=0.01++s2=51.0++sv1=10.01++sv2=1.0++_basin.daily  
  inflating: output/++s1=0.01++s2=51.0++sv1=10.01++sv2=51.0++_basin.daily  
  inflating: output/++s1=10.01++s2=1.0++sv1=0.01++sv2=1.0++_basin.daily  
  inflating: output/++s1=10.01++s2=1.0++sv1=0.01++sv2=51.0++_basin.daily  
  inflating: output/++s1=10.01++s2=1.0++sv1=10.01++sv2=1.0++_basin.daily  
  inflating: output/++s1=10.01++s2=1.0++sv1=10.01++sv2=51.0++_basin.daily  
  inflating: output/++s1=10.01++s2=51.0++sv1=0.01++sv2=1.0++_basin.daily  
  inflating: output/++s1=10.01++s2=51.0++sv1=0.01++sv2=51.0++_basin.daily  
  inflating: output/++s1=10.01++s2=51.0++sv1=10.01++sv2=1.0++_basin.daily  
  inflating: output/++s1=10.01++s2=51.0++sv1=10.01++sv2=51.0++_basin.daily  
  inflating: output/slurm-347567.out  
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=0.01++s2=1.0++sv1=0.01++sv2=1.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=0.01++s2=1.0++sv1=0.01++sv2=51.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=0.01++s2=1.0++sv1=10.01++sv2=1.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=0.01++s2=1.0++sv1=10.01++sv2=51.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=0.01++s2=51.0++sv1=0.01++sv2=1.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=0.01++s2=51.0++sv1=0.01++sv2=51.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=0.01++s2=51.0++sv1=10.01++sv2=1.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=0.01++s2=51.0++sv1=10.01++sv2=51.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=10.01++s2=1.0++sv1=0.01++sv2=1.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=10.01++s2=1.0++sv1=0.01++sv2=51.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=10.01++s2=1.0++sv1=10.01++sv2=1.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=10.01++s2=1.0++sv1=10.01++sv2=51.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=10.01++s2=51.0++sv1=0.01++sv2=1.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=10.01++s2=51.0++sv1=0.01++sv2=51.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=10.01++s2=51.0++sv1=10.01++sv2=1.0++_basin.daily
/home/jovyan/work/Downloads/631914af4b8344e5a78e647255cf1d13/631914af4b8344e5a78e647255cf1d13/data/contents/workspace/163033896392v8/output/++s1=10.01++s2=51.0++sv1=10.01++sv2=51.0++_basin.daily
Number of daily output files: 16

Check ensemble output

When you plot RHESSys daily output, you can use output variables (RHESSys Output Abbreviation) from the table below

Basin Daily Output

RHESSys Output Abbreviation Description Units
pot_surface_infil Rain Throughfall mm
snow_thr Snow Throughfall mm
sat_def_z Saturation Deficit with depth mm of depth
sat_def Saturation Deficit - volume mm of water
rz_storage Rooting Zone Storage mm of water
unsat_stor Unsaturated Storage mm
rz_drainage Rooting Zone Drainage mm
unsat_drain Unsaturated Storage mm
cap Capillary Rise mm
evap Evaporation mm
snowpack Snow Water Equivalent (SWE) mm
trans Transpiration mm
baseflow Baseflow mm
return Return flow mm
streamflow Total Stream Outflow mm (normalized by basin area)
psn Net Photosynthesis kgC/m2
lai Leaf Area Index m2/m2
gw.Qout Groundwater Output mm
gw.storage Groundwater Store mm
detention_store Detention Store mm
%sat_area Percent Saturated Area m2/m2
litter_store Litter intercepted water Store m2/m2
canopy_store Canopy Intercepted water Store m2/m2
%snow_cover Percent Snow Cover m2/m2
snow_subl Snow Sublimation
trans_var Spatial variation in transpiration
acc_trans
acctransv_var
pet Potential Evapotranspiration mm
dC13
precip Precipitation mm
pcp_assim
mortf Fraction of Basin that have tree mortality
tmax Maximum Temperature °C
tmin Minimum Temperature °C
tavg Average Temperature °C
vpd Vapor Pressure Deficit Pa
snowfall Snowfall
recharge _Recharge of water to soil
gpsn Gross Photosynthesis kgC/m2
resp Respiration kgC/m2
gs Canopy Conductance mm/s?
rootdepth Rooting depth
plantc Plant Carbon kgC/m2
snowmelt Snow Melt
canopysubl Canopy Sublimation
routedstreamflow
canopy_snow Snow Intercepted on Canopy
height Canopy height
evap_can Canopy Evaporation?
evap_lit Litter Evaporation_
evap_soil Soil Evaporation_
litrc Litter Carbon_
Kdown Downward (from atmosphere) Direct Shortwave Radiation_
Ldown Downward (from atmosphere) Longwave Radiation_
Kup Reflected (upward) Shortwave Radiation_
Lup Reflected (upward) Longwave Radiation_
Kstar_can Absorbed shortwave by canopy
Kstar_soil Absorbed shortwave by soil
Kstar_snow Absorbed shortwave bysnow
Lstar_can Absorbed longwave by canopy
Lstar_soil Absorbed longwave by soil
Lstar_snow Absorbed longwave by snow
LE_canopy Latent heat evaporated by canopy
LE_soil La
LE_snow
Lstar_strat
canopydrip
ga Aerodynamic Conductance mm/s

Visualize ensemble output

In [18]:
# change the format 
sim_start_date = start_date.replace(" ", "-")
sim_end_date = end_date.replace(" ", "-")
import pandas as pd
sim_output = []
name_lists = []
for lists in sorted_list:
    plot_data = pd.read_csv(os.path.join(output_path, lists.split("/")[-1].split("_")[0] +'_basin.daily'), delimiter=" ")
    name_lists.append(lists.split("/")[-1].split("_")[0])
    date_index = pd.date_range(sim_start_date, sim_end_date, freq='1D')
    plot_data.insert(loc=0, column='Date', value=date_index[:-1].values)
    plot_data.set_index('Date')
    sim_output.append(plot_data)
sim_output[0]
Out[18]:
Date day month year basinID rain_thr snow_thr sat_def_z sat_def rz_storage ... apipedrainNH4 apipedrainDON apipedrainDOC lawnIrrigated septicQ laiNontree PAR unsat_cap unsat_fc rtz_fc
0 2003-01-01 01:00:00 1 1 2003 1 4.821835 0.0 80.462333 23.939074 11.682887 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.957156e+06 -319.944541 0.182463 22.840998
1 2003-01-02 01:00:00 2 1 2003 1 53.744951 0.0 101.896452 29.752340 15.626286 ... 0.0 0.0 0.0 0.0 0.0 0.0 9.716394e+06 -314.131275 3.308670 24.354558
2 2003-01-03 01:00:00 3 1 2003 1 12.287530 0.0 168.384869 47.837514 24.634302 ... 0.0 0.0 0.0 0.0 0.0 0.0 6.740082e+04 -296.046101 11.305803 31.081844
3 2003-01-04 01:00:00 4 1 2003 1 9.333805 0.0 236.122924 65.699550 30.196734 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.468925e+07 -278.184065 21.017158 35.303741
4 2003-01-05 01:00:00 5 1 2003 1 29.811715 0.0 232.562720 64.050252 26.120522 ... 0.0 0.0 0.0 0.0 0.0 0.0 2.051277e+07 -279.833363 21.913954 32.302560
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1090 2005-12-26 01:00:00 26 12 2005 1 5.757633 0.0 707.648765 182.891085 53.308038 ... 0.0 0.0 0.0 0.0 0.0 0.0 4.965091e+06 -160.992530 85.810891 56.042972
1091 2005-12-27 01:00:00 27 12 2005 1 2.492297 0.0 691.823964 177.988734 50.247728 ... 0.0 0.0 0.0 0.0 0.0 0.0 2.356672e+07 -165.894882 84.044230 53.506870
1092 2005-12-28 01:00:00 28 12 2005 1 11.775967 0.0 663.039892 170.330309 47.446539 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.645252e+07 -173.553306 81.374128 50.010583
1093 2005-12-29 01:00:00 29 12 2005 1 0.110947 0.0 658.066540 170.597053 50.843952 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.460504e+06 -173.286563 78.162725 54.883053
1094 2005-12-30 01:00:00 30 12 2005 1 0.055474 0.0 690.111105 179.772627 55.090089 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.627654e+07 -164.110988 80.973981 59.879803

1095 rows × 106 columns

In [19]:
plot_output(sim_output, 'Date', name_lists, len(sim_output), 'streamflow', pre_trim =100, post_trim=-1)

Done