def perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra,<EOL>solar_zenith, solar_azimuth, airmass,<EOL>model='<STR_LIT>', return_components=False):
kappa = <NUM_LIT>  <EOL>z = np.radians(solar_zenith)  <EOL>delta = dhi * airmass / dni_extra<EOL>with np.errstate(invalid='<STR_LIT:ignore>'):<EOL><INDENT>eps = ((dhi + dni) / dhi + kappa * (z ** <NUM_LIT:3>)) / (<NUM_LIT:1> + kappa * (z ** <NUM_LIT:3>))<EOL><DEDENT>if isinstance(eps, pd.Series):<EOL><INDENT>eps = eps.values<EOL><DEDENT>ebin = np.digitize(eps, (<NUM_LIT:0.>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>))<EOL>ebin = np.array(ebin)  <EOL>ebin[np.isnan(eps)] = <NUM_LIT:0><EOL>ebin -= <NUM_LIT:1><EOL>F1c, F2c = _get_perez_coefficients(model)<EOL>nans = np.array([np.nan, np.nan, np.nan])<EOL>F1c = np.vstack((F1c, nans))<EOL>F2c = np.vstack((F2c, nans))<EOL>F1 = (F1c[ebin, <NUM_LIT:0>] + F1c[ebin, <NUM_LIT:1>] * delta + F1c[ebin, <NUM_LIT:2>] * z)<EOL>F1 = np.maximum(F1, <NUM_LIT:0>)<EOL>F2 = (F2c[ebin, <NUM_LIT:0>] + F2c[ebin, <NUM_LIT:1>] * delta + F2c[ebin, <NUM_LIT:2>] * z)<EOL>F2 = np.maximum(F2, <NUM_LIT:0>)<EOL>A = aoi_projection(surface_tilt, surface_azimuth,<EOL>solar_zenith, solar_azimuth)<EOL>A = np.maximum(A, <NUM_LIT:0>)<EOL>B = tools.cosd(solar_zenith)<EOL>B = np.maximum(B, tools.cosd(<NUM_LIT>))<EOL>term1 = <NUM_LIT:0.5> * (<NUM_LIT:1> - F1) * (<NUM_LIT:1> + tools.cosd(surface_tilt))<EOL>term2 = F1 * A / B<EOL>term3 = F2 * tools.sind(surface_tilt)<EOL>sky_diffuse = np.maximum(dhi * (term1 + term2 + term3), <NUM_LIT:0>)<EOL>if isinstance(sky_diffuse, pd.Series):<EOL><INDENT>sky_diffuse[np.isnan(airmass)] = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>sky_diffuse = np.where(np.isnan(airmass), <NUM_LIT:0>, sky_diffuse)<EOL><DEDENT>if return_components:<EOL><INDENT>diffuse_components = OrderedDict()<EOL>diffuse_components['<STR_LIT>'] = sky_diffuse<EOL>diffuse_components['<STR_LIT>'] = dhi * term1<EOL>diffuse_components['<STR_LIT>'] = dhi * term2<EOL>diffuse_components['<STR_LIT>'] = dhi * term3<EOL>mask = sky_diffuse == <NUM_LIT:0><EOL>if isinstance(sky_diffuse, pd.Series):<EOL><INDENT>diffuse_components = pd.DataFrame(diffuse_components)<EOL>diffuse_components.loc[mask] = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>diffuse_components = {k: np.where(mask, <NUM_LIT:0>, v) for k, v in<EOL>diffuse_components.items()}<EOL><DEDENT>return diffuse_components<EOL><DEDENT>else:<EOL><INDENT>return sky_diffuse<EOL><DEDENT>
Determine diffuse irradiance from the sky on a tilted surface using
one of the Perez models.

Perez models determine the diffuse irradiance from the sky (ground
reflected irradiance is not included in this algorithm) on a tilted
surface using the surface tilt angle, surface azimuth angle, diffuse
horizontal irradiance, direct normal irradiance, extraterrestrial
irradiance, sun zenith angle, sun azimuth angle, and relative (not
pressure-corrected) airmass. Optionally a selector may be used to
use any of Perez's model coefficient sets.

Parameters
----------
surface_tilt : numeric
    Surface tilt angles in decimal degrees. surface_tilt must be >=0
    and <=180. The tilt angle is defined as degrees from horizontal
    (e.g. surface facing up = 0, surface facing horizon = 90)

surface_azimuth : numeric
    Surface azimuth angles in decimal degrees. surface_azimuth must
    be >=0 and <=360. The azimuth convention is defined as degrees
    east of north (e.g. North = 0, South=180 East = 90, West = 270).

dhi : numeric
    Diffuse horizontal irradiance in W/m^2. DHI must be >=0.

dni : numeric
    Direct normal irradiance in W/m^2. DNI must be >=0.

dni_extra : numeric
    Extraterrestrial normal irradiance in W/m^2.

solar_zenith : numeric
    apparent (refraction-corrected) zenith angles in decimal
    degrees. solar_zenith must be >=0 and <=180.

solar_azimuth : numeric
    Sun azimuth angles in decimal degrees. solar_azimuth must be >=0
    and <=360. The azimuth convention is defined as degrees east of
    north (e.g. North = 0, East = 90, West = 270).

airmass : numeric
    Relative (not pressure-corrected) airmass values. If AM is a
    DataFrame it must be of the same size as all other DataFrame
    inputs. AM must be >=0 (careful using the 1/sec(z) model of AM
    generation)

model : string (optional, default='allsitescomposite1990')
    A string which selects the desired set of Perez coefficients. If
    model is not provided as an input, the default, '1990' will be
    used. All possible model selections are:

    * '1990'
    * 'allsitescomposite1990' (same as '1990')
    * 'allsitescomposite1988'
    * 'sandiacomposite1988'
    * 'usacomposite1988'
    * 'france1988'
    * 'phoenix1988'
    * 'elmonte1988'
    * 'osage1988'
    * 'albuquerque1988'
    * 'capecanaveral1988'
    * 'albany1988'

return_components: bool (optional, default=False)
    Flag used to decide whether to return the calculated diffuse components
    or not.

Returns
--------
numeric, OrderedDict, or DataFrame
    Return type controlled by `return_components` argument.
    If ``return_components=False``, `sky_diffuse` is returned.
    If ``return_components=True``, `diffuse_components` is returned.

sky_diffuse : numeric
    The sky diffuse component of the solar radiation on a tilted
    surface.

diffuse_components : OrderedDict (array input) or DataFrame (Series input)
    Keys/columns are:
        * sky_diffuse: Total sky diffuse
        * isotropic
        * circumsolar
        * horizon


References
----------
[1] Loutzenhiser P.G. et. al. "Empirical validation of models to
compute solar irradiance on inclined surfaces for building energy
simulation" 2007, Solar Energy vol. 81. pp. 254-267

[2] Perez, R., Seals, R., Ineichen, P., Stewart, R., Menicucci, D.,
1987. A new simplified version of the Perez diffuse irradiance model
for tilted surfaces. Solar Energy 39(3), 221-232.

[3] Perez, R., Ineichen, P., Seals, R., Michalsky, J., Stewart, R.,
1990. Modeling daylight availability and irradiance components from
direct and global irradiance. Solar Energy 44 (5), 271-289.

[4] Perez, R. et. al 1988. "The Development and Verification of the
Perez Diffuse Radiation Model". SAND88-7030