예제 #1
0
def test_backtrack():
    apparent_zenith = pd.Series([80])
    apparent_azimuth = pd.Series([90])

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=False,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 0, 'surface_azimuth': 90,
                           'surface_tilt': 80, 'tracker_theta': 80},
                           index=[0], dtype=np.float64)

    assert_frame_equal(expect, tracker_data)

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 52.5716, 'surface_azimuth': 90,
                           'surface_tilt': 27.42833, 'tracker_theta': 27.4283},
                           index=[0], dtype=np.float64)

    assert_frame_equal(expect, tracker_data)
예제 #2
0
def test_axis_tilt():
    apparent_zenith = pd.Series([30])
    apparent_azimuth = pd.Series([135])

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=30, axis_azimuth=180,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 7.286245, 'surface_azimuth': 142.65730,
                           'surface_tilt': 35.98741,
                           'tracker_theta': -20.88121},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=30, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 47.6632, 'surface_azimuth': 50.96969,
                           'surface_tilt': 42.5152, 'tracker_theta': 31.6655},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)
예제 #3
0
def test_backtrack():
    apparent_zenith = pd.Series([80])
    apparent_azimuth = pd.Series([90])

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=False,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 0, 'surface_azimuth': 90,
                           'surface_tilt': 80, 'tracker_theta': 80},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 52.5716, 'surface_azimuth': 90,
                           'surface_tilt': 27.42833, 'tracker_theta': 27.4283},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)
예제 #4
0
def test_azimuth_north_south():
    apparent_zenith = pd.Series([60])
    apparent_azimuth = pd.Series([90])

    tracker_data = tracking.singleaxis(apparent_zenith,
                                       apparent_azimuth,
                                       axis_tilt=0,
                                       axis_azimuth=180,
                                       max_angle=90,
                                       backtrack=True,
                                       gcr=2.0 / 7.0)

    expect = pd.DataFrame(
        {
            'aoi': 0,
            'surface_azimuth': 90,
            'surface_tilt': 60,
            'tracker_theta': -60
        },
        index=[0],
        dtype=np.float64)

    assert_frame_equal(expect, tracker_data)

    tracker_data = tracking.singleaxis(apparent_zenith,
                                       apparent_azimuth,
                                       axis_tilt=0,
                                       axis_azimuth=0,
                                       max_angle=90,
                                       backtrack=True,
                                       gcr=2.0 / 7.0)

    expect['tracker_theta'] *= -1

    assert_frame_equal(expect, tracker_data)
예제 #5
0
def test_axis_tilt():
    apparent_zenith = pd.Series([30])
    apparent_azimuth = pd.Series([135])

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=30, axis_azimuth=180,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 7.286245, 'surface_azimuth': 142.65730,
                           'surface_tilt': 35.98741,
                           'tracker_theta': -20.88121},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=30, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 47.6632, 'surface_azimuth': 50.96969,
                           'surface_tilt': 42.5152, 'tracker_theta': 31.6655},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)
예제 #6
0
def test_axis_azimuth():
    apparent_zenith = pd.Series([30])
    apparent_azimuth = pd.Series([90])

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=90,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 30, 'surface_azimuth': 180,
                           'surface_tilt': 0, 'tracker_theta': 0},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)

    apparent_zenith = pd.Series([30])
    apparent_azimuth = pd.Series([180])

    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=90,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 0, 'surface_azimuth': 180,
                           'surface_tilt': 30, 'tracker_theta': 30},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)
