Skip to content

One-layer Vs profiles crash HH parameter and damping calibration with IndexError #119

Open

Description

@cursor

Found while reviewing #74. Pre-existing on main (b764057); #74 does not change this code.

Problem

A one-layer Vs profile is accepted by Vs_Profile() and by check_Vs_profile_format(), then crashes HH parameter and damping calibration with IndexError.

hh_param_from_profile(), hh_param_from_curves(), and Damping_Calibration.get_damping_curves() always drop the last row as the halfspace (vs_profile[:-1, ...]) and then index that slice with [-1]. With one layer the slice is empty.

  • One soil layer and no halfspace (n_layer == 1) is discarded, so there is nothing left to calibrate.
  • A single halfspace (n_layer == 0) has no soil layer. That should be a ValueError, not an IndexError.

A two-row profile (one soil layer plus a halfspace) works.

hlp.check_Vs_profile_format(vs_profile)
h = vs_profile[:-1, 0]
Vs = vs_profile[:-1, 1] # exclude the last layer (i.e., half space)
n_layer = len(Vs)
if Tmax is not None:
hlp.assert_array_length(Tmax, n_layer)
rho = _calc_rho(h, Vs)
Gmax = _calc_Gmax(Vs, rho)
sigma_v0 = _calc_vertical_stress(h, rho)

hlp.check_Vs_profile_format(vs_profile)
h = vs_profile[:-1, 0]
Vs = vs_profile[:-1, 1] # exclude the last layer (i.e., half space)
n_layer = len(Vs)
if vs_profile.shape[1] == hlp.NUM_COLUMNS_OF_FULL_VS_PROFILE:
mat = vs_profile[:-1, -1]
rho = vs_profile[:-1, 3]
else: # only 2 columns
mat = np.arange(1, n_layer + 1)
rho = _calc_rho(h, Vs)
if Tmax is not None:
hlp.assert_array_length(Tmax, n_layer)
Gmax = _calc_Gmax(Vs, rho)
sigma_v0 = _calc_vertical_stress(h, rho)

h = self.vs_profile.vs_profile[:-1, 0]
Vs = self.vs_profile.vs_profile[:-1, 1]
n_layer = len(Vs)
# there can only be 5 or 2 columns
n_columns = self.vs_profile.vs_profile.shape[1]
if n_columns == hlp.NUM_COLUMNS_OF_FULL_VS_PROFILE:
rho = self.vs_profile.vs_profile[:-1, 3]
else: # only 2 columns
rho = hhc._calc_rho(h, Vs) # noqa: SLF001
sigma_v0 = hhc._calc_vertical_stress(h, rho) # noqa: SLF001

if thk[-1] == 0: # if the last layer thickness is unknown

import numpy as np
from PySeismoSoil.class_Vs_profile import Vs_Profile
from PySeismoSoil.class_damping_calibration import Damping_Calibration
import PySeismoSoil.helper_hh_calibration as hhc

one_layer = np.array([[10.0, 200.0]])
prof = Vs_Profile(one_layer)
print(prof.n_layer)  # 1

Damping_Calibration(prof).get_damping_curves()
# IndexError in _calc_vertical_stress: h[-1] on an empty array
# (also a RuntimeWarning: Mean of empty slice)

hhc.hh_param_from_profile(one_layer, verbose=False)
# IndexError in thk2dep: thk[-1] on an empty array

hhc.hh_param_from_curves(one_layer, np.zeros((2, 4)), verbose=False)
# same IndexError in thk2dep

Fix

After the halfspace is removed, if no soil layer remains, raise ValueError naming that case. If the profile is a single soil layer (last thickness > 0), keep that layer instead of dropping it. thk2dep() and _calc_vertical_stress() should also reject an empty thickness array with ValueError rather than indexing [-1].

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