Skip to content

Commit 224432b

Browse files
authored
fix(UcnFile): Add check for modflow-6 GWT concentration file header type (#2718)
1 parent 26855e7 commit 224432b

2 files changed

Lines changed: 106 additions & 1 deletion

File tree

autotest/test_binaryfile.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,38 @@ def test_concentration_build_index(example_data_path):
198198
)
199199

200200

201+
def test_mf6_concentration_build_index(example_data_path):
202+
# test low-level BinaryLayerFile._build_index() method with UCN file
203+
pth = (
204+
example_data_path
205+
/ "mf6/create_tests/test_transport/expected_output/gwt_mst03.ucn"
206+
)
207+
with UcnFile(pth) as ucn:
208+
pass
209+
assert ucn.nrow == 1
210+
assert ucn.ncol == 1
211+
assert ucn.nlay == 1
212+
assert not hasattr(ucn, "ntrans")
213+
assert ucn.totalbytes == 1680
214+
assert len(ucn.recordarray) == 28
215+
assert type(ucn.recordarray) == np.ndarray
216+
assert ucn.recordarray.dtype == np.dtype(
217+
[
218+
("kstp", "i4"),
219+
("kper", "i4"),
220+
("pertim", "f8"),
221+
("totim", "f8"),
222+
("text", "S16"),
223+
("ncol", "i4"),
224+
("nrow", "i4"),
225+
("ilay", "i4"),
226+
]
227+
)
228+
229+
assert np.max(ucn.times) == 4.0
230+
assert ucn.kstpkper[-1] == (14, 2)
231+
232+
201233
def test_binaryfile_writeread(function_tmpdir, nwt_model_path):
202234
model = "Pr3_MFNWT_lower.nam"
203235
ml = flopy.modflow.Modflow.load(model, version="mfnwt", model_ws=nwt_model_path)

flopy/utils/binaryfile/__init__.py

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,78 @@ def get_headfile_precision(filename: Union[str, PathLike]):
296296
return result
297297

298298

299+
def get_concentration_file_type(filename: Union[str, PathLike], precision):
300+
"""
301+
Method to check header and determine if the concentration file is a MT3D like
302+
file or a MF6 GWT like concentration file
303+
304+
Parameters
305+
----------
306+
filename : str or PathLike
307+
Path of binary MODFLOW file to determine precision.
308+
precision : str
309+
double or single
310+
311+
Returns
312+
-------
313+
str
314+
Result will be ucn or head
315+
316+
"""
317+
f = open(filename, "rb")
318+
f.seek(0, 2)
319+
totalbytes = f.tell()
320+
f.seek(0, 0) # reset to beginning
321+
assert f.tell() == 0
322+
if totalbytes == 0:
323+
raise ValueError(f"datafile error: file is empty: {filename}")
324+
325+
floattype = "f4"
326+
if precision == "double":
327+
floattype = "f8"
328+
329+
# first try mt3d ucn
330+
vartype = [
331+
("ntrans", "i4"),
332+
("kstp", "i4"),
333+
("kper", "i4"),
334+
("totim", floattype),
335+
("text", "S16"),
336+
]
337+
hdr = binaryread(f, vartype)
338+
339+
try:
340+
s = hdr[0][4].decode()
341+
if not s.strip().lower().startswith("c"):
342+
success = False
343+
else:
344+
success = True
345+
result = "ucn"
346+
except ValueError:
347+
success = False
348+
349+
if not success:
350+
f.seek(0)
351+
vartype = [
352+
("kstp", "<i4"),
353+
("kper", "<i4"),
354+
("pertim", floattype),
355+
("totim", floattype),
356+
("text", "S16"),
357+
]
358+
hdr = binaryread(f, vartype)
359+
s = hdr[0][4].decode()
360+
if not s.strip().lower().startswith("c"):
361+
f.close()
362+
raise ValueError(
363+
f"Could not determine the header type of the concentration {filename}"
364+
)
365+
else:
366+
result = "head"
367+
368+
return result
369+
370+
299371
class BinaryLayerFile(LayerFile):
300372
"""
301373
The BinaryLayerFile class is a parent class from which concrete
@@ -699,7 +771,8 @@ def __init__(
699771
precision = get_headfile_precision(filename)
700772
if precision == "unknown":
701773
raise ValueError(f"Error. Precision could not be determined for {filename}")
702-
self.header_dtype = BinaryHeader.set_dtype(bintype="Ucn", precision=precision)
774+
bintype = get_concentration_file_type(filename, precision)
775+
self.header_dtype = BinaryHeader.set_dtype(bintype=bintype, precision=precision)
703776
super().__init__(filename, precision, verbose, **kwargs)
704777
return
705778

0 commit comments

Comments
 (0)