From 59df264e9262caa5b89022b4aad1943afad529b0 Mon Sep 17 00:00:00 2001 From: ashleymedin Date: Wed, 5 Nov 2025 01:23:33 +0900 Subject: [PATCH 1/4] cython had to be turned on, some geopackages have different nexus names for hydrolocations --- src/troute-network/setup.py | 2 +- src/troute-network/troute/HYFeaturesNetwork.py | 13 ++++++++++++- src/troute-routing/setup.py | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/troute-network/setup.py b/src/troute-network/setup.py index 8193ca0b6..e27207da1 100644 --- a/src/troute-network/setup.py +++ b/src/troute-network/setup.py @@ -17,7 +17,7 @@ sys.argv.remove("--use-cython") else: USE_CYTHON = False - +USE_CYTHON = True ext = "pyx" if USE_CYTHON else "c" # adapted from https://stackoverflow.com/a/5192738/489116 and https://stackoverflow.com/a/32192172/489116 diff --git a/src/troute-network/troute/HYFeaturesNetwork.py b/src/troute-network/troute/HYFeaturesNetwork.py index e94cd47e5..b3313a01a 100644 --- a/src/troute-network/troute/HYFeaturesNetwork.py +++ b/src/troute-network/troute/HYFeaturesNetwork.py @@ -133,7 +133,18 @@ def read_layer(layer_name): lakes["lake_id"] = lakes["lake_id"].astype(int) lakes = lakes.merge(hydro[["hl_link", "id", "hl_reference"]], left_on="lake_id", right_on="hl_link", how="left") - # add hl_uri to nexus + # hydrolocations may call the nexus key "nex_id" or simply "id" + if "nex_id" in hydro.columns: + right_col = "nex_id" + elif "id" in hydro.columns: + right_col = "id" + else: + raise KeyError("HYFeaturesNetwork: hydrolocations layer missing expected nexus id column. available: " + ", ".join(list(hydro.columns))) + + # normalize to 'nex_id' for downstream code, then merge to get hl_uri for nexus + if right_col != "nex_id": + hydro = hydro.rename(columns={right_col: "nex_id"}) + nexus = nexus.merge(hydro[["nex_id", "hl_uri"]], left_on="id", right_on="nex_id", how="left") return flowpaths, lakes, network, nexus diff --git a/src/troute-routing/setup.py b/src/troute-routing/setup.py index a14939f5a..12b0312ed 100644 --- a/src/troute-routing/setup.py +++ b/src/troute-routing/setup.py @@ -18,7 +18,7 @@ sys.argv.remove("--use-cython") else: USE_CYTHON = False - +USE_CYTHON = True ext = "pyx" if USE_CYTHON else "c" # adapted from https://stackoverflow.com/a/5192738/489116 and https://stackoverflow.com/a/32192172/489116 From 73a26b89a3c4510e4b8d4f6ff956d8012c2b6764 Mon Sep 17 00:00:00 2001 From: ashleymedin Date: Wed, 5 Nov 2025 01:31:36 +0900 Subject: [PATCH 2/4] compiler --- compiler_mac.sh | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100755 compiler_mac.sh diff --git a/compiler_mac.sh b/compiler_mac.sh new file mode 100755 index 000000000..16eab4000 --- /dev/null +++ b/compiler_mac.sh @@ -0,0 +1,139 @@ +#TODO add options for clean/noclean, make/nomake, cython/nocython +#TODO include instuctions on blowing away entire package for fresh install e.g. rm -r ~/venvs/mesh/lib/python3.6/site-packages/troute/* +#set root folder of github repo (should be named t-route) +REPOROOT=`pwd` +#For each build step, you can set these to true to make it build +#or set it to anything else (or unset) to skip that step +build_mc_kernel=true +build_diffusive_tulane_kernel=true +build_reservoir_kernel=true +build_framework=true +build_routing=true +build_config=true +build_nwm=true +build_bmi=true + +if [ -z "$F90" ] +then + export F90="gfortran" + echo "using F90=${F90}" +fi +if [ -z "$CC" ] +then + export CC="gcc" + echo "using CC=${CC}" +fi + +#preserve old/default behavior of installing packages with -e +WITH_EDITABLE=true +if [ "$1" == 'no-e' ] +then +WITH_EDITABLE=false +fi + +#if you have custom static library paths, uncomment below and export them +export LIBRARY_PATH=/opt/local/lib/:$LIBRARY_PATH +#if you have custom dynamic library paths, uncomment below and export them +export LD_LIBRARY_PATHS=/opt/local/lib/:$LD_LIBRARY_PATHS +if [ -z "$NETCDF" ] +then + #export NETCDFINC=/usr/include/openmpi-x86_64/ + export NETCDFINC=/opt/local/include/ + # set alternative NETCDF variable include path, for example for WSL + # (Windows Subsystems for Linux). + # + # EXAMPLE USAGE: export NETCDFALTERNATIVE=$HOME/.conda/envs/py39/include/ + # (before ./compiler.sh) + if [ -n "$NETCDFALTERNATIVE" ] + then + echo "using alternative NETCDF inc ${NETCDFALTERNATIVE}" + export NETCDFINC=$NETCDFALTERNATIVE + fi +else + export NETCDFINC="${NETCDF}" +fi +echo "using NETCDFINC=${NETCDFINC}" + +if [[ "$build_mc_kernel" == true ]]; then + #building reach and resevoir kernel files .o + cd $REPOROOT/src/kernel/muskingum/ + make clean + make || exit + make install || exit +fi + +if [[ "$build_diffusive_tulane_kernel" == true ]]; then + #building reach and resevoir kernel files .o + cd $REPOROOT/src/kernel/diffusive/ + make clean + make diffusive.o + make pydiffusive.o + make chxsec_lookuptable.o + make pychxsec_lookuptable.o + make install || exit +fi + +if [[ "$build_reservoir_kernel" == true ]]; then + cd $REPOROOT/src/kernel/reservoir/ + make clean + #make NETCDFINC=`nc-config --includedir` || exit + #make binding_lp.a + #make install_lp || exit + make + make install_lp || exit + make install_rfc || exit + +fi + +if [[ "$build_framework" == true ]]; then + #creates troute package + cd $REPOROOT/src/troute-network + rm -rf build + + if [[ ${WITH_EDITABLE} == true ]]; then + pip install --no-build-isolation --config-setting='--build-option=--use-cython' --editable . --config-setting='editable_mode=compat' || exit + else + pip install --no-build-isolation --config-setting='--build-option=--use-cython' . || exit + fi +fi + +if [[ "$build_routing" == true ]]; then + #updates troute package with the execution script + cd $REPOROOT/src/troute-routing + rm -rf build + + if [[ ${WITH_EDITABLE} == true ]]; then + pip install --no-build-isolation --config-setting='--build-option=--use-cython' --editable . --config-setting='editable_mode=compat' || exit + else + pip install --no-build-isolation --config-setting='--build-option=--use-cython' . || exit + fi +fi + +if [[ "$build_config" == true ]]; then + #updates troute package with the execution script + cd $REPOROOT/src/troute-config + if [[ ${WITH_EDITABLE} == true ]]; then + pip install --editable . || exit + else + pip install . || exit + fi +fi + +if [[ "$build_nwm" == true ]]; then + #updates troute package with the execution script + cd $REPOROOT/src/troute-nwm + if [[ ${WITH_EDITABLE} == true ]]; then + pip install --editable . || exit + else + pip install . || exit + fi +fi + +if [[ "$build_bmi" == true ]]; then + cd $REPOROOT/src/troute-bmi + if [[ ${WITH_EDITABLE} == true ]]; then + pip install --editable . || exit + else + pip install . || exit + fi +fi From 8a49df0516aa368625df4280d82dfaef69ac5e44 Mon Sep 17 00:00:00 2001 From: ashleymedin Date: Wed, 5 Nov 2025 02:22:36 +0900 Subject: [PATCH 3/4] seems to need this --- src/troute-network/troute/HYFeaturesNetwork.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/troute-network/troute/HYFeaturesNetwork.py b/src/troute-network/troute/HYFeaturesNetwork.py index b3313a01a..ddfb70654 100644 --- a/src/troute-network/troute/HYFeaturesNetwork.py +++ b/src/troute-network/troute/HYFeaturesNetwork.py @@ -145,7 +145,8 @@ def read_layer(layer_name): if right_col != "nex_id": hydro = hydro.rename(columns={right_col: "nex_id"}) - nexus = nexus.merge(hydro[["nex_id", "hl_uri"]], left_on="id", right_on="nex_id", how="left") + if not nexus.empty: + nexus = nexus.merge(hydro[["nex_id", "hl_uri"]], left_on="id", right_on="nex_id", how="left") return flowpaths, lakes, network, nexus From c6d5683db5878af3a7058ad30b1cdacb26dc7dc7 Mon Sep 17 00:00:00 2001 From: ashleymedin Date: Tue, 18 Nov 2025 16:42:22 +0900 Subject: [PATCH 4/4] waterbody might not be present --- src/troute-network/troute/HYFeaturesNetwork.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/troute-network/troute/HYFeaturesNetwork.py b/src/troute-network/troute/HYFeaturesNetwork.py index ddfb70654..08937f4cf 100644 --- a/src/troute-network/troute/HYFeaturesNetwork.py +++ b/src/troute-network/troute/HYFeaturesNetwork.py @@ -657,7 +657,13 @@ def preprocess_waterbodies(self, lakes, nexus): self._duplicate_ids_df = pd.DataFrame() self._gl_climatology_df = pd.DataFrame() - self._dataframe = self.dataframe.drop("waterbody", axis=1).drop_duplicates() + # drop 'waterbody' if present; avoid KeyError when it's missing + if "waterbody" in self.dataframe.columns: + self._dataframe = self.dataframe.drop(columns=["waterbody"]).drop_duplicates() + else: + #import warnings + #warnings.warn("HYFeaturesNetwork: 'waterbody' column not present; skipping drop") + self._dataframe = self.dataframe.drop_duplicates() def preprocess_data_assimilation(self, network): if not network.empty: