def test_perez():
    AM = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    irradiance.perez(40, 180, irrad_data['DHI'], irrad_data['DNI'],
                            dni_et,
                            ephem_data['apparent_zenith'],
                            ephem_data['apparent_azimuth'],
                            AM) 
Example #2
0
def test_perez_components(irrad_data, ephem_data, dni_et, relative_airmass):
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out = irradiance.perez(40,
                           180,
                           irrad_data['dhi'],
                           dni,
                           dni_et,
                           ephem_data['apparent_zenith'],
                           ephem_data['azimuth'],
                           relative_airmass,
                           return_components=True)
    expected = pd.DataFrame(
        np.array([[0., 31.46046871, np.nan, 45.45539877],
                  [0., 26.84138589, np.nan, 31.72696071],
                  [0., 0., np.nan, 4.47966439],
                  [0., 4.62212181, np.nan, 9.25316454]]).T,
        columns=['sky_diffuse', 'isotropic', 'circumsolar', 'horizon'],
        index=irrad_data.index)
    expected_for_sum = expected['sky_diffuse'].copy()
    expected_for_sum.iloc[2] = 0
    sum_components = out.iloc[:, 1:].sum(axis=1)
    sum_components.name = 'sky_diffuse'

    assert_frame_equal(out, expected, check_less_precise=2)
    assert_series_equal(sum_components, expected_for_sum, check_less_precise=2)
Example #3
0
def test_perez_components():
    am = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out, df_components = irradiance.perez(40,
                                          180,
                                          irrad_data['dhi'],
                                          dni,
                                          dni_et,
                                          ephem_data['apparent_zenith'],
                                          ephem_data['azimuth'],
                                          am,
                                          return_components=True)
    expected = pd.Series(np.array([0., 31.46046871, np.nan, 45.45539877]),
                         index=times)
    expected_components = pd.DataFrame(
        np.array([[0., 26.84138589, np.nan, 31.72696071],
                  [0., 0., np.nan, 4.47966439],
                  [0., 4.62212181, np.nan, 9.25316454]]).T,
        columns=['isotropic', 'circumsolar', 'horizon'],
        index=times)
    sum_components = df_components.sum(axis=1)

    assert_series_equal(out, expected, check_less_precise=2)
    assert_frame_equal(df_components, expected_components)
    assert_series_equal(sum_components, expected, check_less_precise=2)
def test_perez_components():
    am = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out, df_components = irradiance.perez(40, 180, irrad_data['dhi'], dni,
                     dni_et, ephem_data['apparent_zenith'],
                     ephem_data['azimuth'], am, return_components=True)
    expected = pd.Series(np.array(
        [   0.        ,   31.46046871,  np.nan,   45.45539877]),
        index=times)
    expected_components = pd.DataFrame(
        np.array([[  0.        ,  26.84138589,          np.nan,  31.72696071],
                 [ 0.        ,  0.        ,         np.nan,  4.47966439],
                 [ 0.        ,  4.62212181,         np.nan,  9.25316454]]).T,
        columns=['isotropic', 'circumsolar', 'horizon'],
        index=times
    )
    if pandas_0_22():
        expected_for_sum = expected.copy()
        expected_for_sum.iloc[2] = 0
    else:
        expected_for_sum = expected
    sum_components = df_components.sum(axis=1)

    assert_series_equal(out, expected, check_less_precise=2)
    assert_frame_equal(df_components, expected_components)
    assert_series_equal(sum_components, expected_for_sum, check_less_precise=2)