예제 #7
0
def test_nans():
    apparent_zenith = np.array([10, np.nan, 10])
    apparent_azimuth = np.array([180, 180, np.nan])
    with np.errstate(invalid='ignore'):
        tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                           axis_tilt=0, axis_azimuth=0,
                                           max_angle=90, backtrack=True,
                                           gcr=2.0/7.0)
    expect = {'tracker_theta': np.array([0, nan, nan]),
              'aoi': np.array([10, nan, nan]),
              'surface_azimuth': np.array([90, nan, nan]),
              'surface_tilt': np.array([0, nan, nan])}
    for k, v in expect.items():
        assert_allclose(tracker_data[k], v)

    # repeat with Series because nans can differ
    apparent_zenith = pd.Series(apparent_zenith)
    apparent_azimuth = pd.Series(apparent_azimuth)
    with np.errstate(invalid='ignore'):
        tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                           axis_tilt=0, axis_azimuth=0,
                                           max_angle=90, backtrack=True,
                                           gcr=2.0/7.0)
    expect = pd.DataFrame(np.array(
        [[ 0., 10., 90.,  0.],
         [nan, nan, nan, nan],
         [nan, nan, nan, nan]]),
        columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
    assert_frame_equal(tracker_data, expect)
예제 #8
0
def test_nans():
    apparent_zenith = np.array([10, np.nan, 10])
    apparent_azimuth = np.array([180, 180, np.nan])
    with np.errstate(invalid='ignore'):
        tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                           axis_tilt=0, axis_azimuth=0,
                                           max_angle=90, backtrack=True,
                                           gcr=2.0/7.0)
    expect = {'tracker_theta': np.array([0, nan, nan]),
              'aoi': np.array([10, nan, nan]),
              'surface_azimuth': np.array([90, nan, nan]),
              'surface_tilt': np.array([0, nan, nan])}
    for k, v in expect.items():
        assert_allclose(tracker_data[k], v, atol=1e-7)

    # repeat with Series because nans can differ
    apparent_zenith = pd.Series(apparent_zenith)
    apparent_azimuth = pd.Series(apparent_azimuth)
    with np.errstate(invalid='ignore'):
        tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                           axis_tilt=0, axis_azimuth=0,
                                           max_angle=90, backtrack=True,
                                           gcr=2.0/7.0)
    expect = pd.DataFrame(np.array(
        [[ 0., 10., 90.,  0.],
         [nan, nan, nan, nan],
         [nan, nan, nan, nan]]),
        columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
    assert_frame_equal(tracker_data, expect)
예제 #9
0
def test_slope_aware_backtracking():
    """
    Test validation data set from https://www.nrel.gov/docs/fy20osti/76626.pdf
    """
    index = pd.date_range('2019-01-01T08:00', '2019-01-01T17:00', freq='h')
    index = index.tz_localize('Etc/GMT+5')
    expected_data = pd.DataFrame(index=index,
                                 data=[
                                     (2.404287, 122.79177, -84.440, -10.899),
                                     (11.263058, 133.288729, -72.604, -25.747),
                                     (18.733558, 145.285552, -59.861, -59.861),
                                     (24.109076, 158.939435, -45.578, -45.578),
                                     (26.810735, 173.931802, -28.764, -28.764),
                                     (26.482495, 189.371536, -8.475, -8.475),
                                     (23.170447, 204.13681, 15.120, 15.120),
                                     (17.296785, 217.446538, 39.562, 39.562),
                                     (9.461862, 229.102218, 61.587, 32.339),
                                     (0.524817, 239.330401, 79.530, 5.490),
                                 ],
                                 columns=[
                                     'ApparentElevation', 'SolarAzimuth',
                                     'TrueTracking', 'Backtracking'
                                 ])
    expected_axis_tilt = 9.666
    expected_slope_angle = -2.576
    slope_azimuth, slope_tilt = 180.0, 10.0
    axis_azimuth = 195.0
    axis_tilt = tracking.calc_axis_tilt(slope_azimuth, slope_tilt,
                                        axis_azimuth)
    assert np.isclose(axis_tilt, expected_axis_tilt, rtol=1e-3, atol=1e-3)
    cross_axis_tilt = tracking.calc_cross_axis_tilt(slope_azimuth, slope_tilt,
                                                    axis_azimuth, axis_tilt)
    assert np.isclose(cross_axis_tilt,
                      expected_slope_angle,
                      rtol=1e-3,
                      atol=1e-3)
    sat = tracking.singleaxis(90.0 - expected_data['ApparentElevation'],
                              expected_data['SolarAzimuth'],
                              axis_tilt,
                              axis_azimuth,
                              max_angle=90.0,
                              backtrack=True,
                              gcr=0.5,
                              cross_axis_tilt=cross_axis_tilt)
    assert_series_equal(sat['tracker_theta'],
                        expected_data['Backtracking'].rename('tracker_theta'),
                        check_less_precise=True)
    truetracking = tracking.singleaxis(90.0 -
                                       expected_data['ApparentElevation'],
                                       expected_data['SolarAzimuth'],
                                       axis_tilt,
                                       axis_azimuth,
                                       max_angle=90.0,
                                       backtrack=False,
                                       gcr=0.5,
                                       cross_axis_tilt=cross_axis_tilt)
    assert_series_equal(truetracking['tracker_theta'],
                        expected_data['TrueTracking'].rename('tracker_theta'),
                        check_less_precise=True)
예제 #10
0
def test_arrays_multi():
    apparent_zenith = np.array([[10, 10], [10, 10]])
    apparent_azimuth = np.array([[180, 180], [180, 180]])
    # singleaxis should fail for num dim > 1
    with pytest.raises(ValueError):
        tracking.singleaxis(apparent_zenith, apparent_azimuth,
                            axis_tilt=0, axis_azimuth=0,
                            max_angle=90, backtrack=True,
                            gcr=2.0/7.0)
예제 #11
0
 def time_singleaxis(self):
     with np.errstate(invalid='ignore'):
         tracking.singleaxis(self.solar_position.apparent_zenith,
                             self.solar_position.azimuth,
                             axis_tilt=0,
                             axis_azimuth=0,
                             max_angle=60,
                             backtrack=True,
                             gcr=0.45)
예제 #12
0
def test_slope_aware_backtracking():
    """
    Test validation data set from https://www.nrel.gov/docs/fy20osti/76626.pdf
    """
    expected_data = np.array(
        [('2019-01-01T08:00-0500', 2.404287, 122.79177, -84.440, -10.899),
         ('2019-01-01T09:00-0500', 11.263058, 133.288729, -72.604, -25.747),
         ('2019-01-01T10:00-0500', 18.733558, 145.285552, -59.861, -59.861),
         ('2019-01-01T11:00-0500', 24.109076, 158.939435, -45.578, -45.578),
         ('2019-01-01T12:00-0500', 26.810735, 173.931802, -28.764, -28.764),
         ('2019-01-01T13:00-0500', 26.482495, 189.371536, -8.475, -8.475),
         ('2019-01-01T14:00-0500', 23.170447, 204.13681, 15.120, 15.120),
         ('2019-01-01T15:00-0500', 17.296785, 217.446538, 39.562, 39.562),
         ('2019-01-01T16:00-0500', 9.461862, 229.102218, 61.587, 32.339),
         ('2019-01-01T17:00-0500', 0.524817, 239.330401, 79.530, 5.490)],
        dtype=[('Time', '<M8[h]'), ('ApparentElevation', '<f8'),
               ('SolarAzimuth', '<f8'), ('TrueTracking', '<f8'),
               ('Backtracking', '<f8')])
    expected_axis_tilt = 9.666
    expected_slope_angle = -2.576
    slope_azimuth, slope_tilt = 180.0, 10.0
    axis_azimuth = 195.0
    axis_tilt = tracking.calc_axis_tilt(slope_azimuth, slope_tilt,
                                        axis_azimuth)
    assert np.isclose(axis_tilt, expected_axis_tilt, rtol=1e-3, atol=1e-3)
    cross_axis_tilt = tracking.calc_cross_axis_tilt(slope_azimuth, slope_tilt,
                                                    axis_azimuth, axis_tilt)
    assert np.isclose(cross_axis_tilt,
                      expected_slope_angle,
                      rtol=1e-3,
                      atol=1e-3)
    sat = tracking.singleaxis(90.0 - expected_data['ApparentElevation'],
                              expected_data['SolarAzimuth'],
                              axis_tilt,
                              axis_azimuth,
                              max_angle=90.0,
                              backtrack=True,
                              gcr=0.5,
                              cross_axis_tilt=cross_axis_tilt)
    np.testing.assert_allclose(sat['tracker_theta'],
                               expected_data['Backtracking'],
                               rtol=1e-3,
                               atol=1e-3)
    truetracking = tracking.singleaxis(90.0 -
                                       expected_data['ApparentElevation'],
                                       expected_data['SolarAzimuth'],
                                       axis_tilt,
                                       axis_azimuth,
                                       max_angle=90.0,
                                       backtrack=False,
                                       gcr=0.5,
                                       cross_axis_tilt=cross_axis_tilt)
    np.testing.assert_allclose(truetracking['tracker_theta'],
                               expected_data['TrueTracking'],
                               rtol=1e-3,
                               atol=1e-3)
예제 #13
0
def test_index_mismatch():
    apparent_zenith = pd.Series([30])
    apparent_azimuth = pd.Series([90,180])
    with pytest.raises(ValueError):
        tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                           axis_tilt=0, axis_azimuth=90,
                                           max_angle=90, backtrack=True,
                                           gcr=2.0/7.0)
