Skip to content

Commit

Permalink
Merge pull request #11 from respec/master
Browse files Browse the repository at this point in the history
Pull updates from respec master
  • Loading branch information
ptomasula authored Jun 15, 2020
2 parents 32c93ef + 8fe9a45 commit d0967a1
Show file tree
Hide file tree
Showing 18 changed files with 8,589 additions and 39,614 deletions.
5 changes: 2 additions & 3 deletions HSP2/HYDR.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def _hydr_(ui, ts, COLIND, OUTDGT, rowsFT, funct, Olabels, OVOLlabels):
o[:] = 0.0
rovol = volt

if roseff > 0.0:
if roseff > 0.0: # numba limitation, cant combine into one line
ovol[:] = (rovol/roseff) * oseff[:]
else:
ovol[:] = rovol / nexits
Expand Down Expand Up @@ -483,10 +483,9 @@ def demand(vol, rowFT, funct, nexits, delts, convf, colind, outdgt):
odfv = rowFT[icol-1] * convf
else:
odfv = 0.0

odgt = outdgt[i]

if odfv == 0.0 and odgt == 0.0:
if odfv == 0.0 and odgt == 0.0:
od[i] = 0.0
elif odfv != 0.0 and odgt == 0.0:
od[i] = odfv
Expand Down
9 changes: 3 additions & 6 deletions HSP2/IWATER.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
def iwater(store, siminfo, uci, ts):
''' Driver for IMPLND IWATER code. CALL: iwater(store, general, ui, ts)
store is the Pandas/PyTable open store
general is a dictionary with simulation level infor (OP_SEQUENCE for example)
general is a dictionary with simulation info (OP_SEQUENCE for example)
ui is a dictionary with ILS specific HSPF UCI like data
ts is a dictionary with ILS specific timeseries'''

Expand All @@ -30,13 +30,13 @@ def iwater(store, siminfo, uci, ts):

steps = siminfo['steps'] # number of simulation points

# insure defined, but not usable
# insure defined, but not usable - just in case
for name in ('AIRTMP', 'PETINP', 'PREC', 'RAINF', 'SNOCOV', 'WYIELD'):
if name not in ts:
ts[name] = full(steps, nan, dtype=float64)

# treat missing flows as zero flow
for name in ['SURLI']: # RTLIFG = 1 requires this timeseries
for name in ['SURLI']: # RTLIFG = 1 requires this timeseries
if name not in ts:
ts[name] = zeros(steps, dtype=float64)
# Replace fixed parameters in HSPF with timeseries
Expand Down Expand Up @@ -147,7 +147,6 @@ def _iwater_(ui, ts):
PET[step] = pet
SUPY[step] = supy


surli = SURLI[step]
retsc = RETSC[step]
if RTLIFG: # surface lateral inflow (if any) is subject to retention
Expand All @@ -160,7 +159,6 @@ def _iwater_(ui, ts):
rets = retsc
else:
reto = 0.0

suri = reto
else:
reti = supy
Expand All @@ -172,7 +170,6 @@ def _iwater_(ui, ts):
rets = retsc
else:
reto = 0.0

suri = reto + surli
# IWATER
msupy = suri + surs
Expand Down
3 changes: 1 addition & 2 deletions HSP2/PWATER.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def pwater(store, siminfo, uci, ts):
# surtab = typeT(ui['SURTAB']) # FTable

# missing flows are treated as zeros
for name in ('AGWLI','IFWLI','LGTMP', 'LZLI','PETINP','PREC','SURLI','UZLI'):
for name in ('AGWLI','IFWLI','LGTMP','LZLI','PETINP','PREC','SURLI','UZLI'):
if name not in ts:
ts[name] = zeros(steps)

Expand Down Expand Up @@ -680,7 +680,6 @@ def proute(psur, RTOPFG, delt60, dec, src, surs, errors):
# send what is on the overland flow plane straight to the channel
suro = psur
surs = 0.0

if suro <= 1.0e-10:
suro = 0.0 # fix bug in on pc - underflow leads to "not a number"

Expand Down
2 changes: 1 addition & 1 deletion HSP2/SNOW.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def _snow_(ui, ts):
''
# METEOR
if prec > 0.0:
fprfg = oldprec == 0.0
fprfg = (oldprec == 0.0)
else:
fprfg = False