Example #5
0
def test_perez_components(irrad_data, ephem_data, dni_et, relative_airmass):
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out = irradiance.perez(40, 180, irrad_data['dhi'], dni,
                           dni_et, ephem_data['apparent_zenith'],
                           ephem_data['azimuth'], relative_airmass,
                           return_components=True)
    expected = pd.DataFrame(np.array(
        [[   0.        ,   31.46046871,  np.nan,   45.45539877],
         [  0.        ,  26.84138589,          np.nan,  31.72696071],
         [ 0.        ,  0.        ,         np.nan,  4.47966439],
         [ 0.        ,  4.62212181,         np.nan,  9.25316454]]).T,
        columns=['sky_diffuse', 'isotropic', 'circumsolar', 'horizon'],
        index=irrad_data.index
    )
    if pandas_0_22():
        expected_for_sum = expected['sky_diffuse'].copy()
        expected_for_sum.iloc[2] = 0
    else:
        expected_for_sum = expected['sky_diffuse']
    sum_components = out.iloc[:, 1:].sum(axis=1)
    sum_components.name = 'sky_diffuse'

    assert_frame_equal(out, expected, check_less_precise=2)
    assert_series_equal(sum_components, expected_for_sum, check_less_precise=2)
Example #6
0
def test_perez_scalar():
    # copied values from fixtures
    out = irradiance.perez(40, 180, 118.45831879, 939.95469881,
                           1321.1655834833093, 10.56413562, 144.76567754,
                           1.01688136)
    # this will fail. out is ndarry with ndim == 0. fix in future version.
    # assert np.isscalar(out)
    assert_allclose(out, 109.084332)
Example #7
0
def test_perez_scalar():
    # copied values from fixtures
    out = irradiance.perez(40, 180, 118.45831879, 939.95469881,
                           1321.1655834833093, 10.56413562, 144.76567754,
                           1.01688136)
    # this will fail. out is ndarry with ndim == 0. fix in future version.
    # assert np.isscalar(out)
    assert_allclose(out, 109.084332)
Example #8
0
def test_perez_arrays():
    am = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out = irradiance.perez(40, 180, irrad_data['dhi'].values, dni.values,
                           dni_et, ephem_data['apparent_zenith'].values,
                           ephem_data['azimuth'].values, am.values)
    expected = np.array([0., 31.46046871, np.nan, 45.45539877])
    assert_allclose(out, expected, atol=1e-2)
Example #9
0
def test_perez(irrad_data, ephem_data, dni_et, relative_airmass):
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out = irradiance.perez(40, 180, irrad_data['dhi'], dni, dni_et,
                           ephem_data['apparent_zenith'],
                           ephem_data['azimuth'], relative_airmass)
    expected = pd.Series(np.array([0., 31.46046871, np.nan, 45.45539877]),
                         index=irrad_data.index)
    assert_series_equal(out, expected, check_less_precise=2)
Example #10
0
def test_perez_arrays():
    am = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out = irradiance.perez(40, 180, irrad_data['dhi'].values, dni.values,
                     dni_et, ephem_data['apparent_zenith'].values,
                     ephem_data['azimuth'].values, am.values)
    expected = np.array(
        [   0.        ,   31.46046871,  np.nan,   45.45539877])
    assert_allclose(out, expected, atol=1e-2)
Example #11
0
def test_perez(irrad_data, ephem_data, dni_et, relative_airmass):
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out = irradiance.perez(40, 180, irrad_data['dhi'], dni,
                     dni_et, ephem_data['apparent_zenith'],
                     ephem_data['azimuth'], relative_airmass)
    expected = pd.Series(np.array(
        [   0.        ,   31.46046871,  np.nan,   45.45539877]),
        index=irrad_data.index)
    assert_series_equal(out, expected, check_less_precise=2)
Example #12
0
def test_perez_arrays(irrad_data, ephem_data, dni_et, relative_airmass):
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out = irradiance.perez(40, 180, irrad_data['dhi'].values, dni.values,
                           dni_et, ephem_data['apparent_zenith'].values,
                           ephem_data['azimuth'].values,
                           relative_airmass.values)
    expected = np.array([0., 31.46046871, np.nan, 45.45539877])
    assert_allclose(out, expected, atol=1e-2)
    assert isinstance(out, np.ndarray)
