Skip to content

Commit

Permalink
Merge pull request #82 from USDA-ARS-NWRC/79_pysnobal_config
Browse files Browse the repository at this point in the history
79 pysnobal config
  • Loading branch information
Scott Havens authored Oct 6, 2020
2 parents a40046a + 1712063 commit 7945fee
Show file tree
Hide file tree
Showing 39 changed files with 550 additions and 737 deletions.
4 changes: 0 additions & 4 deletions awsm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@
__config_titles__ = {
'awsm master': 'Configurations for AWSM Master section',
'paths': 'Configurations for PATHS section for rigid directory work',
'grid': 'Configurations for GRID data to run iSnobal',
'files': 'Input files to run AWSM',
'awsm system': 'System parameters',
'isnobal restart': 'Parameters for restarting from crash',
'ipysnobal': 'Running Python wrapped iSnobal',
'ipysnobal initial conditions': 'Initial condition parameters for PySnobal',
'ipysnobal constants': 'Input constants for PySnobal'
}


Expand Down
6 changes: 0 additions & 6 deletions awsm/data/__init__.py

This file was deleted.

117 changes: 55 additions & 62 deletions awsm/framework/CoreConfig.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ model_type: default = None,
description = Model used to simulate snowpack for given time
period. Choose None if not running model

mask_isnobal: default = False,
type = bool,
description = Mask snowpack model output.

[paths]
path_dr: type = criticaldirectory,
description = path to starting drive for AWSM directory
Expand All @@ -37,35 +33,6 @@ folder_date_style: default = start_end,
description = style of date that gets appended to
generated folders for each date range that is simulated

[grid]
active_layer: type = float,
default = 0.25,
description = height of iSnobal active layer in meters

thresh_normal: type = int,
default = 60,
description = normal mass threshold for timestep refinement
within iSnobal

thresh_medium: type = int,
default = 10,
description = medium mass threshold for timestep refinement
within iSnobal

thresh_small: type = int,
default = 1,
description = small mass threshold for timestep refinement
within iSnobal

[FILES]
init_file: type = filename,
description = init file containing model state to initialize
snow model

init_type: default = None,
options = [None netcdf netcdf_out],
description = type of file for initializing model

[awsm system]
log_level: default = debug,
options = [debug info error],
Expand All @@ -75,10 +42,6 @@ log_to_file: default = True,
type = bool,
description = log to auto generated file or print to screen

ithreads: default = 1,
type = int,
description = numbers threads for running snow model

output_frequency: default = 24,
type = int,
description = frequency of snow model outputs in hours.
Expand All @@ -93,25 +56,6 @@ run_for_nsteps: type = int,
description = number of timesteps to run iSnobal. This is
optional and mainly used in model crash scenarios

variables: type = string list,
default = [thickness snow_density specific_mass liquid_water
temp_surf temp_lower temp_snowcover thickness_lower
water_saturation net_rad sensible_heat latent_heat snow_soil
precip_advected sum_eb evaporation snowmelt swi cold_content],
options = [thickness snow_density specific_mass liquid_water
temp_surf temp_lower temp_snowcover thickness_lower
water_saturation net_rad sensible_heat latent_heat snow_soil
precip_advected sum_eb evaporation snowmelt swi cold_content],
description = Variables for PySnobal to output after being
calculated

snow_name: default = snow,
description = prefix of snow ouput file without WYHR
extension

em_name: default = em,
description = prefix of energetics ouput file without WYHR
extension

################################################################################
# Configurations for updating with lidar depths
Expand Down Expand Up @@ -161,20 +105,69 @@ output_folders: default = standard,
directory but it may look in the previous day output if daily

[ipysnobal]
forcing_data_type: default = netcdf,
options = [netcdf],
description = file type from which to get input data to force
iPySnobal

[ipysnobal constants]
init_file: type = filename,
description = init file containing model state to initialize
snow model

init_type: default = None,
options = [None netcdf netcdf_out],
description = type of file for initializing model

active_layer: type = float,
default = 0.25,
description = height of iSnobal active layer in meters

max_h2o: type = float,
default = 0.01,
description = maximum volumetric content of liquid water in the snowpack

thresh_normal: type = int,
default = 60,
description = normal mass threshold for timestep refinement
within iSnobal

thresh_medium: type = int,
default = 10,
description = medium mass threshold for timestep refinement
within iSnobal

thresh_small: type = int,
default = 1,
description = small mass threshold for timestep refinement
within iSnobal

