Repository navigation
HH_Param_Multi_Layer() and MKZ_Param_Multi_Layer() cannot load a one-layer parameter file, including one written by save_txt() #86
Description
Found while reviewing #74. Pre-existing on main (b764057); #74 does not change the behavior.
Problem
A parameter file has one column per layer. For a one-layer file, np.genfromtxt() returns a 1D array, and extract_from_param_format() rejects anything that is not 2D. So HH_Param_Multi_Layer() and MKZ_Param_Multi_Layer() raise TypeError for a one-layer file, even one that save_txt() wrote. The same one-layer data loads fine as a 2D (n, 1) array.
PySeismoSoil/PySeismoSoil/class_parameters.py
Lines 611 to 617 in b764057
| if isinstance(filename_or_data, str): # file name | |
| self._filename = filename_or_data | |
| params = np.genfromtxt(filename_or_data, delimiter=sep) | |
| list_of_param_array = hlp.extract_from_param_format(params) | |
| list_of_param = [ | |
| hh.deserialize_array_to_params(_) for _ in list_of_param_array | |
| ] |
PySeismoSoil/PySeismoSoil/class_parameters.py
Lines 701 to 707 in b764057
| if isinstance(filename_or_data, str): # file name | |
| self._filename = filename_or_data | |
| params = np.genfromtxt(filename_or_data, delimiter=sep) | |
| list_of_param_array = hlp.extract_from_param_format(params) | |
| list_of_param = [ | |
| mkz.deserialize_array_to_params(_) for _ in list_of_param_array | |
| ] |
PySeismoSoil/PySeismoSoil/helper_generic.py
Lines 804 to 805 in b764057
| if not isinstance(params, np.ndarray) or params.ndim != NDIM_2D_ARRAY: | |
| raise TypeError('`params` needs to be a 2D numpy array.') |
import tempfile
import numpy as np
from PySeismoSoil.class_parameters import HH_Param_Multi_Layer, MKZ_Param_Multi_Layer
one_layer_HH = np.genfromtxt('tests/files/HH_X_FKSH14.txt')[:, :1] # shape (9, 1)
one_layer_H4 = np.genfromtxt('tests/files/H4_G_IWTH04.txt')[:, :1] # shape (4, 1)
with tempfile.TemporaryDirectory() as tmp_dir:
for param_class, array in [
(HH_Param_Multi_Layer, one_layer_HH),
(MKZ_Param_Multi_Layer, one_layer_H4),
]:
param = param_class(array) # loading the 2D array works
print(param.n_layer)
file_name = f'{tmp_dir}/params.txt'
param.save_txt(file_name)
print(np.genfromtxt(file_name).shape)
try:
param_class(file_name)
except TypeError as e:
print(f'TypeError: {e}')
# 1
# (9,)
# TypeError: `params` needs to be a 2D numpy array.
# 1
# (4,)
# TypeError: `params` needs to be a 2D numpy array.
# (expected: both files load back with n_layer == 1)Fix
- In the file-name branch of
HH_Param_Multi_Layer.__init__()andMKZ_Param_Multi_Layer.__init__(), read withnp.genfromtxt(filename_or_data, delimiter=sep, ndmin=2). For the one-layer file above this gives shape(9, 1), which loads withn_layer == 1; the five-layerHH_X_FKSH14.txtstill gives(9, 5). - Add a test that a one-layer
HH_Param_Multi_LayerandMKZ_Param_Multi_Layerround-trip throughsave_txt()and the file-name constructor.
Activity