Example #13
0
def test_perez_arrays(irrad_data, ephem_data, dni_et, relative_airmass):
    dni = irrad_data['dni'].copy()
    dni.iloc[2] = np.nan
    out = irradiance.perez(40, 180, irrad_data['dhi'].values, dni.values,
                     dni_et, ephem_data['apparent_zenith'].values,
                     ephem_data['azimuth'].values, relative_airmass.values)
    expected = np.array(
        [   0.        ,   31.46046871,  np.nan,   45.45539877])
    assert_allclose(out, expected, atol=1e-2)
    assert isinstance(out, np.ndarray)
Example #14
0
def test_globalinplane():
    aoi = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
                         ephem_data['azimuth'])
    airmass = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    gr_sand = irradiance.grounddiffuse(40, ghi, surface_type='sand')
    diff_perez = irradiance.perez(
        40, 180, irrad_data['dhi'], irrad_data['dni'], dni_et,
        ephem_data['apparent_zenith'], ephem_data['azimuth'], airmass)
    irradiance.globalinplane(
        aoi=aoi, dni=irrad_data['dni'], poa_sky_diffuse=diff_perez,
        poa_ground_diffuse=gr_sand)
def test_globalinplane():
    AOI = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
                         ephem_data['apparent_azimuth'])
    AM = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    gr_sand = irradiance.grounddiffuse(40, ghi, surface_type='sand')
    diff_perez = irradiance.perez(
        40, 180, irrad_data['DHI'], irrad_data['DNI'], dni_et,
        ephem_data['apparent_zenith'], ephem_data['apparent_azimuth'], AM)
    irradiance.globalinplane(
        AOI=AOI, DNI=irrad_data['DNI'], In_Plane_SkyDiffuse=diff_perez,
        GR=gr_sand)
Example #16
0
def test_globalinplane():
    aoi = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
                         ephem_data['apparent_azimuth'])
    airmass = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    gr_sand = irradiance.grounddiffuse(40, ghi, surface_type='sand')
    diff_perez = irradiance.perez(
        40, 180, irrad_data['dhi'], irrad_data['dni'], dni_et,
        ephem_data['apparent_zenith'], ephem_data['apparent_azimuth'], airmass)
    irradiance.globalinplane(
        aoi=aoi, dni=irrad_data['dni'], poa_sky_diffuse=diff_perez,
        poa_ground_diffuse=gr_sand)
Example #17
0
def test_globalinplane():
    AOI = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
                         ephem_data['apparent_azimuth'])
    AM = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    gr_sand = irradiance.grounddiffuse(40, ghi, surface_type='sand')
    diff_perez = irradiance.perez(40, 180, irrad_data['DHI'],
                                  irrad_data['DNI'], dni_et,
                                  ephem_data['apparent_zenith'],
                                  ephem_data['apparent_azimuth'], AM)
    irradiance.globalinplane(AOI=AOI,
                             DNI=irrad_data['DNI'],
                             In_Plane_SkyDiffuse=diff_perez,
                             GR=gr_sand)
Example #18
0
def test_perez_negative_horizon():
    times = pd.date_range(start='20190101 11:30:00',
                          freq='1H',
                          periods=5,
                          tz='US/Central')

    # Avoid test dependencies on functionality not being tested by hard-coding
    # the inputs. This data corresponds to Goodwin Creek in the afternoon on
    # 1/1/2019.
    # dni_e is slightly rounded from irradiance.get_extra_radiation
    # airmass from atmosphere.get_relative_airmas
    inputs = pd.DataFrame(
        np.array([[158, 19, 1, 0, 0], [249, 165, 136, 93, 50],
                  [57.746951, 57.564205, 60.813841, 66.989435, 75.353368],
                  [171.003315, 187.346924, 202.974357, 216.725599, 228.317233],
                  [1414, 1414, 1414, 1414, 1414],
                  [1.869315, 1.859981, 2.044429, 2.544943, 3.900136]]).T,
        columns=[
            'dni', 'dhi', 'solar_zenith', 'solar_azimuth', 'dni_extra',
            'airmass'
        ],
        index=times)

    out = irradiance.perez(34,
                           180,
                           inputs['dhi'],
                           inputs['dni'],
                           inputs['dni_extra'],
                           inputs['solar_zenith'],
                           inputs['solar_azimuth'],
                           inputs['airmass'],
                           model='allsitescomposite1990',
                           return_components=True)

    # sky_diffuse can be less than isotropic under certain conditions as
    # horizon goes negative
    expected = pd.DataFrame(
        np.array([[281.410185, 152.20879, 123.867898, 82.836412, 43.517015],
                  [166.785419, 142.24475, 119.173875, 83.525150, 45.725931],
                  [113.548755, 16.09757, 9.956174, 3.142467, 0],
                  [1.076010, -6.13353, -5.262151, -3.831230, -2.208923]]).T,
        columns=['sky_diffuse', 'isotropic', 'circumsolar', 'horizon'],
        index=times)

    expected_for_sum = expected['sky_diffuse'].copy()
    sum_components = out.iloc[:, 1:].sum(axis=1)
    sum_components.name = 'sky_diffuse'

    assert_frame_equal(out, expected, check_less_precise=2)
    assert_series_equal(sum_components, expected_for_sum, check_less_precise=2)