z_u: default = 5.0,
type = float,
description = height of wind speed data in meters

z_T: default = 5.0,
z_t: default = 5.0,
type = float,
description = height of temperature data in meters

z_g: default = 0.5,
type = float,
description = depth of soil temperature data in meters

ithreads: default = 1,
type = int,
description = numbers threads for running snow model

output_file_name: default = ipysnobal,
type = string,
description = name of the output file

variables: type = string list,
default = [thickness snow_density specific_mass liquid_water
temperature_surface temperature_lower temperature_snowcover thickness_lower
water_saturation net_radiation sensible_heat latent_heat snow_soil
precip_advected sum_energy_balance evaporation snowmelt surface_water_input cold_content],
options = [thickness snow_density specific_mass liquid_water
temperature_surface temperature_lower temperature_snowcover thickness_lower
water_saturation net_radiation sensible_heat latent_heat snow_soil
precip_advected sum_energy_balance evaporation snowmelt surface_water_input cold_content],
description = Output variables for Pysnobal

mask_isnobal: default = False,
type = bool,
description = Mask snowpack model output.
23 changes: 23 additions & 0 deletions awsm/framework/changelog.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,26 @@ paths/desc -> paths/project_description
# grid
grid/nbits -> REMOVED
grid/csys -> REMOVED
grid/active_layer -> ipysnobal/active_layer
grid/thresh_normal -> ipysnobal/thresh_normal
grid/thresh_medium -> ipysnobal/thresh_medium
grid/thresh_small -> ipysnobal/thresh_small

# files
files/init_file -> ipysnobal/init_file
files/init_type -> ipysnobal/init_type

# awsm system
awsm syste/ithreads -> ipysnobal/ithreads

# update depth

# isnobal restart

# ipysnobal
ipysnobal/forcing_data_type -> REMOVED

# ipysnobal constants
ipysnobal constants/z_u -> ipysnobal/z_u
ipysnobal constants/z_t -> ipysnobal/z_t
ipysnobal constants/z_g -> ipysnobal/z_g
68 changes: 16 additions & 52 deletions awsm/framework/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@

import smrf.framework.logger as logger

from awsm.data.init_model import ModelInit
from awsm.framework import ascii_art
from awsm.interface.smrf_connector import SMRFConnector
from awsm.interface.ipysnobal import PySnobal
from awsm.models.smrf_connector import SMRFConnector
from awsm.models.pysnobal import PySnobal, ModelInit


class AWSM():
Expand All @@ -34,7 +33,7 @@ class AWSM():
Attributes:
"""

def __init__(self, config, testing=False):
def __init__(self, config):
"""
Initialize the model, read config file, start and end date, and logging
Args:
Expand All @@ -43,7 +42,6 @@ def __init__(self, config, testing=False):
"""

self.read_config(config)
self.testing = testing

# create blank log and error log because logger is not initialized yet
self.tmp_log = []
Expand All @@ -69,9 +67,6 @@ def __init__(self, config, testing=False):
# change here requires a change there
self.n_forecast_hours = 18

# options for masking isnobal
self.mask_isnobal = self.config['awsm master']['mask_isnobal']

# store smrf version if running smrf
self.smrf_version = smrf.__version__

Expand All @@ -94,25 +89,14 @@ def __init__(self, config, testing=False):
print(self.tmp_err)
sys.exit()

# Time step mass thresholds for iSnobal
self.mass_thresh = []
self.mass_thresh.append(self.config['grid']['thresh_normal'])
self.mass_thresh.append(self.config['grid']['thresh_medium'])
self.mass_thresh.append(self.config['grid']['thresh_small'])

# threads for running iSnobal
self.ithreads = self.config['awsm system']['ithreads']
# how often to output form iSnobal
self.output_freq = self.config['awsm system']['output_frequency']
# number of timesteps to run if ou don't want to run the whole thing
self.run_for_nsteps = self.config['awsm system']['run_for_nsteps']
# pysnobal output variables
self.pysnobal_output_vars = self.config['awsm system']['variables']
self.pysnobal_output_vars = self.config['ipysnobal']['variables']
self.pysnobal_output_vars = [wrd.lower()
for wrd in self.pysnobal_output_vars]
# snow and emname
self.snow_name = self.config['awsm system']['snow_name']
self.em_name = self.config['awsm system']['em_name']

# options for restarting iSnobal
self.restart_crash = False
Expand All @@ -124,17 +108,6 @@ def __init__(self, config, testing=False):
int(self.config['isnobal restart']['wyh_restart_output'])
self.restart_folder = self.config['isnobal restart']['output_folders']

# iSnobal active layer
self.active_layer = self.config['grid']['active_layer']

# if we are going to run ipysnobal with smrf
if self.model_type in ['ipysnobal', 'smrf_ipysnobal']:
self.ipy_threads = self.ithreads
self.ipy_init_type = \
self.config['files']['init_type']
self.forcing_data_type = \
self.config['ipysnobal']['forcing_data_type']

# parameters needed for restart procedure
self.restart_run = False
if self.config['isnobal restart']['restart_crash']:
Expand Down Expand Up @@ -232,7 +205,7 @@ def load_topo(self):

self.topo = smrf.data.load_topo.Topo(self.config['topo'])

if not self.mask_isnobal:
if not self.config['ipysnobal']['mask_isnobal']:
self.topo.mask = np.ones_like(self.topo.dem)

# see if roughness is in the topo
Expand Down Expand Up @@ -422,18 +395,11 @@ def create_project_description(self):
fp_desc = os.path.join(self.path_wy, 'projectDescription.txt')

if not os.path.isfile(fp_desc):
# look for description or prompt for one
if self.project_description is not None:
pass
else:
self.project_description = input('\nNo description for project. '
'Enter one now, but do not use '
'any punctuation:\n')
with open(fp_desc, 'w') as f:
f.write(self.project_description)

else:
self.tmp_log.append('Description file already exists\n')
self.tmp_log.append('Description file already exists')

def make_rigid_directories(self, path_name):
"""
Expand All @@ -449,7 +415,7 @@ def make_rigid_directories(self, path_name):
os.makedirs(path)
else:
self.tmp_log.append(
'Directory --{}-- exists, not creating.\n'.format(path))
'Directory --{}-- exists, not creating.'.format(path))

