forked from respec/HSPsquared
-
Notifications
You must be signed in to change notification settings - Fork 0
JK HSP2 Log
Joey Kleiner edited this page Dec 13, 2022
·
61 revisions
def _hydr_(ui, ts, COLIND, OUTDGT, rowsFT, funct, Olabels, OVOLlabels, specactions):
def specl(uci, ts, step, specactions):
def _specl_(uci, ts, step, specactions):
- I'm having trouble loading any modules on deq1 (deq3)
- pandas, h5py etc.
- spent time adjusting where python looks for the python/module installation
- hsp2 was having no trouble loading them the last time I ran the model. Check the installation issue: #9
- Where do the different model objects come in to the sequence? https://github.com/HARPgroup/HSPsquared/issues/7
- We don't know yet. Objects may be an enhancement to the
specl
facility from the original model, but it may be more appropriate to make them a separate module but we are using this issue to scope that out.
- We don't know yet. Objects may be an enhancement to the
- When does the demand() function come into play? (located in HYDR.py)
-
demand()
appears to get arguments pertaining to OUTDGT, hence, I think that anything that altersOUTDGT
will influence the processing ofdemand()
, but a primary purpose of this scoping is to determine precisely how that works.
-
- Is OUTDGT different from the withdrawal parameter that will be in the
specactions
dictionary?- OUTDGT will be set by specl entities.
- Where will the parser come into the sequence?
- The parser is at the very beginning when we run
hsp2 import_uci
. Check the parser issue for detail. https://github.com/respec/HSPsquared/issues/99 - it may be a good idea to merge the parser branch into your development branch. It doesn't work, but it dorsn't break anything and it does tie the different functions together.
- The parser is at the very beginning when we run
- Is the HARP hydr CSV the input to
specactions = {}
? https://github.com/HARPgroup/HARParchive/issues/536#issuecomment-1245729144-
specactions
is populated when the UCI is read. See https://github.com/respec/HSPsquared/issues/99
-
- Would be good to have an easy way to visualize model results of test runs (using one of the HARP scripts): https://github.com/HARPgroup/HARParchive/issues/505
- I project they will have the whole set of hydrology metrics integrated next week. :)
- Running
jk_tester.py
-
nano /usr/local/bin/hsp2
- Top line in this file notes the python executable to be used (python 3 in this case):
#!/usr/bin/python3
- Note: "#" is not a comment in this context, it is a shebang line
- Added this header to
jk_tester.py
- Top line in this file notes the python executable to be used (python 3 in this case):
- helpful commands:
python2 -m site
python3 -m site
- setting binary user permissions
-
chmod 755 jk_tester.py
- chmod [owner][group][others], 755 equivalent to rw rx rx
- only have to execute this once, then file permissions are changed forever till you run chmod again
-
- How to run
-
./jk_tester.py
(assumingjk_tester.py
has the header#!/usr/bin/python3
) - OR:
python3 jk_tester.py
(header not needed)
-
-
- Code Updates
- Updated
specl()
and_specl_()
to take input parameter "ui" NOT "uci"- ui is the Numba-ized uci
- Should send
ts_save
andts
- At the beginning of the simulation
ts
is zero -
ts_save
is our state
- At the beginning of the simulation
- Updated
- Where do the objects come in?
- Ans: we don't know yet. One way of doing it is in special actions since that facility is in there. We know special actions can modify state variables, which is exactly what the objects will do
- General HSP2 notes
- The .uci file specifies which .wdm files get pulled in
-
import_uci
1) imports the uci & 2) imports all the wdm timeseries data - in the CBP model the demands come in through a wdm, timeseries of demands for every day in the simulation
- test10 does not do withdrawals
- Some of our questions:
- How does
OUTDGT
operate? -> gets passed to_hydr_()
, runsdemand()
- How does
demand()
operate? -> several calls todemand()
but presumably it only executes once in the loop (lots of if statements)
- How does
- the lowecase variable name is the pass by reference of the UPPERCASE variable in the current timestep
- The withdrawals are represented as the diversions in the uci. example:
- DIVR = non-ag
- DIVA = agricultural
*** DIVERSIONS WDM3 3007 DIVR ENGLZERO SAME RCHRES 1 EXTNL OUTDGT 1 WDM3 3008 DIVA ENGLZERO SAME RCHRES 1 EXTNL OUTDGT 2
- This describes the timeseries and where to look in the wdm
- We expect only 1 of the OUTDGT to have data
- The HARP hydr export will contain what we need: https://github.com/HARPgroup/HARParchive/issues/541
-
demand()
- See
od.sum()
-> we're assuming this sums the multiple OUTDGTs in the wdm- the uci syas how many are summed, the above example has 2
- See
- We think
OUTDGT
is the way to do the withdrawals - We should probably run hours
- Running tests
- New directory created:
/opt/model/HSPsquared/tests/testcbp
- Had to do the following within this new directory
-
chmod g+w * -R
aka change group to writable recursive (for all files and directories under that directory) chgrp modelers * -R
-
- Set up test for
PL3_5250_0001
(Occoquan Main Dam watershed)- we know this one has pretty big values
- uci and wdm files copied over
PL3_5250_0001.uci
met_A51059.wdm
prad_A51059.wdm
-
ps_sep_div_ams_hsp2_2022_PL3_5250_0001.wdm
(This is where the withdrawals are, the avg is ~51 cfs or mgd?) PL3_5250_0001.wdm
- Modified the date range of the simulation at the top of
PL3_5250_0001.uci
toSTART 2001/01/01 END 2001/12/31
- New directory created:
- Do a comparison where we manipulate the withdrawal by a lot, and one where we manipulate it zero
- Then see what the data looks like in the .h5 file to see if this approach works
- Set up the
outdgt
(the variables that represent withdrawals)- Because really we want to tell it what the withdrawal is and then have it do the management of the withdrawal
-
outdgt
is an array - it supports 3 potential values - We think:
-
OUTDGT 1
isDIVR
-
OUTDGT 2
isDIVA
-
- We’ll pass the equations and lookups into
_specl_()
- Within
_specl_()
the objects will do their thing and then it’ll log the value tooutdgt
- We don’t know where the objects will ultimately come into play BUT for our draft testing purposes, objects will be instantiated within
specl
- The objects will say “What value am I setting and how am I setting it”
- Within
- In the old model it uses a broadcast to handle the withdrawal
- We’ll alter that so the river object reads the withdrawal value for all the things contained within it and then sums them
- River Withdrawal Model
- This is the idea (but probably a little premature without understanding how the mechanics of the model work): https://github.com/HARPgroup/HSPsquared/issues/27
- I’ll keep investigating this, How things get modified etc.
- Method
- We will blank the
outdgt
and then set it ourselves - We will zero it even though we don’t really need to, because we’ll be setting it in the
specl
process anyway - Right now it’s just helpful to run with some
outdgt
in there for testing
- We will blank the
- Check for changing values in the H5
- Set
OUTDGT 2
akaDIVA
and see what happens - Get with HARP on these items as-needed
- Set
- The
RCHRES
gets sent tohydr
- steps rows, nexits columns
- Strategy
- We want to be modifying the
ts
- We want to choose the one that gets used in the equations, if we can just pass in
ts
and modifyts['OUTDGT'][step]
, then we’re good - Want to minimize passing in other variables if we can
- We want to be modifying the
- See ~line 73 in HYDR.py:
OUTDGT
comes fromts
- Way to print all keys in
ts
?- See
print(names)
~ line 75 of HYDR.py - Example for printing all keys in a .h5:
- See
import h5py
filename = "PL3_5250_0001.h5"
with h5py.File(filename, "r") as f:
# Print all root level object names (aka keys)
# these can be group or dataset names
print("Keys: %s" % f.keys())
- In the uci,
DIVA
comes out atOUTDGT2
the other isOUTDGT1
- Now in the hydr routine:
- Did the code do anything with the lowercase
outdgt
? - Did it do anything with a manually set 99 value?
- Did the code do anything with the lowercase
- Note: we look at
step-1
because the withdrawal stuff gets executed before the river channel stuff. SO the flow in the stream is 0 for the current time step, therefore you have to look at the previous time step- And that’s not unrealistic since withdrawers typically look at the gage reading from the previous day to base their withdrawals
- Findings:
-
O
and andRO
are influenced by whatoutdgt
is through thedemand()
function - See below ~line 477 in HYDR.py for where those things get set based on the lowercase vars at the end of the loop. See
# HYDR
- We found that modifying
OUTDGT2
ints
does not automatically alteroutdgt
-
- One option:
- Pass
OUTDGT
to thespecl
function - Another option is have a function that loads things from
ts
- Pass
- One next step: want to spend time looking at those things that get set at the bottom of loop in HYDR.py
- what do those look like in the .h5 file?
-
outdgt()
influencesO
andRO
in the next time step through thedemand()
function- See example for looking through the h5: https://github.com/HARPgroup/HSPsquared/issues/24#issuecomment-1258454652
- Current Question: Does pass by reference work for timeseries table
ts
?- https://github.com/HARPgroup/HSPsquared/issues/12
- Need to check the .h5 file to confirm that the values get changed
- Progress has been made on the parser
- https://github.com/HARPgroup/HSPsquared/issues/24
- psa branch pull request submitted to RSEPEC (once they merge it, I can pull it back into the specl branch)
- See:
- readUCI.py
- see line d =parseD(line, parse[‘SPEC-ACTIONS’
- uses ParseTable.csv
- UCI.py: self.specactions defined
- hdf.py
- main.py: uci_obj = io_manager.read_uci() & specations = uci_objspecations
- readUCI.py
- tip: use fgrep for investigating
- Next steps:
- wrapping up coding of withdrawals
- then next step is using real withdrawals & flowby and/or releases
- Investigations
- developed testing script jk_tester.R
cd /opt/model/HSPsquared/tests/testcbp/HSP2results
Rscript jk_tester.R
- Spent time getting oriented with the h5 structure
- developed testing script jk_tester.R
-
ro
is the first value inOUTDGT
akaOUTDGT1
step: 431 of: 8760 steps
Trying specl
[73.66304779 -0. 0. ] # print(OUTDGT[step, :])
73.66304779049824 # print(ro)
Made it to specl()
Made it to _specl_()
[-0.0, 99.0] # print([OUTDGT2_save, ts['OUTDGT2'][step - 1] ])
[73.66304779052734, 73.66304779052734] # print([OUTDGT1_save, ts['OUTDGT1'][step - 1] ])
[73.66304779 -0. 0. ] #print(outdgt[:])
step: 8759 of: 8760 steps
Trying specl
[83.55184937 -0. 0. ]
83.55184936523438
Made it to specl()
Made it to _specl_()
[-0.0, 99.0]
[83.55184936523438, 83.55184936523438]
[83.55184937 -0. 0. ]
- Notice,
ro
is different for every step in the loop, even though its not explicitly called/set at the beginning of the loop - After manually setting
ro
to 99:
step: 8759 of: 8760 steps
Trying specl
[83.55184937 -0. 0. ]
96.18687265721383
Made it to specl()
Made it to _specl_()
[-0.0, 99.0]
[83.55184936523438, 83.55184936523438]
[83.55184937 -0. 0. ]
- Verified that the values in
“RESULTS/RCHRES_R001/HYDR/table”
do in fact change, but not quite as expected- See the output files
HYDR_table_v1.csv
vsHYDR_table_v2.csv
(this one used thero = 99
)
- See the output files
- Added line to gitignore:
tests/testcbp/HSP2results/*.csv
- Currently assuming
RO
= actual withdrawals with availability considered - All names in ts:
['WIND', 'SOLRAD', 'PREC', 'POTEV', 'PLADFX2 1', 'PLADFX1 1', 'PKIF5', 'PKIF4', 'PKIF3', 'PKIF1', 'OXIF2', 'OXIF1', 'OUTDGT2', 'OUTDGT1', 'NUIF23 2', 'NUIF23 1', 'NUIF22 2', 'NUIF22 1', 'NUIF21 2', 'NUIF21 1', 'NUIF14', 'NUIF12', 'NUIF11', 'NUADFX3 1', 'NUADFX2 1', 'NUADFX1 1', 'IVOL', 'ISED3', 'ISED2', 'ISED1', 'IHEAT', 'GATMP', 'DEWTMP', 'CLOUD']
- All names in ui:
['uunits', 'steps', 'nrows', 'nodfv', 'nexits', 'errlen', 'delt', 'VOL', 'VCONFG', 'STCOR', 'OUTDG5', 'OUTDG4', 'OUTDG3', 'OUTDG2', 'OUTDG1', 'ODGTF5', 'ODGTF4', 'ODGTF3', 'ODGTF2', 'ODGTF1', 'ODFVF5', 'ODFVF4', 'ODFVF3', 'ODFVF2', 'ODFVF1', 'NOCGT', 'NEXITS', 'LKFG', 'LEN', 'KS', 'IRMINV', 'IREXIT', 'ICAT', 'FUNCT5', 'FUNCT4', 'FUNCT3', 'FUNCT2', 'FUNCT1', 'FTBW', 'DELTH', 'DB50', 'CPRI5', 'CPRI4', 'CPRI3', 'CPREC7', 'CPREC6', 'CPREC5', 'CPREC4', 'CPREC3', 'CPREC2', 'CPREC1', 'COLIN5', 'COLIN4', 'COLIN3', 'COLIN2', 'COLIN1', 'CFVOL3', 'CFVOL2', 'CFVOL1', 'CFVOL', 'CFRAC7', 'CFRAC6', 'CFRAC5', 'CFRAC4', 'CFRAC3', 'CFRAC2', 'CFRAC1', 'CEXIT4', 'CEXIT3', 'CEXIT2', 'CEXIT1', 'CEVAP5', 'CEVAP4', 'CEVAP3', 'CEVAP2', 'CEVAP1', 'CDEM2', 'CDEM1', 'AUX3FG', 'AUX2FG', 'AUX1FG']
- Recall,
ui
is passed into_hydr_
.ui
is a dictionary:ui = make_numba_dict(uci)
- Recall,
- HYDR/table columns:
"","index","DEP","IVOL","O1","O2","O3","OVOL1","OVOL2","OVOL3","PRSUPY","RO","ROVOL","SAREA","TAU","USTAR","VOL","VOLEV"
- Test Runs:
- Test 0: Raw, no changes:
step: 8759 of: 8760 steps
Trying specl
[83.55184937 -0. 0. ]
83.55184936523438
Made it to specl()
Made it to _specl_()
[-0.0, -0.0]
[83.55184936523438, 83.55184936523438]
[83.55184937 -0. 0. ]
83.55184936523438
[83.55184937 -0. 0. ]
- Test 1: Inside SPECL.py:
ts['OUTDGT2'][step] = 99
- Note: there was no observed change in output h5 HYDR_table
step: 8759 of: 8760 steps
Trying specl
[83.55184937 -0. 0. ]
83.55184936523438
Made it to specl()
Made it to _specl_()
99.0
83.55184936523438
[83.55184937 -0. 0. ]
83.55184936523438
[83.55184937 -0. 0. ]
- Test 2: In HYDR.py:
OUTDGT[step, :] = [ts['OUTDGT1'][step], ts['OUTDGT2'][step], 0.0]
- Now in output h5 HYDR_table,
O2
= 99 for many timesteps
- Now in output h5 HYDR_table,
step: 8759 of: 8760 steps
Trying specl
OUTDGT[step, :] [83.55184937 -0. 0. ]
ro 78.74899348493953
Made it to specl()
Made it to _specl_()
ts['OUTDGT2'][step] 99.0
ts['OUTDGT1'][step] 83.55184936523438
OUTDGT[step, :] [83.55184937 -0. 0. ]
OUTDGT[step, :] [83.55184937 99. 0. ]
roseff 78.74899348493953
outdgt[:] [83.55184937 99. 0. ]
- Findings in HYDR/table
- RO = O1 + O2 + O3
- ROVOL = OVOL1 + OVOL2 + OVOL3
- Pass by reference vs. Pass by value
-
When you pass an object into a function, you're passing a reference (a reference to that data in memory, not a copy)
- If you change the data of that object, you’re changing the original object
- Verified that changing a value on the
ts
dict object within_specl_
automatically alters the ts object withinhydr()
-
When you pass an object into a function, you're passing a reference (a reference to that data in memory, not a copy)
- slicing np arrays makes a difference: https://github.com/HARPgroup/HSPsquared/issues/20
- O3 could be a reservoir thing
- They have exits - sometimes exits represent withdrawals, sometimes they represent releases
- so those exits might get mapped over to an O
- confirmed OVOL3 is the outflow from the reach to the next downstream segment
- OVOL1 2 and 3 are all flows out of the reach
- makes sense that’s overwriting it because that happens after specl
- the Os are exits
- O1 is exit 1, O2 is exit 2
- RO:
- ROVOL:
- O2 goes from 99 to O, this can happen, the Os get modified if there’s not enough water in the reach
- O1 + O2 + is the satisfied demand
- It satisfies the withdrawal “outflow” before the flow out of the reach (makes sense)
- OD is the outflow demand
- either by way of the ftable geom
- or the requested demands
- Lowercase o in the code is an array of O1 + O2 + O3
- Nexit in the uci represents the total number of exits (3 in this case)
- it relates to OD1 OD2 OD3
- irrigation withdrawals is a separate operation, CBP doesn’t use that, its there from the original HSPF developed in the 70s
- recall CBP model != HSPF
- Next:
- Try setting OUTDGT in a way that allows us to modify in in ts (~ line 73 in HYDR)
- If there’s *** anywhere on a line in HSPF, that whole line is a comment
- SO line 51 are the only values that matter in the uci
- Line 78 in HYDR.py is checking those flags
- Then the next test is - does modifying this actually modify the value in ts
- develop is essentially respec's beta version branch
- they do their development on branches, then pull request to develop branch, then pull request to master
- Made "initial" pull request from HARPgroup/specl -> respec/develop: https://github.com/respec/HSPsquared/pull/104
- Last time Rob linked python 3.9
- Was pointing to 3.8 with a symbolic link, and is now pointing to 3.9
- https://github.com/HARPgroup/HSPsquared/issues/9#issuecomment-1300411794
- The
ls -lhrt
line for python3 should show the link between the 2
- Python3 -V
- Have to sudo when installing packages, otherwise it’ll do it in your local environment
-
sudo pip install .
(Works from within the HSPsquared directory) - Rob IS able to install with the main branch BUT not the develop branch
- I verified this is the same on my machine too
- environment_dev.til calls updated versions of the packages
- One thing to try is updating our packages
- Hints for Linux
- diff file name file name
- This will show differences if there are any
- similarly, git diff will show you all the changes you’ve made
- remove a directory with rm -Rf testcbp
- cp FROM TO
- Unlikely our pushed updates would be causing this (the PSA branch and the SPECL)
- This was the flow of branch merges we did
- Specl -> psa -> develop
- This was the flow of branch merges we did
- Git checkout (commit id)
- Using this method we compared earlier commits and then tried to reinstall hsp2 till it worked
- **configuration.py is where we should be loading the specl.py
- Will keep tinkering
- One option, take a copy of that good commit and sequentially put in our changes
Afternoon:
- Create a new branch from an existing branch
git checkout -b [to_branch_name] [from_branch_name]
- I made a new branch that is an exact copy of the master, and it compiles
- specl_11.2.22
- Next steps:
- We want to modify ts dictionary values without resetting ts
- Within SPECL, change value of outdgt2
- Look at old branch, review progress, attempt to that within the specl function
- RB will set up his equation function to do this
- We know how to modify the ts variable, Now we need to know how to modify the state variable (outdgt)
- See: https://github.com/HARPgroup/HSPsquared/issues/5#issuecomment-1309287801