Example #19
0
def test_poa_components(irrad_data, ephem_data, dni_et, relative_airmass):
    aoi = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
                         ephem_data['azimuth'])
    gr_sand = irradiance.get_ground_diffuse(40, irrad_data['ghi'],
                                            surface_type='sand')
    diff_perez = irradiance.perez(
        40, 180, irrad_data['dhi'], irrad_data['dni'], dni_et,
        ephem_data['apparent_zenith'], ephem_data['azimuth'], relative_airmass)
    out = irradiance.poa_components(
        aoi, irrad_data['dni'], diff_perez, gr_sand)
    expected = pd.DataFrame(np.array(
        [[  0.        ,  -0.        ,   0.        ,   0.        ,
            0.        ],
         [ 35.19456561,   0.        ,  35.19456561,  31.4635077 ,
            3.73105791],
         [956.18253696, 798.31939281, 157.86314414, 109.08433162,
           48.77881252],
         [ 90.99624896,  33.50143401,  57.49481495,  45.45978964,
           12.03502531]]),
        columns=['poa_global', 'poa_direct', 'poa_diffuse', 'poa_sky_diffuse',
                 'poa_ground_diffuse'],
        index=irrad_data.index)
    assert_frame_equal(out, expected)
Example #20
0
def test_poa_components(irrad_data, ephem_data, dni_et, relative_airmass):
    aoi = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
                         ephem_data['azimuth'])
    gr_sand = irradiance.get_ground_diffuse(40,
                                            irrad_data['ghi'],
                                            surface_type='sand')
    diff_perez = irradiance.perez(40, 180, irrad_data['dhi'],
                                  irrad_data['dni'], dni_et,
                                  ephem_data['apparent_zenith'],
                                  ephem_data['azimuth'], relative_airmass)
    out = irradiance.poa_components(aoi, irrad_data['dni'], diff_perez,
                                    gr_sand)
    expected = pd.DataFrame(np.array(
        [[0., -0., 0., 0., 0.],
         [35.19456561, 0., 35.19456561, 31.4635077, 3.73105791],
         [956.18253696, 798.31939281, 157.86314414, 109.08433162, 48.77881252],
         [90.99624896, 33.50143401, 57.49481495, 45.45978964, 12.03502531]]),
                            columns=[
                                'poa_global', 'poa_direct', 'poa_diffuse',
                                'poa_sky_diffuse', 'poa_ground_diffuse'
                            ],
                            index=irrad_data.index)
    assert_frame_equal(out, expected)
Example #21
0
def test_perez():
    AM = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    irradiance.perez(40, 180, irrad_data['dhi'], irrad_data['dni'], dni_et,
                     ephem_data['apparent_zenith'],
                     ephem_data['apparent_azimuth'], AM)
Example #22
0
def test_perez():
    am = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    out = irradiance.perez(40, 180, irrad_data['dhi'], irrad_data['dni'],
                           dni_et, ephem_data['apparent_zenith'],
                           ephem_data['azimuth'], am)
    assert not out.isnull().any()
