Skip to content

Commit d6df051

Browse files
Merge pull request #222 from HARPgroup/develop-allops
Throw error when elements appear in SPEC-ACTIONS but not in OPSEQ
2 parents 858d4a1 + 1108cde commit d6df051

7 files changed

Lines changed: 80 additions & 133 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Bare bones cli tester - must be run from the HSPsquared source directory
2+
fpath = "./tests/testcbp/HSP2results/JL1_6562_6560.h5"
3+
4+
from hsp2.hsp2.main import *
5+
from hsp2.hsp2.om import *
6+
from hsp2.hsp2io.hdf import HDF5
7+
from hsp2.hsp2io.io import IOManager
8+
from hsp2.state.state import *
9+
10+
# sets up the model plumbing and reads parameters
11+
with HDF5(fpath) as hdf5_instance:
12+
# Note: now that the UCI is read in and hdf5 loaded, you can see things like:
13+
# - hdf5_instance._store.keys() - all the paths in the UCI/hdf5
14+
io_manager = IOManager(hdf5_instance)
15+
parameter_obj = io_manager.read_parameters()
16+
17+
siminfo = parameter_obj.siminfo
18+
opseq = parameter_obj.opseq
19+
# - finally stash specactions in state, not domain (segment) dependent so do it once
20+
# now load state and the special actions
21+
state = init_state_dicts()
22+
state_siminfo_hsp2(parameter_obj, siminfo, io_manager, state)
23+
# Add support for dynamic functions to operate on STATE
24+
# - Load any dynamic components if present, and store variables on objects
25+
state_load_dynamics_hsp2(state, io_manager, siminfo)
26+
# Iterate through all segments and add crucial paths to state
27+
# before loading dynamic components that may reference them
28+
state_init_hsp2(state, opseq, activities)
29+
# - finally stash specactions in state, not domain (segment) dependent so do it once
30+
state["specactions"] = parameter_obj.specactions # stash the specaction dict in state
31+
om_init_state(state) # set up operational model specific state entries
32+
specl_load_state(state, parameter_obj) # traditional special actions
33+
state_load_dynamics_om(
34+
state, io_manager, siminfo
35+
) # operational model for custom python
36+
# finalize all dynamically loaded components and prepare to run the model
37+
state_om_model_run_prep(state, io_manager, siminfo)

examples/state_specl_ops/demo_equation_cli.py

Lines changed: 0 additions & 75 deletions
This file was deleted.

src/hsp2/hsp2/SPECL.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,32 @@
77
"""
88

99
from numba import njit
10+
from hsp2.hsp2tools.names import hsp2_sequence_id
11+
import warnings
1012

11-
12-
def specl_load_om(state, io_manager, siminfo):
13+
def specl_load_om(state, parameter_obj):
14+
active_segs = list(zip(parameter_obj.opseq['OPERATION'], parameter_obj.opseq['SEGMENT']))
1315
if "ACTIONS" in state["specactions"]:
1416
dc = state["specactions"]["ACTIONS"]
1517
for ix in dc.index:
1618
# add the items to the state['model_data'] dict
1719
speca = dc[ix : (ix + 1)]
1820
# need to add a name attribute
1921
opname = "SPEC" + "ACTION" + str(ix)
22+
segtype = speca['OPTYP'].iloc[0]
23+
segno = speca['RANGE1'].iloc[0]
24+
# must check to see if the action refers to an active OPSEQ segment
25+
# since hsp* allows segments to be defined but not OPNed
26+
id = hsp2_sequence_id(segtype, segno)
27+
if (segtype, id) not in active_segs:
28+
raise Exception(
29+
"HSP* ERROR - Missing/inactive segment " + segtype + " " +
30+
segno + " referenced in SPECIAL ACTIONS. Quitting."
31+
)
32+
# warnings.warn(
33+
# "Missing/inactive segment" + id + "referenced.",
34+
# DeprecationWarning)
35+
# continue
2036
state["model_data"][opname] = {}
2137
state["model_data"][opname]["name"] = opname
2238
for ik in speca.keys():
@@ -34,8 +50,8 @@ def specl_load_om(state, io_manager, siminfo):
3450
return
3551

3652

37-
def specl_load_state(state, io_manager, siminfo):
38-
specl_load_om(state, io_manager, siminfo)
53+
def specl_load_state(state, parameter_obj):
54+
specl_load_om(state, parameter_obj)
3955
# others defined below, like:
4056
# specl_load_uvnames(state, io_manager, siminfo)
4157
# ...

src/hsp2/hsp2/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def main(
9898
# - finally stash specactions in state, not domain (segment) dependent so do it once
9999
state["specactions"] = specactions # stash the specaction dict in state
100100
om_init_state(state) # set up operational model specific state entries
101-
specl_load_state(state, io_manager, siminfo) # traditional special actions
101+
specl_load_state(state, parameter_obj) # traditional special actions
102102
state_load_dynamics_om(
103103
state, io_manager, siminfo
104104
) # operational model for custom python

src/hsp2/hsp2tools/names.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
Functions that should create paths, combined names, etc. should go here
3+
"""
4+
5+
def hsp2_sequence_id(activity, ix):
6+
s = f"{activity[0]}{int(ix):03d}"
7+
return(s)

src/hsp2/hsp2tools/readUCI.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import pandas as pd
1010

1111
from hsp2 import hsp2tools
12+
from hsp2.hsp2tools.names import hsp2_sequence_id
1213
from hsp2.hsp2tools.uci_parse_specactions import specactions_parse
1314

