From 51d04bdcd57cc3f6b10c96438e2324bccf886245 Mon Sep 17 00:00:00 2001 From: Brioch Date: Tue, 19 Aug 2025 17:27:04 +1200 Subject: [PATCH 1/3] Refactoring text exe messes + Modifying bin path behaviour in tests to resolve fall back path if exe not found on PATH --- autotest/conftest.py | 52 ++++++++- autotest/pst_from_tests.py | 197 +++++++-------------------------- autotest/utils_tests.py | 40 ++----- examples/pstfrom_mf6.ipynb | 63 +++++------ examples/pstfrom_mf6_ppu.ipynb | 2 +- pyemu/utils/os_utils.py | 11 +- 6 files changed, 134 insertions(+), 231 deletions(-) diff --git a/autotest/conftest.py b/autotest/conftest.py index 8a6cca34d..0e7114b73 100644 --- a/autotest/conftest.py +++ b/autotest/conftest.py @@ -1,5 +1,7 @@ from pathlib import Path import pytest +import shutil +import platform # from pst_from_tests import setup_freyberg_mf6 pytest_plugins = ["modflow_devtools.fixtures"] @@ -17,10 +19,56 @@ # "moouu_tests.py", # "mat_tests.py", # "da_tests.py", - # "get_pestpp_tests.py" + # "get_pestpp_tests.py", ] +def get_project_root_path(): + """ + Get the root path of the project. + """ + return Path(__file__).parent.parent + + +def get_exe_path(exe_name, forgive=True): + """ + Get the absolute path to an executable in the project. + """ + if shutil.which(exe_name) is not None: + return exe_name + root_path = get_project_root_path() + exe_path = root_path / "bin" + if not (exe_path / exe_name).exists(): + if "linux" in platform.system().lower(): + exe_path = Path(exe_path, "linux") + elif "darwin" in platform.system().lower(): + exe_path = Path(exe_path, "mac") + else: + exe_path = Path(exe_path, "win") + if not (exe_path / exe_name).exists(): + if forgive: + print(f"Executable {exe_name} not found in {exe_path}, returning None") + else: + raise FileNotFoundError(f"Executable {exe_name} not found in system PATH or fallback path:" + f" {exe_path}") + return None + return exe_path / exe_name + + +def full_exe_ref_dict(): + """ + Get a dictionary of executable references for the project. + """ + d = {} + for exe_name in [ + "mfnwt", "mt3dusgs", "mfusg_gsi", "mf6", + "pestpp-ies", "pestpp-sen", "pestpp-opt", "pestpp-glm", + "pestpp-mou", "pestpp-da", "pestpp-sqp", "pestpp-swp" + ]: + d[exe_name] = get_exe_path(exe_name) + return d + + @pytest.fixture(autouse=True) def _ch2testdir(monkeypatch): testdir = Path(__file__).parent - monkeypatch.chdir(testdir) \ No newline at end of file + monkeypatch.chdir(testdir) diff --git a/autotest/pst_from_tests.py b/autotest/pst_from_tests.py index dc916a9ba..751fc3e60 100644 --- a/autotest/pst_from_tests.py +++ b/autotest/pst_from_tests.py @@ -10,35 +10,14 @@ import shutil import pytest -ext = '' -local_bins = False # change if wanting to test with local binary exes -if local_bins: - bin_path = os.path.join("..", "..", "bin") - if "linux" in platform.system().lower(): - pass - bin_path = os.path.join(bin_path, "linux") - elif "darwin" in platform.system().lower(): - pass - bin_path = os.path.join(bin_path, "mac") - else: - bin_path = os.path.join(bin_path, "win") - ext = '.exe' -else: - bin_path = '' - if "windows" in platform.system().lower(): - ext = '.exe' - -mf_exe_path = os.path.join(bin_path, "mfnwt") -mt_exe_path = os.path.join(bin_path, "mt3dusgs") -usg_exe_path = os.path.join(bin_path, "mfusg_gsi") -mf6_exe_path = os.path.join(bin_path, "mf6") -pp_exe_path = os.path.join(bin_path, "pestpp-glm") -ies_exe_path = os.path.join(bin_path, "pestpp-ies") -swp_exe_path = os.path.join(bin_path, "pestpp-swp") - -mf_exe_name = os.path.basename(mf_exe_path) -mf6_exe_name = os.path.basename(mf6_exe_path) +from autotest.conftest import full_exe_ref_dict +exepath_dict = full_exe_ref_dict() +ies_exe_path = exepath_dict['pestpp-ies'] +mf_exe_path = exepath_dict['mfnwt'] +mf6_exe_path = exepath_dict['mf6'] +pp_exe_path = exepath_dict['pestpp-glm'] +usg_exe_path = exepath_dict["mfusg_gsi"] def _get_port(): import socket @@ -92,104 +71,8 @@ def setup_tmp(od, tmp_d, sub=None): shutil.copytree(od, new_d) return new_d -# @pytest.fixture -# def freybergmf6_2_pstfrom(tmp_path): -# import numpy as np -# import pandas as pd -# pd.set_option('display.max_rows', 500) -# pd.set_option('display.max_columns', 500) -# pd.set_option('display.width', 1000) -# try: -# import flopy -# except: -# return -# -# org_model_ws = os.path.join('..', 'examples', 'freyberg_mf6') -# tmp_model_ws = setup_tmp(org_model_ws, tmp_path) -# bd = Path.cwd() -# os.chdir(tmp_path) -# try: -# tmp_model_ws = tmp_model_ws.relative_to(tmp_path) -# sim = flopy.mf6.MFSimulation.load(sim_ws=str(tmp_model_ws)) -# m = sim.get_model() -# sim.set_all_data_external(check_data=False) -# sim.write_simulation() -# -# # SETUP pest stuff... -# os_utils.run("{0} ".format(mf6_exe_path), cwd=tmp_model_ws) -# template_ws = "new_temp" -# if os.path.exists(template_ws): -# shutil.rmtree(template_ws) -# # sr0 = m.sr -# # sr = pyemu.helpers.SpatialReference.from_namfile( -# # os.path.join(tmp_model_ws, "freyberg6.nam"), -# # delr=m.dis.delr.array, delc=m.dis.delc.array) -# sr = m.modelgrid -# # set up PstFrom object -# pf = PstFrom(original_d=tmp_model_ws, new_d=template_ws, -# remove_existing=True, -# longnames=True, spatial_reference=sr, -# zero_based=False, start_datetime="1-1-2018", -# chunk_len=1) -# yield pf -# except Exception as e: -# os.chdir(bd) -# raise e -# os.chdir(bd) - - -# @pytest.fixture -# def freybergnwt_2_pstfrom(tmp_path): -# import numpy as np -# import pandas as pd -# pd.set_option('display.max_rows', 500) -# pd.set_option('display.max_columns', 500) -# pd.set_option('display.width', 1000) -# try: -# import flopy -# except: -# return -# -# org_model_ws = os.path.join('..', 'examples', 'freyberg_sfr_reaches') -# tmp_model_ws = setup_tmp(org_model_ws, tmp_path) -# bd = Path.cwd() -# os.chdir(tmp_path) -# nam_file = "freyberg.nam" -# try: -# tmp_model_ws = tmp_model_ws.relative_to(tmp_path) -# m = flopy.modflow.Modflow.load(nam_file, model_ws=tmp_model_ws, -# check=False, forgive=False, -# exe_name=mf_exe_path) -# flopy.modflow.ModflowRiv(m, stress_period_data={ -# 0: [[0, 0, 0, m.dis.top.array[0, 0], 1.0, m.dis.botm.array[0, 0, 0]], -# [0, 0, 1, m.dis.top.array[0, 1], 1.0, m.dis.botm.array[0, 0, 1]], -# [0, 0, 1, m.dis.top.array[0, 1], 1.0, m.dis.botm.array[0, 0, 1]]]}) -# -# m.external_path = "." -# m.write_input() -# runstr = ("{0} {1}".format(mf_exe_path, m.name + ".nam"), tmp_model_ws) -# print(runstr) -# os_utils.run(*runstr) -# template_ws = "template" -# if os.path.exists(template_ws): -# shutil.rmtree(template_ws) -# sr = pyemu.helpers.SpatialReference.from_namfile( -# os.path.join(m.model_ws, m.namefile), -# delr=m.dis.delr, delc=m.dis.delc) -# # set up PstFrom object -# pf = PstFrom(original_d=tmp_model_ws, new_d=template_ws, -# remove_existing=True, -# longnames=True, spatial_reference=sr, -# zero_based=False, start_datetime="1-1-2018", -# chunk_len=1) -# yield pf -# except Exception as e: -# os.chdir(bd) -# raise e -# os.chdir(bd) - - -def freyberg_test(tmp_path): + +def test_freyberg(tmp_path): import numpy as np import pandas as pd from pyemu import PyemuWarning @@ -383,7 +266,7 @@ def freyberg_test(tmp_path): # add model run command - pf.mod_sys_cmds.append("{0} {1}".format(mf_exe_name, m.name + ".nam")) + pf.mod_sys_cmds.append("{0} {1}".format(mf_exe_path, m.name + ".nam")) print(pf.mult_files) print(pf.org_files) @@ -608,7 +491,7 @@ def test_freyberg_prior_build(tmp_path): # add model run command - pf.mod_sys_cmds.append("{0} {1}".format(mf_exe_name, m.name + ".nam")) + pf.mod_sys_cmds.append("{0} {1}".format(mf_exe_path, m.name + ".nam")) print(pf.mult_files) print(pf.org_files) @@ -1086,7 +969,7 @@ def test_mf6_freyberg(tmp_path): geostruct=rch_temporal_gs) # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) # print(pf.mult_files) # print(pf.org_files) @@ -1298,7 +1181,7 @@ def mf6_freyberg_shortnames_test(tmp_path): assert len(pdf) == 4 # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) print(pf.mult_files) print(pf.org_files) @@ -1414,7 +1297,7 @@ def mf6_freyberg_da_test(tmp_path): m = sim.get_model("freyberg6") # SETUP pest stuff... - os_utils.run("{0} ".format("mf6"), cwd=tmp_model_ws) + os_utils.run("{0} ".format(mf6_exe_path), cwd=tmp_model_ws) template_ws = "new_temp_da" if os.path.exists(template_ws): @@ -1485,7 +1368,7 @@ def mf6_freyberg_da_test(tmp_path): par_type="grid") # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) # print(pf.mult_files) # print(pf.org_files) @@ -1585,7 +1468,7 @@ def setup_freyberg_mf6(wd, model="freyberg_mf6", **kwargs): sim.write_simulation() # SETUP pest stuff... - os_utils.run("{0} ".format("mf6"), cwd=tmp_model_ws) + os_utils.run("{0} ".format(mf6_exe_path), cwd=tmp_model_ws) template_ws = Path(wd, "template") if os.path.exists(template_ws): @@ -1613,7 +1496,7 @@ def setup_freyberg_mf6(wd, model="freyberg_mf6", **kwargs): def build_direct(pf): - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) print(pf.mult_files) print(pf.org_files) @@ -2071,7 +1954,7 @@ def mf6_freyberg_direct_test(tmp_path): sim.write_simulation() # SETUP pest stuff... - os_utils.run("{0} ".format("mf6"), cwd=tmp_model_ws) + os_utils.run("{0} ".format(mf6_exe_path), cwd=tmp_model_ws) template_ws = Path(tmp_path, "new_temp_direct") if os.path.exists(template_ws): @@ -2249,7 +2132,7 @@ def mf6_freyberg_direct_test(tmp_path): use_rows=[('well2', 21, 15), ('well4', 30, 7)]) assert len(pf.par_dfs[-1]) == 2 * 2 # should be # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) print(pf.mult_files) print(pf.org_files) @@ -2497,7 +2380,7 @@ def mf6_freyberg_varying_idomain(tmp_path): geostruct=gr_gs, zone_array=ib[k],ult_lbound=ult_lb,ult_ubound=ult_ub) # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) df = pd.read_csv(os.path.join(tmp_model_ws, "heads.csv"), index_col=0) df = pf.add_observations("heads.csv", insfile="heads.csv.ins", index_cols="time", use_cols=list(df.columns.values), prefix="hds", ofile_sep=",") @@ -2617,7 +2500,7 @@ def mf6_freyberg_short_direct_test(tmp_path): sim.write_simulation() # SETUP pest stuff... - os_utils.run("{0} ".format("mf6"), cwd=tmp_model_ws) + os_utils.run("{0} ".format(mf6_exe_path), cwd=tmp_model_ws) template_ws = "new_temp_direct" if os.path.exists(template_ws): @@ -2759,7 +2642,7 @@ def mf6_freyberg_short_direct_test(tmp_path): transform="none") # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) print(pf.mult_files) print(pf.org_files) @@ -3595,7 +3478,7 @@ def mf6_freyberg_arr_obs_and_headerless_test(tmp_path): arr_dict[arr_file] = np.loadtxt(pf.new_d / arr_file) # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) print(pf.mult_files) print(pf.org_files) @@ -3642,7 +3525,7 @@ def mf6_freyberg_arr_obs_and_headerless_test(tmp_path): assert d.sum() == 0 -def mf6_freyberg_pp_locs_test(tmp_path): +def test_mf6_freyberg_pp_locs(tmp_path): import numpy as np import pandas as pd pd.set_option('display.max_rows', 500) @@ -3747,7 +3630,7 @@ def mf6_freyberg_pp_locs_test(tmp_path): # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) print(pf.mult_files) print(pf.org_files) @@ -4037,7 +3920,7 @@ def mf6_add_various_obs_test(tmp_path): pf.add_parameters(["freyberg6.npf_k_layer1.txt", "freyberg6.npf_k_layer2.txt", "freyberg6.npf_k_layer3.txt"],par_type='constant') - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) pf.add_py_function( __file__, f"_add_big_obsffile('.', profile=False, nchar={linelen})", @@ -4102,11 +3985,7 @@ def mf6_subdir_test(tmp_path): sim.write_simulation() # SETUP pest stuff... - if bin_path == '': - exe = mf6_exe_path # bit of flexibility for local/server run - else: - exe = os.path.join('..', mf6_exe_path) - os_utils.run("{0} ".format(exe), cwd=tmp2_ws) + os_utils.run("{0} ".format(mf6_exe_path), cwd=tmp2_ws) # call generic once so that the output file exists df = generic_function(tmp2_ws) template_ws = "new_temp" @@ -4271,7 +4150,7 @@ def mf6_subdir_test(tmp_path): # # # add model run command pf.pre_py_cmds.append(f"os.chdir('{sd}')") - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) pf.post_py_cmds.insert(0, "os.chdir('..')") # print(pf.mult_files) # print(pf.org_files) @@ -4584,7 +4463,7 @@ def test_vertex_grid(tmp_path): a = [float(i) for i in a.split()] np.savetxt(fname=filename, X=a) # run model after input file change - pyemu.os_utils.run('mf6', cwd=template_ws) + pyemu.os_utils.run(mf6_exe_path, cwd=template_ws) for f in files: layer = int(f.split('_layer')[-1].split('.')[0]) - 1 @@ -4635,7 +4514,7 @@ def test_vertex_grid(tmp_path): index_cols="time", use_cols=list(df.columns.values), prefix="sfr") - pf.mod_sys_cmds.append('mf6') + pf.mod_sys_cmds.append(mf6_exe_path) pst = pf.build_pst() # check_apply(pf) # run once @@ -4837,7 +4716,7 @@ def mf6_freyberg_thresh_test(tmp_path): # SETUP pest stuff... - os_utils.run("{0} ".format("mf6"), cwd=tmp_model_ws) + os_utils.run("{0} ".format(mf6_exe_path), cwd=tmp_model_ws) template_ws = Path(tmp_path, "new_temp_thresh") if os.path.exists(template_ws): @@ -4944,7 +4823,7 @@ def mf6_freyberg_thresh_test(tmp_path): num_cat_arrays += 1 # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) # print(pf.mult_files) # print(pf.org_files) @@ -5707,7 +5586,7 @@ def mf6_freyberg_ppu_hyperpars_invest(tmp_path): # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) print(pf.mult_files) print(pf.org_files) @@ -5806,7 +5685,7 @@ def mf6_freyberg_ppu_hyperpars_thresh_invest(tmp_path): sim.write_simulation() # SETUP pest stuff... - os_utils.run("{0} ".format("mf6"), cwd=tmp_model_ws) + os_utils.run("{0} ".format(mf6_exe_path), cwd=tmp_model_ws) template_ws = Path(tmp_path, "new_temp_thresh") if os.path.exists(template_ws): @@ -5961,7 +5840,7 @@ def mf6_freyberg_ppu_hyperpars_thresh_invest(tmp_path): num_cat_arrays += 1 # add model run command - pf.mod_sys_cmds.append("mf6") + pf.mod_sys_cmds.append(mf6_exe_path) print(pf.mult_files) print(pf.org_files) @@ -6322,7 +6201,7 @@ def invest_vertexpp_setup_speed(): from pathlib import Path from shapely import Polygon import cProfile - sim = flopy.mf6.MFSimulation(sim_name="test", sim_ws="test", exe_name="mf6") + sim = flopy.mf6.MFSimulation(sim_name="test", sim_ws="test", exe_name=mf6_exe_path) gwf = flopy.mf6.ModflowGwf(sim, modelname="test") dis = flopy.mf6.ModflowGwfdis( @@ -6418,7 +6297,7 @@ def xsec_pars_as_obs_test(tmp_path): if __name__ == "__main__": - xsec_pars_as_obs_test(".") + # xsec_pars_as_obs_test(".") #add_py_function_test('.') #mf6_freyberg_pp_locs_test('.') #mf6_subdir_test(".") @@ -6433,7 +6312,7 @@ def xsec_pars_as_obs_test(tmp_path): # invest() # test_add_array_parameters_pps_grid() - #freyberg_test(os.path.abspath(".")) + test_freyberg(os.path.abspath(".")) # freyberg_prior_build_test() #mf6_freyberg_test(os.path.abspath(".")) #$mf6_freyberg_da_test() diff --git a/autotest/utils_tests.py b/autotest/utils_tests.py index 4391c0e7c..2939c1991 100644 --- a/autotest/utils_tests.py +++ b/autotest/utils_tests.py @@ -11,37 +11,15 @@ import pyemu from pst_from_tests import _get_port -ext = '' -local_bins = False # change if wanting to test with local binary exes -if local_bins: - bin_path = os.path.join("..", "..", "bin") - if "linux" in platform.system().lower(): - pass - bin_path = os.path.join(bin_path, "linux") - elif "darwin" in platform.system().lower(): - pass - bin_path = os.path.join(bin_path, "mac") - else: - bin_path = os.path.join(bin_path, "win") - ext = '.exe' -else: - bin_path = '' - if "windows" in platform.system().lower(): - ext = '.exe' - -mf_exe_path = os.path.join(bin_path, "mfnwt") -mt_exe_path = os.path.join(bin_path, "mt3dusgs") -usg_exe_path = os.path.join(bin_path, "mfusg_gsi") -mf6_exe_path = os.path.join(bin_path, "mf6") -pp_exe_path = os.path.join(bin_path, "pestpp-glm") -ies_exe_path = os.path.join(bin_path, "pestpp-ies") -mou_exe_path = os.path.join(bin_path, "pestpp-mou") -swp_exe_path = os.path.join(bin_path, "pestpp-swp") - -mf_exe_name = os.path.basename(mf_exe_path) -mf6_exe_name = os.path.basename(mf6_exe_path) - - +from autotest.conftest import full_exe_ref_dict + +exepath_dict = full_exe_ref_dict() +ies_exe_path = exepath_dict['pestpp-ies'] +mf_exe_path = exepath_dict['mfnwt'] +mf6_exe_path = exepath_dict['mf6'] +pp_exe_path = exepath_dict['pestpp-glm'] +usg_exe_path = exepath_dict["mfusg_gsi"] +mou_exe_path = exepath_dict["pestpp-mou"] def add_pi_obj_func_test(tmp_path): import os diff --git a/examples/pstfrom_mf6.ipynb b/examples/pstfrom_mf6.ipynb index c043ce20c..c2e21f67a 100644 --- a/examples/pstfrom_mf6.ipynb +++ b/examples/pstfrom_mf6.ipynb @@ -911,10 +911,10 @@ ] }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "cell_type": "code", "outputs": [], + "execution_count": null, "source": [ "# load the mf6 model with flopy to get the spatial reference\n", "sim = flopy.mf6.MFSimulation.load(sim_ws=tmp_model_ws)\n", @@ -935,13 +935,13 @@ "\n", "# add observations from the sfr observation output file\n", "df = pd.read_csv(os.path.join(tmp_model_ws, \"sfr.csv\"), index_col=0)\n", - "pf.add_observations(\"sfr.csv\", insfile=\"sfr.csv.ins\", index_cols=\"time\", \n", + "pf.add_observations(\"sfr.csv\", insfile=\"sfr.csv.ins\", index_cols=\"time\",\n", " use_cols=list(df.columns.values),\n", " prefix=\"sfr\")\n", "\n", "# add observations for the heads observation output file\n", "df = pd.read_csv(os.path.join(tmp_model_ws, \"heads.csv\"), index_col=0)\n", - "pf.add_observations(\"heads.csv\", insfile=\"heads.csv.ins\", \n", + "pf.add_observations(\"heads.csv\", insfile=\"heads.csv.ins\",\n", " index_cols=\"time\", use_cols=list(df.columns.values),\n", " prefix=\"hds\")\n", "\n", @@ -977,28 +977,28 @@ "for tag,bnd in tags.items():\n", " lb,ub = bnd[0],bnd[1]\n", " # find all array based files that have the tag in the name\n", - " arr_files = [f for f in os.listdir(template_ws) if tag in f \n", + " arr_files = [f for f in os.listdir(template_ws) if tag in f\n", "\t\t\t\t and f.endswith(\".txt\")]\n", "\n", " if len(arr_files) == 0:\n", " print(\"warning: no array files found for \",tag)\n", " continue\n", - " \n", + "\n", " # make sure each array file in nrow X ncol dimensions (not wrapped, sigh)\n", " for arr_file in arr_files:\n", " arr = np.loadtxt(os.path.join(template_ws,arr_file)).reshape(ib.shape)\n", " np.savetxt(os.path.join(template_ws,arr_file),arr,fmt=\"%15.6E\")\n", - " \n", + "\n", " # if this is the recharge tag\n", " if \"rch\" in tag:\n", " # add one set of grid-scale parameters for all files\n", - " pf.add_parameters(filenames=arr_files, par_type=\"grid\", \n", - " \t\t\t\t par_name_base=\"rch_gr\",pargp=\"rch_gr\", \n", - " \t\t\t\t zone_array=ib, upper_bound=ub, \n", + " pf.add_parameters(filenames=arr_files, par_type=\"grid\",\n", + " \t\t\t\t par_name_base=\"rch_gr\",pargp=\"rch_gr\",\n", + " \t\t\t\t zone_array=ib, upper_bound=ub,\n", " \t\t\t\t lower_bound=lb,geostruct=rch_gs)\n", "\n", - " # add one constant parameter for each array, and \n", - " # assign it a datetime so we can work out the \n", + " # add one constant parameter for each array, and\n", + " # assign it a datetime so we can work out the\n", " # temporal correlation\n", " for arr_file in arr_files:\n", " kper = int(arr_file.split('.')[1].split('_')[-1]) - 1\n", @@ -1016,40 +1016,40 @@ " pargp=arr_file.split('.')[1]+\"_gr\",zone_array=ib,\n", " upper_bound=ub,lower_bound=lb,\n", " geostruct=grid_gs)\n", - " pf.add_parameters(filenames=arr_file, par_type=\"pilotpoints\", \n", + " pf.add_parameters(filenames=arr_file, par_type=\"pilotpoints\",\n", " par_name_base=arr_file.split('.')[1]+\"_pp\",\n", - " pargp=arr_file.split('.')[1]+\"_pp\", \n", + " pargp=arr_file.split('.')[1]+\"_pp\",\n", " zone_array=ib,upper_bound=ub,lower_bound=lb,\n", " pp_space=int(5 * redis_fac),geostruct=pp_gs)\n", "\n", "\n", "# get all the list-type files associated with the wel package\n", - "list_files = [f for f in os.listdir(tmp_model_ws) if \n", - "\t\t\t \"freyberg6.wel_stress_period_data_\" \n", + "list_files = [f for f in os.listdir(tmp_model_ws) if\n", + "\t\t\t \"freyberg6.wel_stress_period_data_\"\n", " in f and f.endswith(\".txt\")]\n", - "# for each wel-package list-type file \n", + "# for each wel-package list-type file\n", "for list_file in list_files:\n", " kper = int(list_file.split(\".\")[1].split('_')[-1]) - 1\n", " # add spatially constant, but temporally correlated parameter\n", " pf.add_parameters(filenames=list_file,par_type=\"constant\",\n", " \t\t\t\t par_name_base=\"twel_mlt_{0}\".format(kper),\n", " pargp=\"twel_mlt\".format(kper),index_cols=[0,1,2],\n", - " use_cols=[3],upper_bound=1.5,lower_bound=0.5, \n", + " use_cols=[3],upper_bound=1.5,lower_bound=0.5,\n", " datetime=dts[kper], geostruct=temporal_gs)\n", "\n", - " # add temporally indep, but spatially correlated grid-scale \n", + " # add temporally indep, but spatially correlated grid-scale\n", " # parameters, one per well\n", - " pf.add_parameters(filenames=list_file, par_type=\"grid\", \n", + " pf.add_parameters(filenames=list_file, par_type=\"grid\",\n", " par_name_base=\"wel_grid_{0}\".format(kper),\n", - " pargp=\"wel_{0}\".format(kper), index_cols=[0, 1, 2], \n", + " pargp=\"wel_{0}\".format(kper), index_cols=[0, 1, 2],\n", " use_cols=[3],upper_bound=1.5, lower_bound=0.5)\n", "\n", - "# add grid-scale parameters for SFR reach conductance. \n", - "# Use layer, row, col and reach number in the \n", + "# add grid-scale parameters for SFR reach conductance.\n", + "# Use layer, row, col and reach number in the\n", "# parameter names\n", - "pf.add_parameters(filenames=\"freyberg6.sfr_packagedata.txt\", \n", + "pf.add_parameters(filenames=\"freyberg6.sfr_packagedata.txt\",\n", " par_name_base=\"sfr_rhk\",\n", - " pargp=\"sfr_rhk\", index_cols=[0,1,2,3], \n", + " pargp=\"sfr_rhk\", index_cols=[0,1,2,3],\n", " use_cols=[9], upper_bound=10.,\n", " lower_bound=0.1,\n", " par_type=\"grid\")\n", @@ -1092,18 +1092,11 @@ ] }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, - "outputs": [], - "source": [] - }, - { "cell_type": "code", - "execution_count": null, - "metadata": {}, "outputs": [], - "source": [] + "execution_count": null, + "source": "" } ], "metadata": { @@ -1122,7 +1115,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.13.5" } }, "nbformat": 4, diff --git a/examples/pstfrom_mf6_ppu.ipynb b/examples/pstfrom_mf6_ppu.ipynb index 9283543d9..df5d5d4a9 100644 --- a/examples/pstfrom_mf6_ppu.ipynb +++ b/examples/pstfrom_mf6_ppu.ipynb @@ -815,7 +815,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.12" + "version": "3.13.5" } }, "nbformat": 4, diff --git a/pyemu/utils/os_utils.py b/pyemu/utils/os_utils.py index 9015f2893..3fada04ee 100644 --- a/pyemu/utils/os_utils.py +++ b/pyemu/utils/os_utils.py @@ -140,7 +140,9 @@ def run_ossystem(cmd_str, cwd=".", verbose=False): exe_name = exe_name.replace(".exe", "") raw[0] = exe_name cmd_str = "{0} {1} ".format(*raw) - if os.path.exists(exe_name) and not exe_name.startswith("./"): + if (os.path.exists(exe_name) + and not exe_name.startswith("./") + and not exe_name.startswith("/")): cmd_str = "./" + cmd_str except Exception as e: @@ -192,8 +194,11 @@ def run_sp(cmd_str, cwd=".", verbose=True, logfile=False, **kwargs): bwd = os.getcwd() os.chdir(cwd) - - if platform.system() != "Windows" and not shutil.which(cmd_str.split()[0]): + exe_name = cmd_str.split()[0] + if (platform.system() != "Windows" + and not shutil.which(exe_name) + and not exe_name.startswith("./") + and not exe_name.startswith("/")): cmd_str = "./" + cmd_str try: From 1fd8939baeace99ba30ef05a95d9cee0033252a9 Mon Sep 17 00:00:00 2001 From: Brioch Date: Tue, 7 Oct 2025 09:55:07 +0100 Subject: [PATCH 2/3] autotest import not req. --- autotest/pst_from_tests.py | 2 +- autotest/utils_tests.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/autotest/pst_from_tests.py b/autotest/pst_from_tests.py index 0d6714401..091f9009e 100644 --- a/autotest/pst_from_tests.py +++ b/autotest/pst_from_tests.py @@ -10,7 +10,7 @@ import shutil import pytest -from autotest.conftest import full_exe_ref_dict +from conftest import full_exe_ref_dict exepath_dict = full_exe_ref_dict() ies_exe_path = exepath_dict['pestpp-ies'] diff --git a/autotest/utils_tests.py b/autotest/utils_tests.py index a5bc8339d..14d4528e4 100644 --- a/autotest/utils_tests.py +++ b/autotest/utils_tests.py @@ -11,7 +11,7 @@ import pyemu from pst_from_tests import _get_port -from autotest.conftest import full_exe_ref_dict +from conftest import full_exe_ref_dict exepath_dict = full_exe_ref_dict() ies_exe_path = exepath_dict['pestpp-ies'] From 21821a5171ba2bd38f7521312069fdd7b3df1a9a Mon Sep 17 00:00:00 2001 From: Brioch Date: Tue, 7 Oct 2025 10:20:09 +0100 Subject: [PATCH 3/3] more cleaning --- autotest/emulator_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autotest/emulator_tests.py b/autotest/emulator_tests.py index 1aa11817d..36bc4e912 100644 --- a/autotest/emulator_tests.py +++ b/autotest/emulator_tests.py @@ -6,11 +6,11 @@ import pandas as pd import platform import pyemu -from pst_from_tests import setup_tmp, bin_path, _get_port +from pst_from_tests import setup_tmp, _get_port, exepath_dict from pyemu.emulators import DSI, LPFA, GPR -ies_exe_path = os.path.join(bin_path, "pestpp-ies") -mou_exe_path = os.path.join(bin_path, "pestpp-mou") +ies_exe_path = exepath_dict["pestpp-ies"] +mou_exe_path = exepath_dict["pestpp-mou"] def dsi_freyberg(tmp_d,transforms=None,tag=""):