def __enter__(self):
self.start_time = datetime.now()
Expand Down Expand Up @@ -530,9 +496,9 @@ def run_awsm_daily_ops(config_file):
new_config = copy.deepcopy(config)
if idd > 0:
new_config.raw_cfg['isnobal restart']['restart_crash'] = False
new_config.raw_cfg['grid']['thresh_normal'] = 60
new_config.raw_cfg['grid']['thresh_medium'] = 10
new_config.raw_cfg['grid']['thresh_small'] = 1
new_config.raw_cfg['ipysnobal']['thresh_normal'] = 60
new_config.raw_cfg['ipysnobal']['thresh_medium'] = 10
new_config.raw_cfg['ipysnobal']['thresh_small'] = 1
# get the end of the day
ed = sd + add_day

Expand All @@ -552,11 +518,11 @@ def run_awsm_daily_ops(config_file):
prev_day = sd - pd.to_timedelta(1, unit='D')
prev_out = os.path.join(prev_out_base,
'run{}'.format(prev_day.strftime(fmt_day)),
'snow.nc')
'ipysnobal.nc')
# reset if running the model
if new_config.cfg['awsm master']['model_type'] is not None:
new_config.raw_cfg['files']['init_type'] = 'netcdf_out'
new_config.raw_cfg['files']['init_file'] = prev_out
new_config.raw_cfg['ipysnobal']['init_type'] = 'netcdf_out'
new_config.raw_cfg['ipysnobal']['init_file'] = prev_out

# if we have a previous storm day file, use it
prev_storm = os.path.join(prev_data_base,
Expand All @@ -574,17 +540,15 @@ def run_awsm_daily_ops(config_file):
run_awsm(new_config)


def run_awsm(config, testing=False):
def run_awsm(config):
"""
Function that runs awsm how it should be operate for full runs.
Args:
config: string path to the config file or inicheck UserConfig instance
testing: only to be used with unittests, if True will convert SMRF data
from to 32-bit then 64-bit to mimic writing the data to a
netcdf. This enables a single set of gold files.
"""
with AWSM(config, testing) as a:

with AWSM(config) as a:
if a.do_forecast:
runtype = 'forecast'
else:
Expand Down
2 changes: 1 addition & 1 deletion awsm/interface/ingest_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def __init__(self, myawsm):
for k in self.update_info.keys()]

# get necessary variables from awsm class
self.active_layer = myawsm.active_layer
self.active_layer = myawsm.config['ipysnobal']['active_layer']
# Buffer size (in cells) for the interpolation to search overself.
self.update_buffer = myawsm.update_buffer

Expand Down
Loading

0 comments on commit 7945fee

Please sign in to comment.