From b29b2defd6f0255195b0de3d1ad83fecc77057c5 Mon Sep 17 00:00:00 2001 From: rhugman Date: Mon, 20 Oct 2025 15:49:27 +0100 Subject: [PATCH 1/5] minor fixes to assert messages and pputils shape handling for single layer disv SRefs --- pyemu/utils/pp_utils.py | 6 +++++- pyemu/utils/pst_from.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pyemu/utils/pp_utils.py b/pyemu/utils/pp_utils.py index eaefc9bb..e9593e62 100644 --- a/pyemu/utils/pp_utils.py +++ b/pyemu/utils/pp_utils.py @@ -783,6 +783,10 @@ def prep_pp_hyperpars(file_tag,pp_filename,pp_info,out_filename,grid_dict, aniso_filename = file_tag + ".aniso.dat" zone_filename = file_tag + ".zone.dat" + if len(arr_shape) == 1 and type(arr_shape) is tuple: + arr_shape = (1,arr_shape[0]) + + nodes = list(grid_dict.keys()) nodes.sort() with open(os.path.join(ws,gridinfo_filename), 'w') as f: @@ -798,7 +802,7 @@ def prep_pp_hyperpars(file_tag,pp_filename,pp_info,out_filename,grid_dict, np.savetxt(os.path.join(ws,aniso_filename), aniso, fmt="%20.8E") if zone_array is None: - zone_array = np.ones(shape,dtype=int) + zone_array = np.ones(arr_shape,dtype=int) np.savetxt(os.path.join(ws,zone_filename),zone_array,fmt="%5d") diff --git a/pyemu/utils/pst_from.py b/pyemu/utils/pst_from.py index 5a921489..507fa4b4 100644 --- a/pyemu/utils/pst_from.py +++ b/pyemu/utils/pst_from.py @@ -2452,7 +2452,7 @@ def add_parameters( orgdata = ar.shape for i, chk in checkref.items(): assert orgdata[i] == chk[1], ( - f"Spatial reference {chk[0]} not equal to original data {chk[0]} for\n" + f"Spatial reference {chk[1]} not equal to original data {orgdata[i]} for\n" + os.path.join( *os.path.split(self.original_file_d)[1:], mod_file ) From 2e827908aee87bdd1afca35a9dd456b53cbcdad7 Mon Sep 17 00:00:00 2001 From: rhugman Date: Wed, 22 Oct 2025 11:52:57 +0100 Subject: [PATCH 2/5] handle flopy default shape for zone array with single layer model --- pyemu/utils/pst_from.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyemu/utils/pst_from.py b/pyemu/utils/pst_from.py index 507fa4b4..303a5189 100644 --- a/pyemu/utils/pst_from.py +++ b/pyemu/utils/pst_from.py @@ -2120,6 +2120,10 @@ def add_parameters( ) if checker: zone_array = np.reshape(zone_array, (zone_array.shape[0], 1)) + # when accesing ib for a 1layer model, the returned array has shape (1,ncpl) + elif len(zone_array.shape) == 2 and zone_array.shape[0] == 1 and zone_array.shape[1] > 1: + zone_array = np.reshape(zone_array, (zone_array.shape[1], 1)) + # Get useful variables from arguments passed # if index_cols passed as a dictionary that maps i,j information From 23c71887a0eb2cab9281646c8292c98a7d9c73d4 Mon Sep 17 00:00:00 2001 From: rhugman Date: Wed, 22 Oct 2025 11:56:44 +0100 Subject: [PATCH 3/5] update pstfrom disv test to use ppu and hyperpars --- autotest/pst_from_tests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/autotest/pst_from_tests.py b/autotest/pst_from_tests.py index 7d60e608..1a2095ba 100644 --- a/autotest/pst_from_tests.py +++ b/autotest/pst_from_tests.py @@ -4609,7 +4609,9 @@ def test_vertex_grid(tmp_path): pargp=f.split('.')[1].replace("_","")+"pp", lower_bound=0.2,upper_bound=5.0, ult_ubound=100, ult_lbound=0.01, - pp_space=500) # ` + pp_options={"prep_hyperpars":True, + "pp_space":500, + "try_use_ppu":True}) # ` tag = "sfr_packagedata" files = [f for f in os.listdir(template_ws) if tag in f.lower() and f.endswith(".txt")] From 2c04aad8bddb18c4a0121ec1ae598b983ae2144a Mon Sep 17 00:00:00 2001 From: rhugman Date: Wed, 22 Oct 2025 12:03:16 +0100 Subject: [PATCH 4/5] added checker to avoid None type zone array --- pyemu/utils/pst_from.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pyemu/utils/pst_from.py b/pyemu/utils/pst_from.py index 303a5189..ed07b512 100644 --- a/pyemu/utils/pst_from.py +++ b/pyemu/utils/pst_from.py @@ -2118,10 +2118,19 @@ def add_parameters( and zone_array is not None and len(zone_array.shape) == 1 ) + checker2 = ( + self._spatial_reference is not None + and not isinstance(self._spatial_reference, dict) + and self._spatial_reference.grid_type == 'vertex' + and zone_array is not None + and len(zone_array.shape) == 2 + and zone_array.shape[0] == 1 + and zone_array.shape[1] > 1 + ) if checker: zone_array = np.reshape(zone_array, (zone_array.shape[0], 1)) # when accesing ib for a 1layer model, the returned array has shape (1,ncpl) - elif len(zone_array.shape) == 2 and zone_array.shape[0] == 1 and zone_array.shape[1] > 1: + if checker2: zone_array = np.reshape(zone_array, (zone_array.shape[1], 1)) From 3605fb582c1623a03f396d5065a2eafbab5ef4ea Mon Sep 17 00:00:00 2001 From: rhugman Date: Wed, 22 Oct 2025 14:29:18 +0100 Subject: [PATCH 5/5] fix to test_vertex_grid --- autotest/pst_from_tests.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/autotest/pst_from_tests.py b/autotest/pst_from_tests.py index 1a2095ba..6529937d 100644 --- a/autotest/pst_from_tests.py +++ b/autotest/pst_from_tests.py @@ -4603,15 +4603,16 @@ def test_vertex_grid(tmp_path): df_pp = pf.add_parameters(f, zone_array=ib[layer], par_type="pilotpoints", - use_pp_zones=True, + #use_pp_zones=True, geostruct=grid_gs, par_name_base=f.split('.')[1].replace("_","")+"pp", pargp=f.split('.')[1].replace("_","")+"pp", lower_bound=0.2,upper_bound=5.0, ult_ubound=100, ult_lbound=0.01, - pp_options={"prep_hyperpars":True, + pp_options={"prep_hyperpars":False, "pp_space":500, - "try_use_ppu":True}) # ` + "try_use_ppu":False, + "pp_zones":True}) # ` tag = "sfr_packagedata" files = [f for f in os.listdir(template_ws) if tag in f.lower() and f.endswith(".txt")] @@ -4683,9 +4684,14 @@ def test_vertex_grid(tmp_path): k = int(f.split('_layer')[-1].split('.')[0]) - 1 a = np.loadtxt(os.path.join(template_ws, f)) a_org = np.loadtxt(os.path.join(template_ws,'org', f)) + assert a.shape == a_org.shape, (a.shape, a_org.shape) + assert np.isclose(a, a_org).all(), a-a_org # weak check - for zone in npfpar.loc[npfpar.pname.str.contains(f'layer{k+1}')].zone.unique(): - assert np.isclose(abs((a/a_org)[ib[k]==int(zone)]-int(zone)).max(), 0) + zones = npfpar.loc[npfpar.pname.str.contains(f'layer{k+1}')].zone.unique() + # check all of zones are in ib[k] + assert set(zones).issubset(set(np.unique(ib[k]))), f"not all zones in ib for {f}" + for zone in zones: + assert np.isclose(abs((a/a_org)[ib[k]==int(zone)]-1).max(), 0), f"{f} zone {zone} failed check" return def test_defaults(tmp_path):