Skip to content

HH_Param_Multi_Layer() and MKZ_Param_Multi_Layer() cannot load a one-layer parameter file, including one written by save_txt() #86

Open

Description

@jsh9

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.

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
]

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
]

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

  1. In the file-name branch of HH_Param_Multi_Layer.__init__() and MKZ_Param_Multi_Layer.__init__(), read with np.genfromtxt(filename_or_data, delimiter=sep, ndmin=2). For the one-layer file above this gives shape (9, 1), which loads with n_layer == 1; the five-layer HH_X_FKSH14.txt still gives (9, 5).
  2. Add a test that a one-layer HH_Param_Multi_Layer and MKZ_Param_Multi_Layer round-trip through save_txt() and the file-name constructor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions