Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(str and repr): better repr and str output for transient data with multiple blocks (#2058) #2102

Merged
merged 3 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions flopy/mf6/data/mfdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,26 @@ def __init__(
self._cached_model_grid = None

def __repr__(self):
return repr(self._get_storage_obj())
if isinstance(self._data_storage, dict):
stor_size = len(self._data_storage)
else:
stor_size = 1
if stor_size <= 1:
return repr(self._get_storage_obj(first_record=True))
else:
rpr = repr(self._get_storage_obj(first_record=True))
return f"{rpr}...\nand {stor_size - 1} additional data blocks"

def __str__(self):
return str(self._get_storage_obj())
if isinstance(self._data_storage, dict):
stor_size = len(self._data_storage)
else:
stor_size = 1
if stor_size <= 1:
return str(self._get_storage_obj(first_record=True))
else:
st = str(self._get_storage_obj(first_record=True))
return f"{st}...\nand {stor_size - 1} additional data blocks"

@property
def path(self):
Expand Down Expand Up @@ -531,7 +547,7 @@ def _get_aux_var_name(self, aux_var_index):
# TODO: Verify that this works for multi-dimensional layering
return aux_var_names[0][aux_var_index[0] + 1]

def _get_storage_obj(self):
def _get_storage_obj(self, first_record=False):
return self._data_storage


Expand Down
8 changes: 6 additions & 2 deletions flopy/mf6/data/mfdataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@ def _new_storage(
data_path=self._path,
)

def _get_storage_obj(self):
def _get_storage_obj(self, first_record=False):
return self._data_storage

def _set_storage_obj(self, storage):
Expand Down Expand Up @@ -2020,7 +2020,11 @@ def _new_storage(
def _set_storage_obj(self, storage):
self._data_storage[self._current_key] = storage

def _get_storage_obj(self):
def _get_storage_obj(self, first_record=False):
if first_record and isinstance(self._data_storage, dict):
for value in self._data_storage.values():
return value
return None
if (
self._current_key is None
or self._current_key not in self._data_storage
Expand Down
8 changes: 6 additions & 2 deletions flopy/mf6/data/mfdatalist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,7 @@ def _new_storage(self, stress_period=0):
data_path=self._path,
)

def _get_storage_obj(self):
def _get_storage_obj(self, first_record=False):
return self._data_storage

def plot(
Expand Down Expand Up @@ -2046,7 +2046,11 @@ def update_record(self, record, key_index, key=0):
def _new_storage(self, stress_period=0):
return {}

def _get_storage_obj(self):
def _get_storage_obj(self, first_record=False):
if first_record and isinstance(self._data_storage, dict):
for value in self._data_storage.values():
return value
return None
if (
self._current_key is None
or self._current_key not in self._data_storage
Expand Down
99 changes: 76 additions & 23 deletions flopy/mf6/data/mfdataplist.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,55 @@ def __init__(self):
self.data_storage_type = None
self.modified = False

def __repr__(self):
return self.get_data_str(True)

def __str__(self):
return self.get_data_str(False)

def _get_header_str(self):
header_list = []
if self.data_storage_type == DataStorageType.external_file:
header_list.append(f"open/close {self.fname}")
else:
header_list.append("internal")
if self.iprn is not None:
header_list.append(f"iprn {self.iprn}")
if len(header_list) > 0:
return ", ".join(header_list)
else:
return ""

def get_data_str(self, formal):
data_str = ""
layer_str = ""
if self.data_storage_type == DataStorageType.internal_array:
if self.internal_data is not None:
header = self._get_header_str()
if formal:
data_str = "{}{}{{{}}}\n({})\n".format(
data_str,
layer_str,
header,
repr(self.internal_data),
)
else:
data_str = "{}{}{{{}}}\n({})\n".format(
data_str,
layer_str,
header,
str(self.internal_data),
)
elif self.data_storage_type == DataStorageType.external_file:
header = self._get_header_str()
data_str = "{}{}{{{}}}\n({})\n".format(
data_str,
layer_str,
header,
"External data not displayed",
)
return data_str

def get_record(self):
rec = {}
if self.internal_data is not None:
Expand Down Expand Up @@ -726,7 +775,7 @@ def set_data(self, data, autofill=False, check_data=True, append=False):
self._simulation_data.debug,
)

data_storage = self._get_storage()
data_storage = self._get_storage_obj()
if append:
# append data to existing dataframe
current_data = self._get_dataframe()
Expand All @@ -742,15 +791,15 @@ def set_data(self, data, autofill=False, check_data=True, append=False):

def has_modified_ext_data(self):
"""check to see if external data has been modified since last read"""
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
return (
data_storage.data_storage_type == DataStorageType.external_file
and data_storage.internal_data is not None
)

def binary_ext_data(self):
"""check for binary data"""
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
return data_storage.binary

def to_array(self, kper=0, mask=False):
Expand Down Expand Up @@ -792,7 +841,7 @@ def set_record(self, record, autofill=False, check_data=True):

"""
if isinstance(record, dict):
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
if "filename" in record:
data_storage.set_external(record["filename"])
if "binary" in record:
Expand Down Expand Up @@ -851,9 +900,9 @@ def append_data(self, data):
"""
try:
self._resync()
if self._get_storage() is None:
if self._get_storage_obj() is None:
self._data_storage = self._new_storage()
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
if (
data_storage.data_storage_type
== DataStorageType.internal_array
Expand Down Expand Up @@ -952,7 +1001,7 @@ def store_internal(
Verify data prior to storing

"""
storage = self._get_storage()
storage = self._get_storage_obj()
# check if data is already stored external
if (
storage is None
Expand Down Expand Up @@ -999,7 +1048,7 @@ def store_as_external_file(
"""
# only store data externally (do not subpackage info)
if self.structure.construct_package is None:
storage = self._get_storage()
storage = self._get_storage_obj()
# check if data is already stored external
if (
replace_existing_external
Expand Down Expand Up @@ -1030,7 +1079,7 @@ def store_as_external_file(

def external_file_name(self):
"""Returns external file name, or None if this is not external data."""
storage = self._get_storage()
storage = self._get_storage_obj()
if storage is None:
return None
if (
Expand Down Expand Up @@ -1191,15 +1240,15 @@ def _save_binary_data(self, fd_data_file, data):
fd_data_file,
self._model_or_sim.modeldiscrit,
)
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
data_storage.internal_data = None

def has_data(self, key=None):
"""Returns whether this MFList has any data associated with it."""
try:
if self._get_storage() is None:
if self._get_storage_obj() is None:
return False
return self._get_storage().has_data()
return self._get_storage_obj().has_data()
except Exception as ex:
type_, value_, traceback_ = sys.exc_info()
raise MFDataException(
Expand Down Expand Up @@ -1281,7 +1330,7 @@ def load(
next data line : str

"""
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
data_storage.modified = False
# parse first line to determine if this is internal or external data
datautil.PyListUtil.reset_delimiter_used()
Expand Down Expand Up @@ -1338,7 +1387,7 @@ def load(
def _new_storage(self):
return {"Data": PandasListStorage()}

def _get_storage(self):
def _get_storage_obj(self, first_record=False):
return self._data_storage["Data"]

def _get_id_fields(self, data_frame):
Expand Down Expand Up @@ -1484,7 +1533,7 @@ def _get_data(self):

def _get_dataframe(self):
"""get and return dataframe for this list data"""
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
if data_storage is None or data_storage.data_storage_type is None:
block_exists = self._block.header_exists(
self._current_key, self.path
Expand Down Expand Up @@ -1551,9 +1600,9 @@ def _get_record(self, data_frame=False):

"""
try:
if self._get_storage() is None:
if self._get_storage_obj() is None:
return None
record = self._get_storage().get_record()
record = self._get_storage_obj().get_record()
except Exception as ex:
type_, value_, traceback_ = sys.exc_info()
raise MFDataException(
Expand Down Expand Up @@ -1650,7 +1699,7 @@ def _write_file_entry(
-------
result of pandas to_csv call
"""
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
if data_storage is None:
return ""
if (
Expand Down Expand Up @@ -1751,7 +1800,7 @@ def _get_file_path(self):
file_path : file path to data

"""
data_storage = self._get_storage()
data_storage = self._get_storage_obj()
if data_storage.fname is None:
return None
if self._model_or_sim.type == "model":
Expand Down Expand Up @@ -1989,11 +2038,11 @@ def store_as_external_file(
self._cache_model_grid = True
for sp in self._data_storage.keys():
self._current_key = sp
storage = self._get_storage()
storage = self._get_storage_obj()
if storage.internal_size == 0:
storage.internal_data = self.get_dataframe(sp)
if storage.internal_size > 0 and (
self._get_storage().data_storage_type
self._get_storage_obj().data_storage_type
!= DataStorageType.external_file
or replace_existing_external
):
Expand Down Expand Up @@ -2027,7 +2076,7 @@ def store_internal(
for sp in self._data_storage.keys():
self._current_key = sp
if (
self._get_storage().data_storage_type
self._get_storage_obj().data_storage_type
== DataStorageType.external_file
):
super().store_internal(
Expand Down Expand Up @@ -2482,7 +2531,11 @@ def update_record(self, record, key_index, key=0):
def _new_storage(self):
return {}

def _get_storage(self):
def _get_storage_obj(self, first_record=False):
if first_record and isinstance(self._data_storage, dict):
for value in self._data_storage.values():
return value
return None
if (
self._current_key is None
or self._current_key not in self._data_storage
Expand Down
8 changes: 6 additions & 2 deletions flopy/mf6/data/mfdatascalar.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ def _new_storage(self, stress_period=0):
data_path=self._path,
)

def _get_storage_obj(self):
def _get_storage_obj(self, first_record=False):
return self._data_storage

def plot(self, filename_base=None, file_extension=None, **kwargs):
Expand Down Expand Up @@ -911,7 +911,11 @@ def load(
def _new_storage(self, stress_period=0):
return {}

def _get_storage_obj(self):
def _get_storage_obj(self, first_record=False):
if first_record and isinstance(self._data_storage, dict):
for value in self._data_storage.values():
return value
return None
if (
self._current_key is None
or self._current_key not in self._data_storage
Expand Down
16 changes: 16 additions & 0 deletions flopy/mf6/data/mfdatastorage.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,22 @@ def get_data_str(self, formal):
layer_str,
self._get_layer_header_str(index),
)
elif storage.data_storage_type == DataStorageType.external_file:
header = self._get_layer_header_str(index)
if self.layered:
data_str = "{}{}{{{}}}\n({})\n".format(
data_str,
layer_str,
header,
"External data not displayed",
)
else:
data_str = "{}{}{{{}}}\n({})\n".format(
data_str,
layer_str,
header,
"External data not displayed",
)
return data_str

def _get_layer_header_str(self, layer):
Expand Down
Loading