Example #23
0
def test_perez():
    am = atmosphere.relativeairmass(ephem_data['apparent_zenith'])
    out = irradiance.perez(40, 180, irrad_data['dhi'], irrad_data['dni'],
                     dni_et, ephem_data['apparent_zenith'],
                     ephem_data['azimuth'], am)
    assert not out.isnull().any()
Example #24
0
def perez_diffuse_luminance(timestamps, surface_tilt, surface_azimuth,
                            solar_zenith, solar_azimuth, dni, dhi):
    """Function used to calculate the luminance and the view factor terms from the
    Perez diffuse light transposition model, as implemented in the
    ``pvlib-python`` library.
    This function was custom made to allow the calculation of the circumsolar
    component on the back surface as well. Otherwise, the ``pvlib``
    implementation would ignore it.

    Parameters
    ----------
    timestamps : array-like
        simulation timestamps
    surface_tilt : array-like
        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 : array-like
        The azimuth of the rotated panel,
        determined by projecting the vector normal to the panel's surface to
        the earth's surface [degrees].
    solar_zenith : array-like
        solar zenith angles
    solar_azimuth : array-like
        solar azimuth angles
    dni : array-like
        values for direct normal irradiance
    dhi : array-like
        values for diffuse horizontal irradiance

    Returns
    -------
    df_inputs : `pandas.DataFrame`
        Dataframe with the following columns:
        ['solar_zenith', 'solar_azimuth', 'surface_tilt', 'surface_azimuth',
        'dhi', 'dni', 'vf_horizon', 'vf_circumsolar', 'vf_isotropic',
        'luminance_horizon', 'luminance_circuqmsolar', 'luminance_isotropic',
        'poa_isotropic', 'poa_circumsolar', 'poa_horizon', 'poa_total_diffuse']

    """
    # Create a dataframe to help filtering on all arrays
    df_inputs = pd.DataFrame(
        {
            'surface_tilt': surface_tilt,
            'surface_azimuth': surface_azimuth,
            'solar_zenith': solar_zenith,
            'solar_azimuth': solar_azimuth,
            'dni': dni,
            'dhi': dhi
        },
        index=pd.DatetimeIndex(timestamps))

    dni_et = irradiance.get_extra_radiation(df_inputs.index.dayofyear)
    am = atmosphere.get_relative_airmass(df_inputs.solar_zenith)

    # Need to treat the case when the sun is hitting the back surface of pvrow
    aoi_proj = irradiance.aoi_projection(df_inputs.surface_tilt,
                                         df_inputs.surface_azimuth,
                                         df_inputs.solar_zenith,
                                         df_inputs.solar_azimuth)
    sun_hitting_back_surface = ((aoi_proj < 0) &
                                (df_inputs.solar_zenith <= 90))
    df_inputs_back_surface = df_inputs.loc[sun_hitting_back_surface].copy()
    # Reverse the surface normal to switch to back-surface circumsolar calc
    df_inputs_back_surface.loc[:, 'surface_azimuth'] = (
        df_inputs_back_surface.loc[:, 'surface_azimuth'] - 180.)
    df_inputs_back_surface.loc[:, 'surface_azimuth'] = np.mod(
        df_inputs_back_surface.loc[:, 'surface_azimuth'], 360.)
    df_inputs_back_surface.loc[:, 'surface_tilt'] = (
        180. - df_inputs_back_surface.surface_tilt)

    if df_inputs_back_surface.shape[0] > 0:
        # Use recursion to calculate circumsolar luminance for back surface
        df_inputs_back_surface = perez_diffuse_luminance(
            *breakup_df_inputs(df_inputs_back_surface))

    # Calculate Perez diffuse components
    components = irradiance.perez(df_inputs.surface_tilt,
                                  df_inputs.surface_azimuth,
                                  df_inputs.dhi,
                                  df_inputs.dni,
                                  dni_et,
                                  df_inputs.solar_zenith,
                                  df_inputs.solar_azimuth,
                                  am,
                                  return_components=True)

    # Calculate Perez view factors:
    a = irradiance.aoi_projection(df_inputs.surface_tilt,
                                  df_inputs.surface_azimuth,
                                  df_inputs.solar_zenith,
                                  df_inputs.solar_azimuth)
    a = np.maximum(a, 0)
    b = cosd(df_inputs.solar_zenith)
    b = np.maximum(b, cosd(85))

    vf_perez = pd.DataFrame(
        {
            'vf_horizon': sind(df_inputs.surface_tilt),
            'vf_circumsolar': a / b,
            'vf_isotropic': (1. + cosd(df_inputs.surface_tilt)) / 2.
        },
        index=df_inputs.index)

    # Calculate diffuse luminance
    luminance = pd.DataFrame(np.array([
        components['horizon'] / vf_perez['vf_horizon'],
        components['circumsolar'] / vf_perez['vf_circumsolar'],
        components['isotropic'] / vf_perez['vf_isotropic']
    ]).T,
                             index=df_inputs.index,
                             columns=[
                                 'luminance_horizon', 'luminance_circumsolar',
                                 'luminance_isotropic'
                             ])
    luminance.loc[components['sky_diffuse'] == 0, :] = 0.

    # Format components column names
    components = components.rename(
        columns={
            'isotropic': 'poa_isotropic',
            'circumsolar': 'poa_circumsolar',
            'horizon': 'poa_horizon'
        })

    df_inputs = pd.concat([df_inputs, components, vf_perez, luminance],
                          axis=1,
                          join='outer')
    df_inputs = df_inputs.rename(columns={'sky_diffuse': 'poa_total_diffuse'})

    # Adjust the circumsolar luminance when it hits the back surface
    if df_inputs_back_surface.shape[0] > 0:
        df_inputs.loc[sun_hitting_back_surface, 'luminance_circumsolar'] = (
            df_inputs_back_surface.loc[:, 'luminance_circumsolar'])

    return df_inputs
