Calculate a bolometric correction constant for a J band magnitude based on
    a spectral type, using the fits of Wilking+ (1999AJ....117..469W), Dahn+
    (2002AJ....124.1170D), and Nakajima+ (2004ApJ...607..499N).

    spt - Numerical spectral type. M0=0, M9=9, L0=10, ...

    Returns: the correction `bck` such that `m_bol = k_abs + bck`, or NaN if
    `spt` is out of range.

    Valid values of `spt` are between 2 and 30.

def bck_from_spt (spt):
    """Calculate a bolometric correction constant for a J band magnitude based on
    a spectral type, using the fits of Wilking+ (1999AJ....117..469W), Dahn+
    (2002AJ....124.1170D), and Nakajima+ (2004ApJ...607..499N).

    spt - Numerical spectral type. M0=0, M9=9, L0=10, ...

    Returns: the correction `bck` such that `m_bol = k_abs + bck`, or NaN if
    `spt` is out of range.

    Valid values of `spt` are between 2 and 30.

    """

    # NOTE: the way np.piecewise() is implemented, the last 'true' value in
    # the condition list is the one that takes precedence. This motivates the
    # construction of our condition list.
    #
    # XXX: I've restructured the implementation; this needs testing!

    spt = np.asfarray (spt) # we crash with integer inputs for some reason.
    return np.piecewise (spt,
                         [spt < 30,
                          spt < 19,
                          spt <= 14,
                          spt < 10,
                          (spt < 2) | (spt >= 30)],
                         [lambda s: 3.41 - 0.21 * (s - 20), # Nakajima
                          lambda s: 3.42 - 0.075 * (s - 14), # Dahn, Nakajima
                          lambda s: 3.42 + 0.075 * (s - 14), # Dahn, Nakajima
                          lambda s: 2.43 + 0.0895 * s, # Wilking; only ok for spt >= M2!
                          np.nan])