예제 #14
0
def test_index_mismatch():
    apparent_zenith = pd.Series([30])
    apparent_azimuth = pd.Series([90,180])
    with pytest.raises(ValueError):
        tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                           axis_tilt=0, axis_azimuth=90,
                                           max_angle=90, backtrack=True,
                                           gcr=2.0/7.0)
예제 #15
0
def test_arrays_multi():
    apparent_zenith = np.array([[10, 10], [10, 10]])
    apparent_azimuth = np.array([[180, 180], [180, 180]])
    # singleaxis should fail for num dim > 1
    with pytest.raises(ValueError):
        tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                           axis_tilt=0, axis_azimuth=0,
                                           max_angle=90, backtrack=True,
                                           gcr=2.0/7.0)
예제 #16
0
def test_arrays():
    apparent_zenith = np.array([10])
    apparent_azimuth = np.array([180])
    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)
    assert isinstance(tracker_data, dict)
    expect = {'tracker_theta': 0, 'aoi': 10, 'surface_azimuth': 90,
              'surface_tilt': 0}
    for k, v in expect.items():
        assert_allclose(tracker_data[k], v)
예제 #17
0
def test_scalars():
    apparent_zenith = 10
    apparent_azimuth = 180
    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)
    assert isinstance(tracker_data, dict)
    expect = {'tracker_theta': 0, 'aoi': 10, 'surface_azimuth': 90,
              'surface_tilt': 0}
    for k, v in expect.items():
        assert np.isclose(tracker_data[k], v)