Example #25
0
def perez_diffuse_luminance(timestamps, array_tilt, array_azimuth,
                            solar_zenith, solar_azimuth, dni, dhi):
    """
    Function used to calculate the luminance and the view factor terms from the
    Perez diffuse light transposition model, as implemented in the
    ``pvlib-python`` library.
    This function was custom made to allow the calculation of the circumsolar
    component on the back surface as well. Otherwise, the ``pvlib``
    implementation would ignore it.

    :param array-like timestamps: simulation timestamps
    :param array-like array_tilt: pv module tilt angles
    :param array-like array_azimuth: pv array azimuth angles
    :param array-like solar_zenith: solar zenith angles
    :param array-like solar_azimuth: solar azimuth angles
    :param array-like dni: values for direct normal irradiance
    :param array-like dhi: values for diffuse horizontal irradiance
    :return: ``df_inputs``, dataframe with the following columns:
        ['solar_zenith', 'solar_azimuth', 'array_tilt', 'array_azimuth', 'dhi',
        'dni', 'vf_horizon', 'vf_circumsolar', 'vf_isotropic',
        'luminance_horizon', 'luminance_circumsolar', 'luminance_isotropic',
        'poa_isotropic', 'poa_circumsolar', 'poa_horizon', 'poa_total_diffuse']
    :rtype: class:`pandas.DataFrame`
    """
    # Create a dataframe to help filtering on all arrays
    df_inputs = pd.DataFrame(
        {
            'array_tilt': array_tilt,
            'array_azimuth': array_azimuth,
            'solar_zenith': solar_zenith,
            'solar_azimuth': solar_azimuth,
            'dni': dni,
            'dhi': dhi
        },
        index=pd.DatetimeIndex(timestamps))

    dni_et = irradiance.extraradiation(df_inputs.index.dayofyear)
    am = atmosphere.relativeairmass(df_inputs.solar_zenith)

    # Need to treat the case when the sun is hitting the back surface of pvrow
    aoi_proj = aoi_projection(df_inputs.array_tilt, df_inputs.array_azimuth,
                              df_inputs.solar_zenith, df_inputs.solar_azimuth)
    sun_hitting_back_surface = ((aoi_proj < 0) &
                                (df_inputs.solar_zenith <= 90))
    df_inputs_back_surface = df_inputs.loc[sun_hitting_back_surface]
    # Reverse the surface normal to switch to back-surface circumsolar calc
    df_inputs_back_surface.loc[:, 'array_azimuth'] -= 180.
    df_inputs_back_surface.loc[:, 'array_azimuth'] = np.mod(
        df_inputs_back_surface.loc[:, 'array_azimuth'], 360.)
    df_inputs_back_surface.loc[:, 'array_tilt'] = (
        180. - df_inputs_back_surface.array_tilt)

    if df_inputs_back_surface.shape[0] > 0:
        # Use recursion to calculate circumsolar luminance for back surface
        df_inputs_back_surface = perez_diffuse_luminance(
            *breakup_df_inputs(df_inputs_back_surface))

    # Calculate Perez diffuse components
    diffuse_poa, components = irradiance.perez(df_inputs.array_tilt,
                                               df_inputs.array_azimuth,
                                               df_inputs.dhi,
                                               df_inputs.dni,
                                               dni_et,
                                               df_inputs.solar_zenith,
                                               df_inputs.solar_azimuth,
                                               am,
                                               return_components=True)

    # Calculate Perez view factors:
    a = aoi_projection(df_inputs.array_tilt, df_inputs.array_azimuth,
                       df_inputs.solar_zenith, df_inputs.solar_azimuth)
    a = np.maximum(a, 0)
    b = cosd(df_inputs.solar_zenith)
    b = np.maximum(b, cosd(85))

    vf_perez = pd.DataFrame(
        np.array([
            sind(df_inputs.array_tilt), a / b,
            (1. + cosd(df_inputs.array_tilt)) / 2.
        ]).T,
        index=df_inputs.index,
        columns=['vf_horizon', 'vf_circumsolar', 'vf_isotropic'])

    # Calculate diffuse luminance
    luminance = pd.DataFrame(np.array([
        components['horizon'] / vf_perez['vf_horizon'],
        components['circumsolar'] / vf_perez['vf_circumsolar'],
        components['isotropic'] / vf_perez['vf_isotropic']
    ]).T,
                             index=df_inputs.index,
                             columns=[
                                 'luminance_horizon', 'luminance_circumsolar',
                                 'luminance_isotropic'
                             ])
    luminance.loc[diffuse_poa == 0, :] = 0.

    # Format components column names
    components = components.rename(
        columns={
            'isotropic': 'poa_isotropic',
            'circumsolar': 'poa_circumsolar',
            'horizon': 'poa_horizon'
        })

    df_inputs = pd.concat(
        [df_inputs, components, vf_perez, luminance, diffuse_poa],
        axis=1,
        join='outer')
    df_inputs = df_inputs.rename(columns={0: 'poa_total_diffuse'})

    # Adjust the circumsolar luminance when it hits the back surface
    if df_inputs_back_surface.shape[0] > 0:
        df_inputs.loc[sun_hitting_back_surface, 'luminance_circumsolar'] = (
            df_inputs_back_surface.loc[:, 'luminance_circumsolar'])
    return df_inputs
