Determine the incidence angle modifier using the ASHRAE transmission
    model.

    ashraeiam calculates the incidence angle modifier as developed in
    [1], and adopted by ASHRAE (American Society of Heating,
    Refrigeration, and Air Conditioning Engineers) [2]. The model has
    been used by model programs such as PVSyst [3].

    Note: For incident angles near 90 degrees, this model has a
    discontinuity which has been addressed in this function.

    Parameters
    ----------
    aoi : numeric
        The angle of incidence between the module normal vector and the
        sun-beam vector in degrees. Angles of nan will result in nan.

    b : float, default 0.05
        A parameter to adjust the modifier as a function of angle of
        incidence. Typical values are on the order of 0.05 [3].

    Returns
    -------
    IAM : numeric
        The incident angle modifier calculated as 1-b*(sec(aoi)-1) as
        described in [2,3].

        Returns zeros for all abs(aoi) >= 90 and for all IAM values that
        would be less than 0.

    References
    ----------
    [1] Souka A.F., Safwat H.H., "Determination of the optimum
    orientations for the double exposure flat-plate collector and its
    reflections". Solar Energy vol .10, pp 170-174. 1966.

    [2] ASHRAE standard 93-77

    [3] PVsyst Contextual Help.
    http://files.pvsyst.com/help/index.html?iam_loss.htm retrieved on
    September 10, 2012

    See Also
    --------
    irradiance.aoi
    physicaliam

def ashraeiam(aoi, b=0.05):
    '''
    Determine the incidence angle modifier using the ASHRAE transmission
    model.

    ashraeiam calculates the incidence angle modifier as developed in
    [1], and adopted by ASHRAE (American Society of Heating,
    Refrigeration, and Air Conditioning Engineers) [2]. The model has
    been used by model programs such as PVSyst [3].

    Note: For incident angles near 90 degrees, this model has a
    discontinuity which has been addressed in this function.

    Parameters
    ----------
    aoi : numeric
        The angle of incidence between the module normal vector and the
        sun-beam vector in degrees. Angles of nan will result in nan.

    b : float, default 0.05
        A parameter to adjust the modifier as a function of angle of
        incidence. Typical values are on the order of 0.05 [3].

    Returns
    -------
    IAM : numeric
        The incident angle modifier calculated as 1-b*(sec(aoi)-1) as
        described in [2,3].

        Returns zeros for all abs(aoi) >= 90 and for all IAM values that
        would be less than 0.

    References
    ----------
    [1] Souka A.F., Safwat H.H., "Determination of the optimum
    orientations for the double exposure flat-plate collector and its
    reflections". Solar Energy vol .10, pp 170-174. 1966.

    [2] ASHRAE standard 93-77

    [3] PVsyst Contextual Help.
    http://files.pvsyst.com/help/index.html?iam_loss.htm retrieved on
    September 10, 2012

    See Also
    --------
    irradiance.aoi
    physicaliam
    '''

    iam = 1 - b * ((1 / np.cos(np.radians(aoi)) - 1))
    aoi_gte_90 = np.full_like(aoi, False, dtype='bool')
    np.greater_equal(np.abs(aoi), 90, where=~np.isnan(aoi), out=aoi_gte_90)
    iam = np.where(aoi_gte_90, 0, iam)
    iam = np.maximum(0, iam)

    if isinstance(iam, pd.Series):
        iam = pd.Series(iam, index=aoi.index)

    return iam