def sd_nzs(period, site_class, z_factor, r_factor, n_factor):
    """
    Returns the NZ sd_nzs value for a given Time and soil type

    :param period: float or array
    :param site_class: Either 'C', 'D' or 'E'
    output: sd_nzs: float or array
    """
    if period < 0:
        raise ValueError('Structural period is negative')
    elif site_class == 'C':
        if period == 0:
            c_h = 1.33 * period ** 2
        elif period < 0.1:
            c_h = (1.33 + 1.6 * (period / 0.1)) * period ** 2
        elif period < 0.3:
            c_h = 2.93 * period ** 2
        elif period < 1.5:
            c_h = 2.0 * (0.5 / period) ** 0.75 * period ** 2
        elif period < 3.0:
            c_h = 1.32 / period * period ** 2
        else:
            c_h = 3.96
    elif site_class == 'D':
        if period == 0:
            c_h = 1.12 * period ** 2
        elif period < 0.1:
            c_h = (1.12 + 1.88 * (period / 0.1)) * period ** 2
        elif period < 0.56:
            c_h = 3.0 * period ** 2
        elif period < 1.5:
            c_h = 2.4 * (0.75 / period) ** 0.75 * period ** 2
        elif period < 3.0:
            c_h = 2.14 / period * period ** 2
        else:
            c_h = 6.42
    elif site_class == 'E':
        if period == 0:
            c_h = 1.12 * period ** 2
        elif period < 0.1:
            c_h = (1.12 + 1.88 * (period / 0.1)) * period ** 2
        elif period < 1.0:
            c_h = 3.0 * period ** 2
        elif period < 1.5:
            c_h = 3.0 / period ** 0.75 * period ** 2
        elif period < 3.0:
            c_h = 3.32 / period * period ** 2
        else:
            c_h = 9.96
    else:
        raise ValueError('Soil must be type C, D or E')
    sd = c_h * z_factor * n_factor * r_factor
    return sd