def test_perez_scalar():
    # copied values from fixtures
    out = irradiance.perez(40, 180, 118.45831879, 939.95469881,
                           1321.1655834833093, 10.56413562, 144.76567754,
                           1.01688136)
    assert_allclose(out, 109.084332)
Example #27
0
def perez_diffuse_luminance(df_inputs):
    """
    Function used to calculate the luminance and the view factor terms from the
    Perez diffuse light transposition model, as implemented in the
    ``pvlib-python`` library.

    :param df_inputs: class:`pandas.DataFrame` with following columns:
        ['solar_zenith', 'solar_azimuth', 'array_tilt', 'array_azimuth', 'dhi',
        'dni']. Units are: ['deg', 'deg', 'deg', 'deg', 'W/m2', 'W/m2']
    :return: class:`pandas.DataFrame` with the following columns:
        ['solar_zenith', 'solar_azimuth', 'array_tilt', 'array_azimuth', 'dhi',
        'dni', 'vf_horizon', 'vf_circumsolar', 'vf_isotropic',
        'luminance_horizon', 'luminance_circumsolar', 'luminance_isotropic',
        'poa_isotropic', 'poa_circumsolar', 'poa_horizon', 'poa_total_diffuse']
    """

    dni_et = irradiance.extraradiation(df_inputs.index.dayofyear)
    am = atmosphere.relativeairmass(df_inputs.solar_zenith)

    # Need to treat the case when the sun is hitting the back surface of pvrow
    aoi_proj = aoi_projection(df_inputs.array_tilt, df_inputs.array_azimuth,
                              df_inputs.solar_zenith, df_inputs.solar_azimuth)
    sun_hitting_back_surface = ((aoi_proj < 0) &
                                (df_inputs.solar_zenith <= 90))
    df_inputs_back_surface = df_inputs.loc[sun_hitting_back_surface]
    # Reverse the surface normal to switch to back-surface circumsolar calc
    df_inputs_back_surface.loc[:, 'array_azimuth'] -= 180.
    df_inputs_back_surface.loc[:, 'array_azimuth'] = np.mod(
        df_inputs_back_surface.loc[:, 'array_azimuth'], 360.
    )
    df_inputs_back_surface.loc[:, 'array_tilt'] = (
        180. - df_inputs_back_surface.array_tilt)

    if df_inputs_back_surface.shape[0] > 0:
        # Use recursion to calculate circumsolar luminance for back surface
        df_inputs_back_surface = perez_diffuse_luminance(
            df_inputs_back_surface)

    # Calculate Perez diffuse components
    diffuse_poa, components = irradiance.perez(df_inputs.array_tilt,
                                               df_inputs.array_azimuth,
                                               df_inputs.dhi, df_inputs.dni,
                                               dni_et,
                                               df_inputs.solar_zenith,
                                               df_inputs.solar_azimuth,
                                               am,
                                               return_components=True)

    # Calculate Perez view factors:
    a = aoi_projection(df_inputs.array_tilt, df_inputs.array_azimuth,
                       df_inputs.solar_zenith, df_inputs.solar_azimuth)
    a = np.maximum(a, 0)
    b = cosd(df_inputs.solar_zenith)
    b = np.maximum(b, cosd(85))

    vf_perez = pd.DataFrame(
        np.array([
            sind(df_inputs.array_tilt),
            a / b,
            (1. + cosd(df_inputs.array_tilt)) / 2.
        ]).T,
        index=df_inputs.index,
        columns=['vf_horizon', 'vf_circumsolar', 'vf_isotropic']
    )

    # Calculate diffuse luminance
    luminance = pd.DataFrame(
        np.array([
            components['horizon'] / vf_perez['vf_horizon'],
            components['circumsolar'] / vf_perez['vf_circumsolar'],
            components['isotropic'] / vf_perez['vf_isotropic']
        ]).T,
        index=df_inputs.index,
        columns=['luminance_horizon', 'luminance_circumsolar',
                 'luminance_isotropic']
    )
    luminance.loc[diffuse_poa == 0, :] = 0.

    # Format components column names
    components = components.rename(columns={'isotropic': 'poa_isotropic',
                                            'circumsolar': 'poa_circumsolar',
                                            'horizon': 'poa_horizon'})

    df_inputs = pd.concat([df_inputs, components, vf_perez, luminance,
                           diffuse_poa],
                          axis=1, join='outer')
    df_inputs = df_inputs.rename(columns={0: 'poa_total_diffuse'})

    # Adjust the circumsolar luminance when it hits the back surface
    if df_inputs_back_surface.shape[0] > 0:
        df_inputs.loc[sun_hitting_back_surface, 'luminance_circumsolar'] = (
            df_inputs_back_surface.loc[:, 'luminance_circumsolar']
        )
    return df_inputs