What’s New#
v3.1.0 (Unreleased)#
New Features#
A migration guide for updating projects from pywatershed 2.x to 3.x,
version_migration_guides/v2_to_v3.md: the verified, complete list of breaking changes with scans, fixes, and symptom lookup, written to be followed by a person or handed whole to an AI assistant. Retroactive additions to the v3.0.0 Breaking Changes section below record five changes it documents that were found undocumented. (PR416) By James McCreight.HRU cascading flow (Hortonian surface runoff and soilzone interflow / Dunnian flow) following PRMS
cascade_flag=1withcascadegw_flag=0: new process classesPRMSRunoffCascadesNoDprstandPRMSSoilzoneCascadesNoDprst, cascade parameter preprocessing from PRMS parameter files (preprocess_cascade_params()), and support for inactive HRUs viabase.ActiveHruMixin(which HRUs are active is always derived from thehru_typeparameter; results at inactive HRUs are masked tonanand excluded from mass-balance checks by the newactive_maskcapability ofbase.Budget). Verified against PRMS 5.2.1 on thesagehen_5yr(sagehen_no_gw_cascades) and new griddedsagehen_gridded_5yr(5609 cells with inactive cells) test domains, both tested in CI on all platforms. Demonstrated in the new notebookexamples/11_cascading_flow.ipynb. (PR407) By James McCreight.analysis.ProcessPlotreads geodatabase layers (hru_layer/seg_layername the layer withinhru_shp_file_name/seg_shp_file_name), sizes each map to the domain’s extent and sets the initial view to it, andProcessPlot.plot_hru_var()maps a(time, nhru)array as one frame per time with a time widget (climholds the color scale across frames;timemay be omitted for a DataArray with atimecoordinate). A layer whose CRS has no EPSG code raises; a layer declaring no CRS is taken as EPSG:5070. Shown inexamples/11_cascading_flow.ipynb. (PR407, PR423) By James McCreight.The gridded
sagehen_gridded_5yrtest domain generates its own CBH forcing files with PRMS from its two-station data file (the 5609-cell text files are ~600 MB, too large to distribute), making it fully reproducible from a clean clone. For this, the CBH writer inprms_src(write_climate_hru.f90) is patched to write full precision (G0format in place ofE12.4), so the forcing pywatershed reads carries the values PRMS computed rather than four-digit roundings. (PR407) By James McCreight.Reading a PRMS parameter file expands the compact forms PRMS allows to the full shape pywatershed expects: a parameter given on
nmonthalone is broadcast to(nmonth, nhru), andtmax_adjandtmin_adjgiven onnhrualone are broadcast to(nmonth, nhru)(thesagehen_gridded_5yrparameter file uses both). A monthly parameter is recognized by its declarednmonthdimension, not by having 12 values. A shape not handled passes through with the dims the file declares. (PR407, PR423) By James McCreight.separate_domain_params_dis_to_ncdf()takes an optionalcontrol; when itscascade_flagis set the cascade parameters are derived before separation so the cascade process classes get complete parameter files. Awrite_disswitch skips the discretization files when only process files are wanted. The scripttest_data/generate/separate_params_to_nc.pyreplaces theprms_parameter_discretization_separationnotebook as the single way the test domains’parameters_*.ncfiles are written. (PR407) By James McCreight.Restart capability (
restart_read,restart_write,restart_write_freq) forPRMSSoilzoneNoDprst, which previously raisedNotImplementedError, and for the new cascade classesPRMSRunoffCascadesNoDprstandPRMSSoilzoneCascadesNoDprst(which also gaininput_aliases). The soilzone restart state, also forPRMSSoilzone, now includespref_flow_stor, which is live whereverpref_flow_den > 0(previously omitted, so such restarts were not exact; the NHM test domains havepref_flow_den = 0). The process-level perfect-restart test, nowautotest/test_restart_processes.py(wastest_nhm_restart.py), picks the process classes from the control file and its dates from the simulation period, so it runs on the sagehen domains and theno_dprstcontrols too. That exposed a second omission:PRMSSnownow saves PRMS 5.2.1’s full snowcomp restart state (addsint_alb,salb,lst,iso,mso,lso,albedo,pk_temp,snsv), whose omission made restarts of a depleting snowpack inexact. (PR407) By James McCreight.
Breaking Changes#
PRMSCanopytakes the inputpkwater_antein place of the inputspk_ice_prevandfreeh2o_prev, andPRMSSnowdeclares the variablepkwater_anteto supply it. Code which suppliesPRMSCanopyits inputs individually must be updated; models assembled from process lists or model dictionaries are unaffected. (PR414) By James McCreight.hru_typeis now a declared parameter ofPRMSAtmosphere,PRMSAtmosphereTranspFrost,PRMSAtmosphereTranspFrostDynamic,PRMSSolarGeometry,PRMSCanopy,PRMSGroundwaterandPRMSGroundwaterNoDprst, which use it (throughbase.ActiveHruMixin) to identify inactive HRUs. AParametersobject built by hand for one of these processes must now includehru_type; PRMS parameter files and theparameters_dis_hru.ncdiscretization file written byseparate_domain_params_dis_to_ncdf()already carry it. As a consequence,PRMSCanopynow applies PRMS’s lake treatment to HRUs withhru_typelake (no interception), where it previously treated every HRU as land; results change on domains with lake HRUs. Note that lake HRUs are currently untested in pywatershed: no test domain contains one. (PR407) By James McCreight.Keyword arguments were inserted mid-signature:
stream_seg_in=Nonenow precedesdprst_flaginPRMSSoilzone, andactive_mask=Noneprecedesunit_descinbase.Budget. Code passing those or any later arguments positionally must switch to keywords. (PR407, PR423) By James McCreight.Every process is named for its class:
Process.__init__setsself.name = type(self).__name__and no subclass assignsnameitself. The subclasses’ own assignments all matched their class names already, except thatPRMSAtmosphereTranspFrostandPRMSAtmosphereTranspFrostDynamicinherited their parent’s"PRMSAtmosphere"; their single-file netCDF output (whennetcdf_output_separate_filesis off) and budget descriptions now carry their own class names. (PR423) By James McCreight.The variable metadata entry
hru_hortn_cascflow(PRMS’s name, declared by no process) is replaced byhru_horton_cascflow, the variablePRMSRunoffCascadesNoDprstdeclares; the unusedstrm_seg_inentry is removed in favor ofstream_seg_in, declared by both cascade classes. PRMS output files are renamed on conversion to netCDF. (PR407, PR423) By James McCreight.
Bug fixes#
NetCdfWritesilently dropped a string coordinate whose maximum length matched an earlier string coordinate’s (the two share achar<N>dimension, and the guard against creating that dimension twice also skipped creating the variable). InFlowGraphoutputnode_maker_idwent missing whenever its ids were as long as thenode_maker_namevalues. Reported in GH421. (PR422) By James McCreight.Loading a parameter netCDF file with netCDF4 (the default for
Parameters.from_netcdf()) dropped a coordinate that no data variable uses (recorded in the file’s globalcoordinatesattribute), so a process declaring a dimension none of its parameters use, e.g.nsegmentforPRMSRunoffCascadesNoDprst, could not write netCDF output on that dimension. (PR407) By James McCreight.PRMSCanopygates rain interception by grasses on the antecedent snowpack,pkwater_ante, as PRMS does (intcp.f90:416, which testsPkwater_equivbeforesnowcompupdates it for the timestep;snowcomp.f90:946publishes that value asPkwater_ante). pywatershed instead reconstructed the pack aspk_ice_prev + freeh2o_prev. PRMS carriesPkwater_equivas its own accumulated double rather than recomputing it as that sum, and in the vanishing tail of a melting pack the two differ by orders of magnitude and fall on opposite sides of thednearzero(2.23e-16) threshold, flipping whether a day’s rain is intercepted.PRMSSnownow declarespkwater_ante, assnowcompdoes (snowcomp.f90:346-349), so coupled models supply it. (PR414) By James McCreight.Modelreports both candidate filenames when an input file is missing. Input discovery looks for<variable>.ncin the input directory and, failing that, retries the same name as<variable>.param; only the second name reached the error, so a missing netCDF input was reported as a not-found dynamic parameter file. Both lookups are now checked up front and a missing input raises naming both candidates. (PR407) By James McCreight.Integer variables written by
dd_to_nc4_ds()(and so byDatasetDictandseparate_nhm_params()) no longer carry a default_FillValueof -9999, which made xarray promote them to float on read and turn legitimate -9999 values into NaN. The in-memory fill used to mask inactive HRUs is now the separatemask_fill_values_dict. (PR407) By James McCreight.ProcessPlot.plot_hru_var()no longer errors on avar_namethat contains a known variable or parameter name as a substring (the metadata lookup passed the string where a list of names is expected, so"sroff (cascade - no cascade)"matchedsroffand then failed to find itself). (PR407) By James McCreight.NetCDF output no longer floods the console with NumPy’s
Setting the shape on a NumPy array has been deprecatedwarning (one per variable per timestep with netCDF4 <= 1.7.4 and NumPy >= 2.5). The suppression is applied around each write in code, not only as a pytest filter, because flopy setswarnings.simplefilter("always", DeprecationWarning)at import and overrides any earlier filter; seeMAINTENANCE.mdfor when it can be removed. (PR419) By James McCreight.
Internal changes#
The public API surface (exports,
__init__signatures, declared input/variable/parameter name sets, control options, and variable/parameter metadata) is snapshotted inautotest/api_surface.txt, generated byautotest/api_surface.pyand checked byautotest/test_api_surface.py(domainless). A surface change fails CI until the baseline is regenerated with the script’s--writeoption — and, if any existing line changed or was removed, documented under Breaking Changes. (PR416) By James McCreight.Retire the last intel-built artifact, the GSFLOW binary for MacOS, which was x86_64 and required Rosetta 2 on Apple Silicon. All three checked-in GSFLOW 2.4.0 binaries (macOS arm64, Linux, Windows) are now gfortran double-precision builds from a single GSFLOW source commit and CI run, with provenance recorded in
bin/README.mdfor the first time. (PR415) By James McCreight.Quiet the test suite’s NumPy >= 2.5 deprecation warnings, which numbered tens of thousands per run.
constants.natis nownp.datetime64("NaT", "ns"), the generic form being deprecated andnsbeing what its only use already cast to;environment.ymlrequiresholoviews >=1.23.0, the release which dropped thenat_as_integerthe warning came from; andautotest/pytest.iniignores thendarray.shapeassignment that netCDF4 <= 1.7.4 makes on every variable write, which is fixed upstream by netcdf4-python PR #1469 but unreleased and so is tracked inMAINTENANCE.md. (PR414) By James McCreight.Retire ifort and Intel MacOS. The PRMS binaries are no longer checked in to
bin/; they are compiled fromprms_src/with gfortran (supplied byenvironment.yml) the first time they are needed, bypywatershed.utils.compile_prms(), whichci.yaml,autotest/ci_local.sh, and the test-data fixtures all call. Theprms_srcmakelists gained-std=gnu17for gcc, without which PRMS 5.2.1’s C sources fail to build under the C23 default of gcc 15. Apple Silicon binaries are taggedmac_armrather thanm1, and Intel MacOS is no longer detected. GSFLOW binaries remain checked in because their source is not part of this repository. (PR414) By James McCreight.Lint Jupyter notebooks.
[tool.ruff] includecovered only*.py, soruff check .and CI never saw notebooks, while the pre-commit hook passed*.ipynbpaths explicitly (which overridesinclude) and did. Notebook problems were therefore invisible until someone edited a notebook and was met with errors they had not caused. Notebooks are now ininclude, withE501andI001exempted: they are narrative, and several import a module purely for its side effect (hvplot.xarrayregisters a.hvplotaccessor) and must do so after the module they extend, which sorting undoes. Notebooks are linted but not auto-formatted, for the same line-length reason. This surfaced four broken cells that no test covered: two stray), a string opened with"and closed with', and a use ofpl.Pathwith noimport pathlib. Three notebooks needed further cleanup once the syntax errors stopped masking it: unused imports, unused assignments, a semicolon-joined statement, and bareexceptclauses narrowed toexcept AssertionError. Also repairs four malformed# noqadirectives (including a# noaqtypo) that ruff silently ignored, which meant the unused-import fixer would have deleted thehvplotimports they were meant to protect. (PR412) By James McCreight.Add
MAINTENANCE.md, a ledger of maintenance todos blocked on external events (dependency releases, cross-repo work), each with a mechanically checkable unblock condition; the/maintenanceClaude skill checks them live and reports what is actionable. (PR409) By James McCreight.Reduce CI footprint with a skeleton/full split: pushes to any branch (in this repository or on forks) run a skeleton — installs, linting, domainless tests, the docs build, and example notebooks on ubuntu only — while the full suite (domain test jobs, all platforms) runs for pull requests (including drafts), pushes to
develop/main, andworkflow_dispatch. Domain jobs can be opted in on branch pushes with aci-<token>(e.g.ci-fgr,ci-all) in the branch name or head commit message — see DEVELOPER.md.concurrencygroups cancel in-flight runs superseded by a newer push on the same non-mainline ref. (PR408) By James McCreight.PRMSCanopy,PRMSSnow,PRMSRunoffandPRMSSoilzone(and their no-dprst and cascade subclasses) loop over active HRUs only, the cascade classes in routing order;PRMSAtmosphere,PRMSSolarGeometryandPRMSGroundwatercompute every HRU and mask the inactive ones at initialization, as doesPRMSRunoffAg, which loops over all HRUs. All-active domains are unaffected. (PR407, PR423) By James McCreight.compile_prms()prefers the active Python environment’sgfortran/gcc(e.g. conda-forge’s) over ones earlier on the PATH, and fails up front naming whichever ofmake,gccandgfortranis missing. (PR407) By James McCreight.Require pyPRMS >=0.10.0 and remove the temporary
packaging <26.3pin it supersedes (pyPRMS 0.9.10 crashed on import of metadata with packaging >=26.3). Also remove calls to pyPRMS methods deprecated in 0.10.0:Parameters.adjust_bounded_parameters()in domain subsetting andDataFile.data_by_variable()in the obsin flow node test. (PR406) By James McCreight.
v3.0.0 (13 July 2026)#
A migration guide for updating a project from v2.x, written to be followed by a person or handed to an AI assistant, is at version_migration_guides/v2_to_v3.md in the repository.
New Features#
The new staticmethod
Model.solve_inputs()determines where each process input comes from — another process or a file — from a process list or model dictionary, without instantiating a Model or requiring any files to exist. Useful for determining the file inputs a model configuration requires, e.g. when forcing a sub-model from another model’s outputs. Model construction uses the same implementation internally. (PR396) By James McCreight.The
base.ConservativeProcessclass now supports both mass and energy budgets. Processes can specify which quantity to budget using thequantityparameter in_set_budget(). The newmass_budgetandenergy_budgetproperties provide explicit access to each budget type. The legacybudgetproperty is deprecated and will be removed in the next major release - usemass_budgetinstead. (PR343) By James McCreight.The new
PRMSStreamTempandPRMSStreamTempHumidityCBHclasses provide stream temperature simulation using the PRMS stream temperature methodology, computing water temperatures based on energy balance in stream segments. The latter class accepts time-varying humidity inputs on the HRUs while the former accepts a mean monthly humidity for each segment. The classes support optional energy flux tracking and budgeting via thetrack_energy_fluxesparameter (default: True). When enabled, it computes and tracks 11 energy flux components including advective heat transport (upstream, lateral, outflow), surface energy exchange (solar radiation, longwave emission/absorption, evaporative cooling, convective exchange), and internal sources (friction heating, groundwater conduction). These fluxes are available as output variables and included in the energy budget. When disabled (track_energy_fluxes=False), energy flux variables are set to None and excluded from NetCDF output, withimbalance_behaviorrequired to be None. The classesPRMSStreamTempandPRMSStreamTempHumidityCBHtake a stream shade class as input on initialization. Two stream shade classes have been implemented,PRMSStreamShadeConstantandPRMSStreamShadeDynamic. The former works based on 3 parameters: summer shade fraction, winter shade fraction, and segment latitude. The latter class computes shade dynamically based on topographic and vegetation parameters using solar geometry calculations. This is the default PRMS behavior whenstream_temp_shade_flag = 0and requires 13 parameters describing topography and vegetation characteristics for each stream segment. The classesPRMSStreamTempandPRMSStreamTempHumidityCBHalso require one ofPRMSHydraulicGeometryFullorPRMSHydraulicGeometryWidthOnlyas an upstream process to provide hydraulic geometry variables needed for energy balance calculations.PRMSHydraulicGeometryFullcomputes flow-dependent hydraulic geometry (width, depth, area, velocity) using power-law relationships when all parameters are provided, whilePRMSHydraulicGeometryWidthOnlyuses PRMS default values for depth parameters (depth_alpha=0.27, depth_m=0.39) when they are missing from the parameter file, matching PRMS 5.2.1 behavior. These capabilities are demonstrated in notebooksexamples/01_multi-process_models.ipynbandexamples/02_prms_legacy_models.ipynbas part of the NHM configuration in pywatershed. (PR343) By James McCreight.Option for
Modelclass to read from a single netcdf file or (not and, the existing option,) from a directory containing multiple netcdf files. (PR333) By James McCreight.A new
SourceSinkFlowNodeclass adds or removes flow above some minimum flow parameter as specified by an input data file. (PR327) By James McCreight.The
Controlclass has new method edit_init_start_times to manage changing these times. (PR335) By James McCreight.The
FlowGraphclass has new method plot to show an abstract plot of the FlowGraph. (PR351) By James McCreight.The
base.Processclass and subclasses have a new restart capability. See notebookexamples/08_restart_streamflow.ipynbfor examples. (PR349, PR362) By James McCreight.The
PRMSAtmosphereTranspFrostimplements the transp_frost module of PRMS. (PR354) By James McCreight.The
PRMSAtmosphereTranspFrostDynamicextendsPRMSAtmosphereTranspFrostto accept dynamic (time-varying) fall_frost and spring_frost dates from PRMS dynamic parameter files, reproducing PRMS/GSFLOW runs withdyn_fallfrost_flagand/ordyn_springfrost_flagset. (PR392) By James McCreight.The load() method of
parameters.PrmsParametersnow supports reading multiple parameter files which are treated as addenda to the first parameter file in the list which contains the dimension information. (PR354) By James McCreight.The
StarfitSourceSinkFlowNodeallows sources and sinks to interact with storage of a Starfit reservoir/FlowNode. (PR348) By James McCreight.The new
Outputclass provides flexible output collection and statistical analysis for models, supporting HRUs of interest (HOI), segments/nodes of interest (NOI), and monthly accumulations. Includes Zarr chunked output capability for efficient large-scale data writing (~6x faster than NetCDF). See notebookexamples/09_model_output.ipynbfor examples. (PR363) By James McCreight.New agricultural water use classes enable simulation of irrigated agriculture based on GSFLOW.
PRMSRunoffAgextendsPRMSRunoffto calculate infiltration separately for pervious and agricultural areas.PRMSSoilzoneAgObsETprovides dual-area soil moisture accounting with iterative adjustment of irrigation to match observed actual ET.PRMSSoilzoneAgis a simplified version without the observed ET iteration, suitable when ET observations are not available. See notebookexamples/10_ag_irrigation_use.ipynbfor examples. (PR362) By James McCreight.Add pre-commit hook to run security review on staged files or on entire repository, checks for: 1. Absolute paths, 2. IP addresses, 3. Internal server hostnames, and 4. Usernames/passwords or credentials. See .github/scripts/check_security.py. (PR384) By James McCreight.
Bug fixes for PRMS 5.2.1.1: 1) errant code skipped humidity CBH files entirely when they were selected to be used, 2) code deletion resulted in
seg_humidnot being zeroed each timestep and erroneously accumulating. Both fixes are extensively documented. The PRMS code was modified (compared to the released 5.2.1.1) and the pywatershed code was made to match PRMS stream temperature when using humidity inputs from 1. CBH, 2. scalar parameter, and 3. monthly spatially distributed parameters. (PR386) By James McCreight.Add a weekly security scan using Safety CLI in a GitHub Actions workflow (
.github/workflows/security_check.yaml): checks conda-installed packages, pip-installed packages, andpyproject.tomldependencies separately. (PR387) By James McCreight.
Breaking Changes#
The
budget_typeparameter has been renamed toimbalance_behaviorinbase.ConservativeProcessand all its subclasses, inbase.FlowGraph, and in control options. Update allbudget_typereferences toimbalance_behaviorin your code and configuration files. This breaking change clarifies what the parameter does and is intentionally distinct from the budget quantity parameter. (PR343) By James McCreight.Budget netcdf output filenames have changed to include the quantity type. Mass budgets are now named
ProcessName_mass_budget.ncinstead ofProcessName_budget.nc. Energy budgets useProcessName_energy_budget.nc. (PR343) By James McCreight.The variable
seg_widthwas renamedseg_flow_width. It is the only variable removed from the metadata in this release; code selecting it for output, or reading it from output files, must use the new name. (PR343) By James McCreight.PRMSAtmosphereno longer overridesget_variables()and so inheritsbase.Process’s implementation, which returns the keys ofget_init_values(). The result is alistof 15 names where it was atupleof 14;tmax_sumis now included. Code which iterates the result, to select output variables for example, gets a variable it did not get before and raises no error. (PR349) By James McCreight.The method
PRMSAtmosphere.calculate_transp_tindexwas renamedcalc_transp_tindex. (PR354) By James McCreight.FlowNodeMaker.get_nodetakesselfas its first argument; the base class previously declaredget_node(control, index)without it. Thebase.FlowNodeMakersubclasses in pywatershed already suppliedself, but custom subclasses which copied the base class signature must add it. (PR348) By James McCreight.Control.load_prms()changed in two ways. The optionsparameter_file,netcdf_output_dirandstreamflow_moduleare unwrapped from their single-element lists only when exactly one value is present; two or more values are now retained as a list. Andkeep_unused_options=Trueno longer forceswarn_unused_optionstoTrue, so the two are set independently. (PR354) By James McCreight.
Bug fixes#
The
PRMSRunoffAgmass budget did not balance on days with canopy changeover (intcp_changeover > 0, at canopy density transitions), for two reasons: the budget input termintcp_changeover_budgetwas assigned only in dead code and remained zero, and depression storage inflow was missing changeover water when changeover is carried separately from net_rain (intcp_changeover_in_net_rain=False). GSFLOW carries changeover inside net_rain, whereby its depression storage receives this water. With the fix the budget closes to machine precision. (PR401) By James McCreight.utils.PrmsDynamicParameterdaily_data_arrayleft fill values for days betweendaily_start_dateand the first dynamic parameter date inside that window, instead of forward-filling from the most recent date at or beforedaily_start_dateas PRMS applies dynamic updates. Only runs starting between dynamic parameter dates were affected. (PR393) By James McCreight.PRMS 5.2.1.1 had a bug in stream temperature where division by HRU area was repeated multiple times. In the old code this occurred in routing.f90 on lines 764 and 765 and then again on 789 and 790, where
seginc_swradandseginc_potetwere divided despite this having already occurred on lines 744 and 745. Comments regarding the fix are found on lines 764 and 793 in the fixed code. (PR383) By James McCreight.
Internal changes#
The
base.ConservativeProcessclass now uses_mass_budgetand_energy_budgetattributes internally instead ofbudget. Thebudgetproperty remains as a deprecated alias for_mass_budgetfor backward compatibility.Release procedures were revamped:
.github/RELEASE.mdrewritten as a concrete step-by-step guide with a running example, guarded release automation jobs (checks, package build/publish, frozen conda environment exports per platform), a preflight script shared between local use and CI, and a version-consistency test. (PR395) By James McCreight.CI no longer uses
fortran-lang/setup-fortran; gfortran is provided by the conda environment. (PR394) By James McCreight.CI and the conda environments temporarily install flopy from its develop branch (with codegen options) to accommodate a flopy API change, until the next flopy release. (PR397) By James McCreight.
The autotests now require an explicit
--domainoption; the silentdrb_2yrdefault was removed. (PR393) By James McCreight.autotest/ci_local.shkeeps previously downloaded mf6 binaries on PATH so mf6-dependent tests run even when the modflow section is skipped. (PR398) By James McCreight.Refactor of
test_data/generate/convert_prms_output_to_nc.pyto put final variables into a separate file to run by pytests both after all other variables are generated and so the final variables are run serially. (PR331) By James McCreight.
v2.0.4 (23 February 2026)#
New Features#
Fixes to release workflow, pypi publishing.
v2.0.3 (22 February 2026)#
New Features#
Some minor fixes. This is a data release for the upcoming major release, new data will be an asset on this release.
v2.0.2 (14 March 2025)#
Bug fixes#
Fixed setup.py to allow editable installs, keeping up with changes in the pythonverse. Deprecated all fortran code built and interfaced using f2py as it was not popular and had only maybe very slight speed advantages compared to numba. This was not considered a breaking change because there are redundant alternatives to the fortran. (PR331) By James McCreight.
v2.0.1 (19 December 2024)#
New Features#
Corrected disclaimer on top-level README.md. Other minor fixes not to code base (CI, envs, etc).
v2.0.0 (16 December 2024)#
New Features#
The
FlowGraphcapabilities are introduced. These allow users to combine different kinds flow solutions in arbitrary order on a “flow graph”. The accompanying base classesFlowNodeandFlowNodeMakerare introduced along with their subclasses for modelingPassThroughFlowNodes,ObsInFlowNodes (flow replacement by observations with sink and source tracking in mass balance),PRMSChannelFlowNodes, andStarfitFlowNodes. A new example notebook, examples/06_flow_graph_starfit.ipynb demonstrates adding STARFIT reservoir nodes into a FlowGraph otherwise simulating PRMSChannel and highlights helper functions for this use case. (PR233) By James McCreight.The
MmrToMf6Dfwclass builds a MF6 simulation with Diffusive Wave (DFW) routing from PRMS NHM input files and a few simple assumptions. The lateral (to-channel) fluxes from a PRMS are used as time varying boundary conditions. A new notebook runs the Delaware River Basin using MF6 DFW: examples/07_mmr_to_mf6_chf_dfw.ipynb. (PR290) By James McCreight.No depression storage subclasses are available for PRMSRunoff, PRMSSoilzone, and PRMSGroundwater by adding “NoDprst” to the end of the names. Depression storage is switched off in sagehen_5yr and in new nhm_no_dprst configurations. (PR288) By James McCreight.
Dunnian flow is implemented (in PRMSSoilzone) and tested for sagehen_5yr. (PR288) By James McCreight.
Preferential flow is implemented (in PRMSSoilzone) and tested for sagehen_5yr. (PR288) By James McCreight.
Control instances have a diff method to compare with other instances. (PR288) By James McCreight.
Feature to standardize subsetting input data (parameters and forcings) in space and time either from file (
utils.netcdf_utils.subset_netcdf_file()) or in memory (utils.netcdf_utils.subset_xr()). (PR304) By James McCreight.
Breaking Changes#
pref_flow_infil_frac now a required parameter input for PRMSSoilzone. The NHM values assumed previously are zeros on all HRUs. (PR288) By James McCreight.
Bug fixes#
Fixed calculation of the variable transp_on was incorrectly calculated in certain situations not covered by NHM configuratons but covered by sagehen_5yr. (PR288) By James McCreight.
Fixed calculation of variable dprst_area_open which was not being checked but was affecting no other variables. (PR288) By James McCreight.
The variable pptmix was incorrectly calculated in certain situations not covered by the NHM configurations. (PR288) By James McCreight.
Internal changes#
Testing system refactor to handle pairs of domains and control files allowing much more flexibility in configuration/control testing. (PR278) By James McCreight.
New testing domain “sagehen_5yr” is added to test_data directory with configuration sagehen_no_cascades. This domain introduces multiple PRMS capabilities (noted indvidually in this PR) not used in the NHM configuration and provides a test for these. (PR288) By James McCreight.
Tests are now marked as “domain” or “domainless” to avoid redundant runs of domainless tests across test domains. (PR288) By James McCreight.
New tests test_prms_above_snow and test_prms_below_snow replace test_model and are extremely close to PRMS (PRMSSolarGeometry: 1.0e-8, PRMSAtmosphere: 1.0e-5, PRMSCanopy: 1.0e-6, PRMSRunoff: 1.0e-8, PRMSRunoffNoDprst: 1.0e-8, PRMSSoilzone: 1.0e-8, PRMSSoilzoneNoDprst: 1.0e-8, PRMSGroundwater: 1.0e-8, PRMSGroundwaterNoDprst: 1.0e-8, PRMSChannel: 5.0e-7) for all test domains. (PR288) By James McCreight.
Migration to Numpy 2.0+. (PR310) By James McCreight.
v1.1.0 (25 June 2024)#
New features#
Minor enhancement to ensure PRMSSnow hru_deplcrv parameter is integer or coercable. (PR296) By James McCreight.
Release assests to include new GIS files and an additional domain to support the upcoming major release. By James McCreight.
v1.0.0 (18 December 2023)#
New features#
Control object features including (optional) warnings for unused legacy options, and defined and enforced options. Also to_yaml() and __str__ implementations. (PR240) By James McCreight.
Example notebook of how to edit Parameters with associated bug fixes to do so. (PR232) By James McCreight.
Conda feedstock for pywatershed conda-forge/staged-recipes#23428. By Joseph Hughes.
Breaking changes#
The control.options “netcdf_output_dir”, “netcdf_output_var_names”, and “netcdf_output_separate_files” match the keyword arguments “output_dir”, “output_vars”, and “separate_files” for both process.intitalize_netcdf() and model.initialize_netcdf(). None of these arguments can be supplied in both places (control and method call). It used to be that calling initialize_netcdf() would override what is supplied in control.options but this will now throw an error. The suggestion is to use control.options and not pass arguments to intialize_netcdf(). When using Control.load() (deprecated) or Control.load_prms() from a PRMS control file, note that the “control.options” of “netcdf_output_dir” and “netcdf_output_var_names” are set by values in the PRMS control file. You can edit these, but be aware that they are now set in that load. (PR257) By James McCreight.
Deprecations#
Deprecation of Control.load() for Control.load_prms(). (PR240) By James McCreight.
Performance#
Bug fixes#
Mass balance fix in PRMS snow for rain on snow followed by evaporation consuming the entire snow pack. (PR248) By James McCreight.
Fix mass balance issue in PRMSSnow is also present in PRMS, snow evap is not taken from freeh2o when there is no pk_ice. (PR236) By James McCreight.
Resolve issues with different ways of specifying necdf output options. (PR230) By James McCreight.
Resolve issues with different ways of specifiying netcdf output options. (PR230) By James McCreight.
PRMSSoilzone remove soil_moist_prev because soil_moist is not prognotic and PRMSRunoff was needing it in the advance and not getting the correct value. PRMSRunoff now depends on soil_lower_prev and soil_rechr_prev instead. (PR244) By James McCreight.
Documentation#
Implement sphinx_autodoc_typehints. (PR257) By James McCreight.
New gh-pages branch (without history) to publish “pywatershed notes” including the extended release notes for v1.0.0. This branch publishes analysis supporting the version 1.0.0 release.
Add about section for version 1.0 to describe how pywatershed matches PRMS’ NHM configuration and how to perform the comparison. (PR244) By James McCreight.
Internal changes#
New system for generating test_data, by calling generate_test_data.py from autotest/. The system helps autotest know if test data were generated and if they are up to date. (PR253) By James McCreight.
Apply pylint and flake8 everywhere as much as possible. (PR251) By James McCreight.
Remove diagnostic variables pkwater_equiv_change, pkwater_ante (PR248) By James McCreight.
Use v1 instead of main for fortran-lang/setup-fortran. (PR242, PR243) By Wes Bonelli.
Refactor test data generation to solve race condition for dependent tests. (PR237) By Wes Bonelli.
Refactor tests against PRMS for consistency, flexibility, and thoroughness. (PR244) By James McCreight.
v0.2.1 (19 July 2023)#
Bug fixes#
Package data was not properly installed. (PR219) By James McCreight.
Small addition to notebook 02 (PR219) By James McCreight.
v0.2.0 (18 July 2023)#
New features#
New example notebooks. Moved old notebooks to examples/developer. (PR204) By James McCreight.
New way to specify Model instantiation either in-memory or from yaml files using a model dictionary. The approach is loosely based on MODFLOW 6 input organization. See Model documentation. Introduced the concept of discretizations for PRMS, defining “dis_hru” and “dis_seg”. These are components of how model dictionaries are specified. (PR188) By James McCreight.
New Control.from_yaml() method. (PR188) By James McCreight.
What’s new workflow (behold!) per GH180 and PR181 By James McCreight.
Add automatic release workflow to PyPi as per GH178. Associated implementation of gitflow and semver conventions. Overhauled CONTRIBUTING.md, DEVELOPER.md, README.md, and .github/RELEASE.md to document adopted practices. Adoption of git-cliff to generate change logs by filtering comitt messages, see cliff.toml. Clean up of environment files and streamlining against pyproject.toml. Symlink gfortran dylibs to /usr/local/lib on macOS CI so PRMS binaries included in this repo can find them. (PR179) By Wes Bonelli.
Breaking changes#
Move Control attribute “config” to “options” for handling global options. (PR188) By James McCreight.
Remove arguments from Model initialization. Options pass via control, new set_options() method on Process and ConservativeProcess (PR188) By James McCreight.
Control no longer takes a Parameter object as an initialization argument. Process subclasses now require arguments discretization and parameters. The firstargument of Model not a indefinite number of processes, it is now either a list of Process subclasses or a model dictionary (see Model documentation. (PR188) By James McCreight.
Deprecations#
Performance#
Introduce ASV performance benchmarks for import and various NHM configurations in pywatershed. (GH170 and PR184) By James McCreight.
Bug fixes#
Remove non-pep-compliant post-release reset PR steps. (PR203) By Wes Bonelli.
Add doc building requirements to environment.yml (PR188) By James McCreight.
Revive fortran compiling for editable installs (PR188) By James McCreight.
Made the Parameter class data completely private by converting dicts to MappingProxyTypes and setting numpy.ndarrays to read-only. (GH177 and PR183) By James McCreight.
ModelGraph improvements and fixes (however result are platform dependent) (PR162) By James McCreight.
Documentation#
Model class, DatasetDict and general documentation overhaul (PR188) By James McCreight.
Internal changes#
Introduce precommit hooks: nbstripout, blackdoc, and doctoc. (PR197) By James McCreight.
Rename StorageUnit to ConservativeProcess that subclasses from a new Process class that contains most of the StorageUnit functionality. (PR188) By James McCreight.
New set_options() method on Process and ConservativeProcess to set their initialization options as ‘_` atrributes. (PR188) By James McCreight.
Clean up of how the calc_method option assigns function names to reduce the total amount of code and do it upon initialization. (PR188) By James McCreight.
Rename many modules to use lower-snake-case names including those in base/, atmoshpere/, and hydrology/ (PR188) By James McCreight.
NHM “self-driving” tests (PR160) By James McCreight.
Refactor dependencies for standard pypi installation. (PR164, GH178) By Joseph Hughes.
v0.1.1 (27 April 2023)#
Initial release.