예제 #18
0
def test_arrays():
    apparent_zenith = np.array([10])
    apparent_azimuth = np.array([180])
    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)
    assert isinstance(tracker_data, dict)
    expect = {'tracker_theta': 0, 'aoi': 10, 'surface_azimuth': 90,
              'surface_tilt': 0}
    for k, v in expect.items():
        assert_allclose(tracker_data[k], v, atol=1e-7)
예제 #19
0
def test_low_sun_angles():
    # GH 656, 824
    result = tracking.singleaxis(
        apparent_zenith=80, apparent_azimuth=338, axis_tilt=30,
        axis_azimuth=180, max_angle=60, backtrack=True, gcr=0.35)
    expected = {
        'tracker_theta': np.array([60.0]),
        'aoi': np.array([80.420987]),
        'surface_azimuth': np.array([253.897886]),
        'surface_tilt': np.array([64.341094])}
    for k, v in result.items():
        assert_allclose(expected[k], v)
예제 #20
0
def test_max_angle():
    apparent_zenith = pd.Series([60])
    apparent_azimuth = pd.Series([90])
    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=45, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 15, 'surface_azimuth': 90,
                           'surface_tilt': 45, 'tracker_theta': 45},
                           index=[0], dtype=np.float64)

    assert_frame_equal(expect, tracker_data)
예제 #21
0
def test_horizon_tilted():
    # GH 569
    solar_azimuth = np.array([0, 180, 359])
    solar_zenith = np.full_like(solar_azimuth, 45)
    solar_azimuth = pd.Series(solar_azimuth)
    solar_zenith = pd.Series(solar_zenith)
    out = tracking.singleaxis(solar_zenith, solar_azimuth, axis_tilt=90,
                              axis_azimuth=180, backtrack=False, max_angle=180)
    expected = pd.DataFrame(np.array(
        [[ 180.,  45.,   0.,  90.],
         [   0.,  45., 180.,  90.],
         [ 179.,  45., 359.,  90.]]),
        columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
    assert_frame_equal(out, expected)
예제 #22
0
    def get_orientation(self, solar_zenith, solar_azimuth):
        # Different trackers update at different rates; in this example we'll
        # assume a relatively slow update interval of 15 minutes to make the
        # effect more visually apparent.
        zenith_subset = solar_zenith.resample('15min').first()
        azimuth_subset = solar_azimuth.resample('15min').first()

        tracking_data_15min = tracking.singleaxis(
            zenith_subset, azimuth_subset, self.axis_tilt, self.axis_azimuth,
            self.max_angle, self.backtrack, self.gcr, self.cross_axis_tilt)
        # propagate the 15-minute positions to 1-minute stair-stepped values:
        tracking_data_1min = tracking_data_15min.reindex(solar_zenith.index,
                                                         method='ffill')
        return tracking_data_1min
예제 #23
0
def test_max_angle():
    apparent_zenith = pd.Series([60])
    apparent_azimuth = pd.Series([90])
    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=45, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'aoi': 15, 'surface_azimuth': 90,
                           'surface_tilt': 45, 'tracker_theta': 45},
                           index=[0], dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)