Expand Down
2 changes: 1 addition & 1 deletion HSP2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

from HSP2.main import main
from HSP2.mainDoE import main as mainDoE
from HSP2.utilities import versions
from HSP2.utilities import versions, flowtype

__version__ = '1.0.0'
34 changes: 34 additions & 0 deletions HSP2/configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
''' Copyright (c) 2020 by RESPEC, INC.
Author: Robert Heaphy, Ph.D.
License: LGPL2
'''

from numpy import zeros


# new activity modules must be added here and in *activites* below
from HSP2.ATEMP import atemp
from HSP2.SNOW import snow
from HSP2.PWATER import pwater
from HSP2.IWATER import iwater
from HSP2.HYDR import hydr

def noop (store, siminfo, ui, ts):
ERRMSGS = []
errors = zeros(len(ERRMSGS), dtype=int)
return errors, ERRMSGS

# Note: This is the ONLY place in HSP2 that defines activity execution order
activities = {
'PERLND': {'ATEMP':atemp, 'SNOW':snow, 'PWATER':pwater, 'SEDMNT':noop,
'PSTEMP':noop, 'PWTGAS':noop, 'PQUAL':noop, 'MSTLAY':noop, 'PEST':noop,
'NITR':noop, 'PHOS':noop, 'TRACER':noop},
'IMPLND': {'ATEMP':atemp, 'SNOW':snow, 'IWATER':iwater, 'SOLIDS':noop,
'IWTGAS':noop, 'IQUAL':noop},
'RCHRES': {'HYDR':hydr, 'ADCALC':noop, 'CONS':noop, 'HTRCH':noop,
'SEDTRN':noop, 'GQUAL':noop, 'OXRX':noop, 'NUTRX':noop, 'PLANK':noop,
'PHCARB':noop}}


# NOTE: the flowtype (Python set) at the top of utilities.py may need to be
# updated for new types of flows in new or modified HSP2 modules.
34 changes: 6 additions & 28 deletions HSP2/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
License: LGPL2
'''

from numpy import zeros, float64, float32
from numpy import float64, float32
from pandas import HDFStore, Timestamp, read_hdf, DataFrame, date_range
from pandas.tseries.offsets import Minute
from numba import types
Expand All @@ -12,29 +12,7 @@
from datetime import datetime as dt
import os
from HSP2.utilities import transform, versions

def noop (store, siminfo, ui, ts):
ERRMSGS = []
errors = zeros(len(ERRMSGS), dtype=int)
return errors, ERRMSGS

# new activity modules must be added here and in *activites* below
from HSP2.ATEMP import atemp
from HSP2.SNOW import snow
from HSP2.PWATER import pwater
from HSP2.IWATER import iwater
from HSP2.HYDR import hydr

# Note: This is the ONLY place in HSP2 that defines activity execution order
activities = {
'PERLND': {'ATEMP':atemp, 'SNOW':snow, 'PWATER':pwater, 'SEDMNT':noop,
'PSTEMP':noop, 'PWTGAS':noop, 'PQUAL':noop, 'MSTLAY':noop, 'PEST':noop,
'NITR':noop, 'PHOS':noop, 'TRACER':noop},
'IMPLND': {'ATEMP':atemp, 'SNOW':snow, 'IWATER':iwater, 'SOLIDS':noop,
'IWTGAS':noop, 'IQUAL':noop},
'RCHRES': {'HYDR':hydr, 'ADCALC':noop, 'CONS':noop, 'HTRCH':noop,
'SEDTRN':noop, 'GQUAL':noop, 'OXRX':noop, 'NUTRX':noop, 'PLANK':noop,
'PHCARB':noop}}
from HSP2.configuration import activities, noop


def main(hdfname, saveall=False):
Expand Down Expand Up @@ -131,15 +109,15 @@ def get_uci(store):
siminfo['stop'] = Timestamp(temp['Stop'])
elif module == 'LINKS':
ddlinks = defaultdict(list)
for row in store[path].itertuples():
for row in store[path].replace('na','').itertuples():
ddlinks[row.TVOLNO].append(row)
elif module == 'MASS_LINKS':
ddmasslinks = defaultdict(list)
for row in store[path].itertuples():
for row in store[path].replace('na','').itertuples():
ddmasslinks[row.MLNO].append(row)
elif module == 'EXT_SOURCES':
ddext_sources = defaultdict(list)
for row in store[path].itertuples():
for row in store[path].replace('na','').itertuples():
ddext_sources[(row.TVOL, row.TVOLNO)].append(row)
elif module == 'OP_SEQUENCE':
opseq = store[path]
Expand Down Expand Up @@ -183,7 +161,7 @@ def save_timeseries(store, ts, savedict, siminfo, saveall, operation, segment, a
for y in (save & set(ts.keys())):
df[y] = ts[y]
df = df.astype(float32).sort_index(axis='columns')
path = f'/RESULTS/{operation}_{segment}/{activity}'
path = f'RESULTS/{operation}_{segment}/{activity}'
if not df.empty:
df.to_hdf(store, path, complib='blosc', complevel=9)
else:
Expand Down
37 changes: 6 additions & 31 deletions HSP2/mainDoE.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
License: LGPL2
'''

from numpy import zeros, float64
from numpy import float64, float32
from pandas import HDFStore, Timestamp, read_hdf, DataFrame, date_range
from pandas.tseries.offsets import Minute
from numba import types
Expand All @@ -13,29 +13,7 @@
import os
from copy import deepcopy
from HSP2.utilities import transform, versions

def noop (store, siminfo, ui, ts):
ERRMSGS = []
errors = zeros(len(ERRMSGS), dtype=int)
return errors, ERRMSGS

# new activity modules must be added here and in *activites* below
from HSP2.ATEMP import atemp
from HSP2.SNOW import snow
from HSP2.PWATER import pwater
from HSP2.IWATER import iwater
from HSP2.HYDR import hydr

# Note: This is the ONLY place in HSP2 that defines activity execution order
activities = {
'PERLND': {'ATEMP':atemp, 'SNOW':snow, 'PWATER':pwater, 'SEDMNT':noop,
'PSTEMP':noop, 'PWTGAS':noop, 'PQUAL':noop, 'MSTLAY':noop, 'PEST':noop,
'NITR':noop, 'PHOS':noop, 'TRACER':noop},
'IMPLND': {'ATEMP':atemp, 'SNOW':snow, 'IWATER':iwater, 'SOLIDS':noop,
'IWTGAS':noop, 'IQUAL':noop},
'RCHRES': {'HYDR':hydr, 'ADCALC':noop, 'CONS':noop, 'HTRCH':noop,
'SEDTRN':noop, 'GQUAL':noop, 'OXRX':noop, 'NUTRX':noop, 'PLANK':noop,
'PHCARB':noop}}
from HSP2.configuration import activities, noop