1415
pd.set_option("io.hdf.default_format", "table")
@@ -530,7 +531,7 @@ def opn(info, lines):
530531
s = tokens[2].split(":")
531532
indelt = int(s[0]) if len(s) == 1 else 60 * int(s[0]) + int(s[1])
532533
elif tokens[0] in ops:
533-
s = f"{tokens[0][0]}{int(tokens[1]):03d}"
534+
s = hsp2_sequence_id(tokens[0][0], tokens[1])
534535
lst.append((tokens[0], s, indelt))
535536
dfopn = pd.DataFrame(lst, columns=["OPERATION", "SEGMENT", "INDELT_minutes"])
536537
dfopn.to_hdf(store, key="/CONTROL/OP_SEQUENCE", data_columns=True)
Lines changed: 13 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,41 @@
1-
# Must be run from the HSPsquared source directory, the h5 file has already been setup with hsp import_uci test10.uci
2-
# bare bones tester - must be run from the HSPsquared source directory
3-
import os
1+
# this is a simple tester that should be kept up to date with the code in main.py
2+
# alternative to step debugger
3+
fpath = "./tests/testcbp/HSP2results/JL1_6562_6560.h5"
44

5-
import numpy
65
from hsp2.hsp2.main import *
76
from hsp2.hsp2.om import *
87
from hsp2.hsp2io.hdf import HDF5
98
from hsp2.hsp2io.io import IOManager
109
from hsp2.state.state import *
1110

12-
fpath = "./tests/testcbp/HSP2results/JL1_6562_6560.h5"
1311
# try also:
1412
# fpath = './tests/testcbp/HSP2results/JL1_6562_6560.h5'
1513
# sometimes when testing you may need to close the file, so try:
1614
# f = h5py.File(fpath,'a') # use mode 'a' which allows read, write, modify
1715
# # f.close()
1816
hdf5_instance = HDF5(fpath)
1917
io_manager = IOManager(hdf5_instance)
20-
uci_obj = io_manager.read_uci()
21-
siminfo = uci_obj.siminfo
22-
opseq = uci_obj.opseq
18+
parameter_obj = io_manager.read_parameters()
19+
siminfo = parameter_obj.siminfo
20+
opseq = parameter_obj.opseq
2321
# Note: now that the UCI is read in and hdf5 loaded, you can see things like:
2422
# - hdf5_instance._store.keys() - all the paths in the UCI/hdf5
2523
# - finally stash specactions in state, not domain (segment) dependent so do it once
2624
# now load state and the special actions
2725
state = init_state_dicts()
28-
state_initialize_om(state)
29-
state["specactions"] = uci_obj.specactions # stash the specaction dict in state
30-
31-
state_siminfo_hsp2(uci_obj, siminfo)
26+
state_siminfo_hsp2(parameter_obj, siminfo, io_manager, state)
3227
# Add support for dynamic functions to operate on STATE
3328
# - Load any dynamic components if present, and store variables on objects
3429
state_load_dynamics_hsp2(state, io_manager, siminfo)
3530
# Iterate through all segments and add crucial paths to state
3631
# before loading dynamic components that may reference them
3732
state_init_hsp2(state, opseq, activities)
38-
state_load_dynamics_specl(state, io_manager, siminfo) # traditional special actions
33+
# - finally stash specactions in state, not domain (segment) dependent so do it once
34+
state["specactions"] = specactions # stash the specaction dict in state
35+
om_init_state(state) # set up operational model specific state entries
36+
specl_load_state(state, io_manager, siminfo) # traditional special actions
3937
state_load_dynamics_om(
4038
state, io_manager, siminfo
4139
) # operational model for custom python
42-
state_om_model_run_prep(
43-
state, io_manager, siminfo
44-
) # this creates all objects from the UCI and previous loads
45-
# state['model_root_object'].find_var_path('RCHRES_R001')
46-
# Get the timeseries naked, without an object
47-
Rlocal = state["model_object_cache"]["/STATE/RCHRES_R001/Rlocal"]
48-
Rlocal_ts = Rlocal.read_ts()
49-
rchres1 = state["model_object_cache"]["/STATE/RCHRES_R001"]
50-
Rlocal_check = ModelLinkage(
51-
"Rlocal1", rchres1, {"right_path": "/TIMESERIES/TS010", "link_type": 3}
52-
)
53-
# Calls:
54-
# - ts = Rlocal.io_manager.read_ts(Category.INPUTS, None, Rlocal.ts_name)
55-
# - ts = transform(ts, Rlocal.ts_name, 'SAME', Rlocal.siminfo)
56-
Rlocal.io_manager._output._store.keys()
57-
# write it back. We can give an arbitrary name or it will default to write back to the source path in right_path variable
58-
ts1 = (
59-
precip_ts.read_ts()
60-
) # same as precip_ts.ts_ix[precip_ts.ix], same as state['ts_ix'][precip_ts.ix]
61-
# we can specify a custom path to write this TS to
62-
precip_ts.write_path = "/RESULTS/test_TS039"
63-
precip_ts.write_ts()
64-
# precip_ts.write_ts is same as:
65-
# ts4 = precip_ts.format_ts(ts1, ['tsvalue'], siminfo['tindex'])
66-
# ts4.to_hdf(precip_ts.io_manager._output._store, precip_ts.write_path, format='t', data_columns=True, complevel=precip_ts.complevel)
67-
68-
start = time.time()
69-
iterate_models(
70-
model_exec_list, op_tokens, state_ix, dict_ix, ts_ix, siminfo["steps"], -1
71-
)
72-
end = time.time()
73-
print(
74-
len(model_exec_list),
75-
"components iterated over state_ix",
76-
siminfo["steps"],
77-
"time steps took",
78-
end - start,
79-
"seconds",
80-
)
40+
# finalize all dynamically loaded components and prepare to run the model
41+
state_om_model_run_prep(state, io_manager, siminfo)

0 commit comments

Comments
 (0)