예제 #24
0
def test_horizon_tilted():
    # GH 569
    solar_azimuth = np.array([0, 180, 359])
    solar_zenith = np.full_like(solar_azimuth, 45)
    solar_azimuth = pd.Series(solar_azimuth)
    solar_zenith = pd.Series(solar_zenith)
    out = tracking.singleaxis(solar_zenith, solar_azimuth, axis_tilt=90,
                              axis_azimuth=180, backtrack=False, max_angle=180)
    expected = pd.DataFrame(np.array(
        [[-180.,  45.,   0.,  90.],
         [   0.,  45., 180.,  90.],
         [ 179.,  45., 359.,  90.]]),
        columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
    assert_frame_equal(out, expected)
예제 #25
0
def test_solar_noon():
    index = pd.date_range(start='20180701T1200', freq='1s', periods=1)
    apparent_zenith = pd.Series([10], index=index)
    apparent_azimuth = pd.Series([180], index=index)
    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'tracker_theta': 0, 'aoi': 10,
                           'surface_azimuth': 90, 'surface_tilt': 0},
                          index=index, dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)
예제 #26
0
def test_solar_noon():
    index = pd.date_range(start='20180701T1200', freq='1s', periods=1)
    apparent_zenith = pd.Series([10], index=index)
    apparent_azimuth = pd.Series([180], index=index)
    tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
                                       axis_tilt=0, axis_azimuth=0,
                                       max_angle=90, backtrack=True,
                                       gcr=2.0/7.0)

    expect = pd.DataFrame({'tracker_theta': 0, 'aoi': 10,
                           'surface_azimuth': 90, 'surface_tilt': 0},
                          index=index, dtype=np.float64)
    expect = expect[SINGLEAXIS_COL_ORDER]

    assert_frame_equal(expect, tracker_data)