def main(hdfname, doe, doename='DOE_RESULTS', saveall=False):
Expand Down Expand Up @@ -105,7 +83,6 @@ def main(hdfname, doe, doename='DOE_RESULTS', saveall=False):
None.
'''


if not os.path.exists(hdfname):
print(f'{hdfname} HDF5 File Not Found, QUITTING')
return
Expand All @@ -127,7 +104,6 @@ def main(hdfname, doe, doename='DOE_RESULTS', saveall=False):
savepath = f'{doename}/RUN{run}'
msg(2, f'Starting Run {run}; saving as {savepath}')


uci = deepcopy(originaluci)
for _, operation, segment, delt in opseq.itertuples():
msg(3, f'{operation} {segment} DELT(minutes): {delt}')
Expand All @@ -144,7 +120,7 @@ def main(hdfname, doe, doename='DOE_RESULTS', saveall=False):

msg(4, f'{activity}')
if operation == 'RCHRES':
get_flows(store,ts,activity,segment,ddlinks,ddmasslinks,msg,savepath)
get_flows(store,ts,activity,segment,ddlinks,ddmasslinks,siminfo['steps'],msg,savepath)
ui = uci[operation, activity, segment] # ui is a dictionary

# update deep copy of UCI dict with run dict
Expand Down Expand Up @@ -273,17 +249,16 @@ def save_timeseries(store,ts,savedict,siminfo,saveall,operation,segment,activity
df = DataFrame(index=siminfo['tindex'])
for y in (save & set(ts.keys())):
df[y] = ts[y]
df = df.astype('float32').sort_index(axis='columns')
path = f'/RESULTS/{operation}_{segment}/{activity}'
df = df.astype(float32).sort_index(axis='columns')
path = f'{savepath}/{operation}_{segment}/{activity}'
if not df.empty:
store.put(path, df)
store.flush()
else:
print('Save DataFrame Empty for', path)
return


def get_flows(store, ts, activity, segment, ddlinks, ddmasslinks, msg, savepath):
def get_flows(store, ts, activity, segment, ddlinks, ddmasslinks, steps, msg, savepath):
for x in ddlinks[segment]:
mldata = ddmasslinks[x.MLNO]
for dat in mldata:
Expand Down
24 changes: 22 additions & 2 deletions HSP2/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@
from numba.typed import Dict


flowtype = {
# EXTERNAL FLOWS
'PREC','WIND','WINMOV','SOLRAD','PETINP','POTEV','SURLI','IFWLI','AGWLI',
'SLSED','IVOL','ICON',
# COMPUTED FLOWS
'PRECIP','SNOWF','PRAIN','SNOWE','WYIELD','MELT', #SNOW
'SUPY','SURO','IFWO','AGWO','PERO','IGWI','PET','CEPE','UZET','LZET', #PWATER
'AGWET','BASET','TAET','IFWI','UZI','INFIL','PERC','LZI','AGWI', #PWATER
'SOHT','IOHT','AOHT','POHT','SODOXM','SOCO2M','IODOXM','IOCO2M', #PWTGAS
'AODOXM','AOCO2M','PODOXM','POCO2M', #PWTGAS
'SUPY','SURO','PET','IMPEV' #IWATER
'SOSLD', #SOLIDS
'SOHT','SODOXM','SOCO2M', #IWTGAS
'SOQS','SOQO','SOQUAL', #IQUAL
'IVOL','PRSUPY','VOLEV','ROVOL','POTEV', #HYDR
'ICON','ROCON', #CONS
'IHEAT','HTEXCH','ROHEAT','QTOTAL','QSOLAR','QLONGW','QEVAP','QCON', #HTRCH
'QPREC','QBED', #HTRCH
}


def make_numba_dict(uci):
'''
Move UCI dictionary data to Numba dict for FLAGS, STATES, PARAMETERS.
Expand All @@ -35,8 +56,7 @@ def make_numba_dict(uci):
return ui


flowtype = {'PREC','WIND','WINMOV','SOLRAD','PETINP','POTEV','SURLI','IFWLI',
'AGWLI','SLSED','IVOL','ICON'}

def transform(ts, name, how, siminfo):
'''
upsample (disaggregate) /downsample (aggregate) ts to freq and trim to [start:stop]
Expand Down
51 changes: 51 additions & 0 deletions HSP2_Driver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import os, sys

# print('in HSP2_Driver')
command_line = ""
# print('arg count ' + str(len(sys.argv)))
if len(sys.argv) >= 2:
# see if anything on command line
command_line = sys.argv[1]
print('command line' + command_line)

# if given UCI, import to h5 file
# if given WDM, import to h5 file
# if given h5, run HSP2

from PyQt5.QtWidgets import QFileDialog, QApplication

application = QApplication(sys.argv)

if command_line == '':
file_filter = "Run HDF5 (*.h5);;" \
"Import UCI to HDF5 (*.uci);;" \
"Import WDM to HDF5 (*.wdm)"
filename, filetype = QFileDialog.getOpenFileName(None, 'HSP2 Open File...', '', file_filter)
else:
filename = command_line

file_ext = filename[-3:]
dir_name = os.path.dirname(filename)
os.chdir(dir_name)

if file_ext.upper() == "UCI":
h5_name = filename[:-3] + "h5"
from HSP2tools.readUCI import readUCI
readUCI(filename, h5_name)
# readUCI('HSPF.uci', 'test.h5')

if file_ext.upper() == "WDM":
h5_name = filename[:-3] + "h5"
from HSP2tools.readWDM import readWDM
readWDM(filename, h5_name)
# readWDM('GRICM.wdm', 'test.h5')
# readWDM('ZUMBROSCEN.WDM', 'test.h5')

if file_ext.upper() == ".H5":
from HSP2.main import main
main(filename, saveall=True)
# main('test.h5', saveall=True)




Loading

0 comments on commit d0967a1

Please sign in to comment.