예제 #27
0
def test_horizon_flat():
    # GH 569
    solar_azimuth = np.array([0, 180, 359])
    solar_zenith = np.array([100, 45, 100])
    solar_azimuth = pd.Series(solar_azimuth)
    solar_zenith = pd.Series(solar_zenith)
    # depending on platform and numpy versions this will generate
    # RuntimeWarning: invalid value encountered in > < >=
    out = tracking.singleaxis(solar_zenith, solar_azimuth, axis_tilt=0,
                              axis_azimuth=180, backtrack=False, max_angle=180)
    expected = pd.DataFrame(np.array(
        [[ nan,  nan,  nan,  nan],
         [  0.,  45., 270.,   0.],
         [ nan,  nan,  nan,  nan]]),
        columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
    assert_frame_equal(out, expected)
예제 #28
0
def test_horizon_flat():
    # GH 569
    solar_azimuth = np.array([0, 180, 359])
    solar_zenith = np.array([100, 45, 100])
    solar_azimuth = pd.Series(solar_azimuth)
    solar_zenith = pd.Series(solar_zenith)
    # depending on platform and numpy versions this will generate
    # RuntimeWarning: invalid value encountered in > < >=
    out = tracking.singleaxis(solar_zenith, solar_azimuth, axis_tilt=0,
                              axis_azimuth=180, backtrack=False, max_angle=180)
    expected = pd.DataFrame(np.array(
        [[ nan,  nan,  nan,  nan],
         [  0.,  45., 270.,   0.],
         [ nan,  nan,  nan,  nan]]),
        columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
    assert_frame_equal(out, expected)
예제 #29
0
def test_low_sun_angles():
    # GH 656
    result = tracking.singleaxis(apparent_zenith=80,
                                 apparent_azimuth=338,
                                 axis_tilt=30,
                                 axis_azimuth=180,
                                 max_angle=60,
                                 backtrack=True,
                                 gcr=0.35)
    expected = {
        'tracker_theta': np.array([-50.31051385]),
        'aoi': np.array([61.35300178]),
        'surface_azimuth': np.array([112.53615425]),
        'surface_tilt': np.array([56.42233095])
    }
    for k, v in result.items():
        assert_allclose(expected[k], v)
예제 #30
0
def test_calc_axis_tilt():
    # expected values
    expected_axis_tilt = 2.239  # [degrees]
    expected_side_slope = 9.86649274360294  # [degrees]
    expected = DATA_DIR / 'singleaxis_tracker_wslope.csv'
    expected = pd.read_csv(expected, index_col='timestamp', parse_dates=True)
    # solar positions
    starttime = '2017-01-01T00:30:00-0300'
    stoptime = '2017-12-31T23:59:59-0300'
    lat, lon = -27.597300, -48.549610
    times = pd.DatetimeIndex(pd.date_range(starttime, stoptime, freq='H'))
    solpos = pvlib.solarposition.get_solarposition(times, lat, lon)
    # singleaxis tracker w/slope data
    slope_azimuth, slope_tilt = 77.34, 10.1149
    axis_azimuth = 0.0
    max_angle = 75.0
    # Note: GCR is relative to horizontal distance between rows
    gcr = 0.33292759  # GCR = length / horizontal_pitch = 1.64 / 5 / cos(9.86)
    # calculate tracker axis zenith
    axis_tilt = tracking.calc_axis_tilt(slope_azimuth,
                                        slope_tilt,
                                        axis_azimuth=axis_azimuth)
    assert np.isclose(axis_tilt, expected_axis_tilt)
    # calculate cross-axis tilt and relative rotation
    cross_axis_tilt = tracking.calc_cross_axis_tilt(slope_azimuth, slope_tilt,
                                                    axis_azimuth, axis_tilt)
    assert np.isclose(cross_axis_tilt, expected_side_slope)
    sat = tracking.singleaxis(solpos.apparent_zenith,
                              solpos.azimuth,
                              axis_tilt,
                              axis_azimuth,
                              max_angle,
                              backtrack=True,
                              gcr=gcr,
                              cross_axis_tilt=cross_axis_tilt)
    np.testing.assert_allclose(sat['tracker_theta'],
                               expected['tracker_theta'],
                               atol=1e-7)
    np.testing.assert_allclose(sat['aoi'], expected['aoi'], atol=1e-7)
    np.testing.assert_allclose(sat['surface_azimuth'],
                               expected['surface_azimuth'],
                               atol=1e-7)
    np.testing.assert_allclose(sat['surface_tilt'],
                               expected['surface_tilt'],
                               atol=1e-7)
예제 #31
0
import matplotlib.pyplot as plt

tz = 'US/Eastern'
lat, lon = 40, -80

times = pd.date_range('2019-01-01',
                      '2019-01-02',
                      closed='left',
                      freq='5min',
                      tz=tz)
solpos = solarposition.get_solarposition(times, lat, lon)

truetracking_angles = tracking.singleaxis(
    apparent_zenith=solpos['apparent_zenith'],
    apparent_azimuth=solpos['azimuth'],
    axis_tilt=0,
    axis_azimuth=180,
    max_angle=90,
    backtrack=False,  # for true-tracking
    gcr=0.5)  # irrelevant for true-tracking

truetracking_position = truetracking_angles['tracker_theta'].fillna(0)
truetracking_position.plot(title='Truetracking Curve')

plt.show()

#%%
# Backtracking
# -------------
#
# Because truetracking yields steep tilt angle in morning and afternoon, it
# will cause row to row shading as the shadows from adjacent rows fall on each
df_monthly = pd.DataFrame()

# fixed-tilt:
for tilt in range(0, 50, 10):
    # we will hardcode azimuth=180 (south) for all fixed-tilt cases
    poa_irradiance = calculate_poa(tmy, solar_position, tilt, 180)
    column_name = "FT-{}".format(tilt)
    # TMYs are hourly, so we can just sum up irradiance [W/m^2] to get
    # insolation [Wh/m^2]:
    df_monthly[column_name] = poa_irradiance.resample('m').sum()

# single-axis tracking:
orientation = tracking.singleaxis(
    solar_position['apparent_zenith'],
    solar_position['azimuth'],
    axis_tilt=0,  # flat array
    axis_azimuth=180,  # south-facing azimuth
    max_angle=60,  # a common maximum rotation
    backtrack=True,  # backtrack for a c-Si array
    gcr=0.4)  # a common ground coverage ratio

poa_irradiance = calculate_poa(tmy, solar_position,
                               orientation['surface_tilt'],
                               orientation['surface_azimuth'])
df_monthly['SAT-0.4'] = poa_irradiance.resample('m').sum()

# calculate the percent difference from GHI
ghi_monthly = tmy['GHI'].resample('m').sum()
df_monthly = 100 * (df_monthly.divide(ghi_monthly, axis=0) - 1)

df_monthly.plot()
plt.xlabel('Month of Year')
예제 #33
0
def smarts_spectrum_with_single_axis_tracker(time_range,
                                             cache_1='cache1.h5',
                                             cache_2='cache2.h5',
                                             force_restart=False,
                                             norm_2pass=True):
    """

    Generate spectrum with single axis tracker

    :param time_range: a datetime-like array
    :param cache_1:
    :param cache_2:
    :param force_restart:
    :param norm_2pass:
    :return:
    """

    if force_restart == False and os.path.exists(cache_2) == True:
        print("Load data from cache.")
        df = pd.read_hdf(cache_2, key='spec_df')
        out_df = pd.read_hdf(cache_2, key='param_df')
        return df, out_df

    # Run the first pass to calculate the solar position
    df, out_df = get_clear_sky(time_range, extend_dict={'TILT': -999})
    df.to_hdf(cache_1, key='spec_df', mode='a')
    out_df.to_hdf(cache_1, key='param_df', mode='a')

    tracker_angle = singleaxis(apparent_azimuth=out_df['azimuth'],
                               apparent_zenith=out_df['zenith'],
                               backtrack=False)

    # Add tracker angle into the parameter datatframe
    out_df = pd.concat([out_df, tracker_angle], axis=1)

    # Rename the tracker azimuth and tilt in order to feed them into 2nd pass SMARTS
    out_df = out_df.rename(index=str,
                           columns={
                               "surface_azimuth": "WAZIM",
                               "surface_tilt": "TILT"
                           })

    # Do the second pass to calculate the output spectrum by using single axis tracker

    df, n_out_df = get_clear_sky(time_range,
                                 extend_df=out_df[['TILT', 'WAZIM']])

    # Renormalize the direct normal incidence
    if norm_2pass == True:
        n_out_df['direct_norm_factor'] = n_out_df['direct_tilt'] / n_out_df[
            'direct_normal']
        df = pd.merge(left=df,
                      right=n_out_df,
                      left_index=True,
                      right_index=True)
        df['BEAM_NORMAL'] = df['BEAM_NORMAL'] * df['direct_norm_factor']

    df.to_hdf(cache_2, key='spec_df', mode='a')
    n_out_df.to_hdf(cache_2, key='param_df', mode='a')

    return df, n_out_df
lat, lon = 40, -80
gcr = 0.4

# calculate the solar position
times = pd.date_range('2019-01-01 06:00', '2019-01-01 18:00', closed='left',
                      freq='1min', tz=tz)
solpos = solarposition.get_solarposition(times, lat, lon)

# compare the backtracking angle at various terrain slopes
fig, ax = plt.subplots()
for cross_axis_tilt in [0, 5, 10]:
    tracker_data = tracking.singleaxis(
        apparent_zenith=solpos['apparent_zenith'],
        apparent_azimuth=solpos['azimuth'],
        axis_tilt=0,  # flat because the axis is perpendicular to the slope
        axis_azimuth=180,  # N-S axis, azimuth facing south
        max_angle=90,
        backtrack=True,
        gcr=gcr,
        cross_axis_tilt=cross_axis_tilt)

    # tracker rotation is undefined at night
    backtracking_position = tracker_data['tracker_theta'].fillna(0)
    label = 'cross-axis tilt: {}°'.format(cross_axis_tilt)
    backtracking_position.plot(label=label, ax=ax)

plt.legend()
plt.title('Backtracking Curves')
plt.show()

# %%
예제 #35
0
def find_clearsky_poa(df,
                      lat,
                      lon,
                      irradiance_poa_key='irradiance_poa_o_###',
                      mounting='fixed',
                      tilt=0,
                      azimuth=180,
                      altitude=0):
    loc = Location(lat, lon, altitude=altitude)

    CS = loc.get_clearsky(df.index)

    df['csghi'] = CS.ghi
    df['csdhi'] = CS.dhi
    df['csdni'] = CS.dni

    if mounting.lower() == "fixed":
        sun = get_solarposition(df.index, lat, lon)

        fixedpoa = get_total_irradiance(tilt, azimuth, sun.zenith, sun.azimuth,
                                        CS.dni, CS.ghi, CS.dhi)

        df['cspoa'] = fixedpoa.poa_global

    if mounting.lower() == "tracking":
        sun = get_solarposition(df.index, lat, lon)

        # default to axis_tilt=0 and axis_azimuth=180

        tracker_data = singleaxis(sun.apparent_zenith,
                                  sun.azimuth,
                                  axis_tilt=tilt,
                                  axis_azimuth=azimuth,
                                  max_angle=50,
                                  backtrack=True,
                                  gcr=0.35)

        track = get_total_irradiance(tracker_data['surface_tilt'],
                                     tracker_data['surface_azimuth'],
                                     sun.zenith, sun.azimuth, CS.dni, CS.ghi,
                                     CS.dhi)

        df['cspoa'] = track.poa_global

    # the following code is assuming clear sky poa has been generated per pvlib, aligned in the same
    # datetime index, and daylight savings or any time shifts were previously corrected
    # the inputs below were tuned for POA at a 15 minute frequency
    # note that detect_clearsky has a scaling factor but I still got slightly different results when I scaled measured poa first

    df['poa'] = df[irradiance_poa_key] / df[irradiance_poa_key].quantile(
        0.98) * df.cspoa.quantile(0.98)

    # inputs for detect_clearsky

    measured = df.poa.copy()
    clear = df.cspoa.copy()
    dur = 60
    lower_line_length = -41.416
    upper_line_length = 77.789
    var_diff = .00745
    mean_diff = 80
    max_diff = 90
    slope_dev = 3

    is_clear_results = detect_clearsky(measured.values,
                                       clear.values,
                                       df.index,
                                       dur,
                                       mean_diff,
                                       max_diff,
                                       lower_line_length,
                                       upper_line_length,
                                       var_diff,
                                       slope_dev,
                                       return_components=True)

    clearSeries = pd.Series(index=df.index, data=is_clear_results[0])

    clearSeries = clearSeries.reindex(index=df.index, method='ffill', limit=3)

    return clearSeries
예제 #36
0
times = pd.date_range('2021-06-21', '2021-06-22', freq='1T', tz=tz)

# create location object and get clearsky data
site_location = location.Location(lat, lon, tz=tz, name='Greensboro, NC')
cs = site_location.get_clearsky(times)

# get solar position data
solar_position = site_location.get_solarposition(times)

# set ground coverage ratio and max_angle to
# pull orientation data for a single-axis tracker
gcr = 0.35
max_phi = 60
orientation = tracking.singleaxis(solar_position['apparent_zenith'],
                                  solar_position['azimuth'],
                                  max_angle=max_phi,
                                  backtrack=True,
                                  gcr=gcr)

# set axis_azimuth, albedo, pvrow width and height, and use
# the pvfactors engine for both front and rear-side absorbed irradiance
axis_azimuth = 180
pvrow_height = 3
pvrow_width = 4
albedo = 0.2

# explicity simulate on pvarray with 3 rows, with sensor placed in middle row
# users may select different values depending on needs
irrad = pvfactors_timeseries(solar_position['azimuth'],
                             solar_position['apparent_zenith'],
                             orientation['surface_azimuth'],
예제 #37
0
# Compute the diffuse irradiance on the panel, from the sky:
S_d_sky = irradiance.klucher(surface_tilt, surface_azimuth, I_d_hor, I_hor,
                             ephem_data['zenith'], ephem_data['azimuth'])

# Compute the angles between the panel and the sun:
aoi = irradiance.aoi(surface_tilt, surface_azimuth, ephem_data['zenith'],
                     ephem_data['azimuth'])

# Compute the global irradiance on the panel:
S = irradiance.globalinplane(aoi, DNI, S_d_sky, S_d_reflect)

# Second case: with tracking (axis is supposed to be north-south):

S_track = tracking.singleaxis(ephem_data['apparent_zenith'],
                              ephem_data['azimuth'],
                              axis_tilt=0,
                              axis_azimuth=0,
                              max_angle=360,
                              backtrack=True)

S['Direct with tracking'] = DNI * np.cos(np.radians(S_track.aoi))

S = S.fillna(0)
S.plot()
#S.to_excel('data/incidentPV.xlsx')

# Adding temperature to the dataframe:
S['T'] = T

# print S with w 15min time resolution:
index15 = pd.DatetimeIndex(start='2015-01-01 00:00',
                           end='2015-12-31 23:59:00',
예제 #38
0
sp_df = pd.DataFrame()
for sl in siteLat:
    sp_df = sp.get_solarposition(time = dateTimeSpanUTC,
                                 latitude = sl, longitude = siteLong, 
                                 altitude = siteElev, 
                                 temperature = aveTemp)
    # convert the solar position data index back to local timestamp
    sp_df.index = dateTimeSpan
    solPos.append(sp_df)
    
# create dataframes for tracking angle using pvlib
trackAngl = []
tr_df = pd.DataFrame()
for s in solPos:
    tr_df = trk.singleaxis(s['apparent_zenith'], s['azimuth'], 
                           axis_tilt = 0, axis_azimuth = 0, max_angle = rom,
                           backtrack = True, gcr = gcRatio)
    tr_df['tracker_theta'] = -1.0 * tr_df['tracker_theta']
    trackAngl.append(tr_df)
    


trdiff_ls = []
durmx_ls = []
colnames = ['btmdur', 'lmdur', 'trdur', 'ladur', 'btadur', 'mxdifftime', 'mxdiffdur']
si = 0
for tr in trackAngl:
    # remove NA's from trackAngl
    tr.dropna(inplace = True)
    
    # trdiff is the delta between data points