Exemplo n.º 1
0
def test_geometric_clipping_missing_data(freq, power_pvwatts):
    power = power_pvwatts.resample(freq).asfreq()
    power.loc[power.between_time('09:00', '10:30').index] = np.nan
    power.loc[power.between_time('12:15', '12:45').index] = np.nan
    power.dropna(inplace=True)
    with pytest.raises(ValueError,
                       match="Cannot infer frequency of `ac_power`. "
                             "Please resample or pass `freq`."):
        clipping.geometric(power)
    assert not clipping.geometric(power, freq=freq).any()
Exemplo n.º 2
0
def test_geometric_index_not_sorted():
    power = pd.Series(
        [1, 2, 3],
        index=pd.DatetimeIndex(
            ['20200201 0700', '20200201 0630', '20200201 0730']
        )
    )
    with pytest.raises(ValueError,
                       match=r"Index must be monotonically increasing\."):
        clipping.geometric(power, freq='30T')
Exemplo n.º 3
0
def test_geometric_clipping_correct(power_pvwatts, freq):
    power = power_pvwatts.resample(freq).asfreq()
    clipped = clipping.geometric(power)
    expected = power == power.max()
    if freq == '5T':
        assert np.allclose(power[clipped], power.max(), atol=0.5)
    else:
        assert_series_equal(clipped, expected)
Exemplo n.º 4
0
def test_geometric_clipping_midday_clouds(power_pvwatts):
    power = power_pvwatts.resample('15T').asfreq()
    power.loc[power.between_time(
        start_time='17:30', end_time='19:30',
        include_start=True, include_end=True
    ).index] = list(range(30, 39)) * 31
    clipped = clipping.geometric(power)
    expected = power == power.max()
    assert_series_equal(clipped, expected)
Exemplo n.º 5
0
    def find_clipped_times_pva(self):

        # Make normalized power column.
        self.df['power_dc'] = self.df[self.voltage_dc_key] * self.df[
            self.
            current_dc_key] / self.modules_per_string / self.parallel_strings

        # Find clipped times.
        self.df['clipped_times'] = clipping.geometric(
            ac_power=self.df['power_dc'], freq=self.freq)
Exemplo n.º 6
0
def classify_operating_mode(voltage,
                            current,
                            power_clip=np.inf,
                            method='fraction',
                            clipped_times=None,
                            freq='15min'):
    """

    Parameters
    ----------
    voltage
    currente
    method

    Returns
    -------
    operating_cls : array

        Array of classifications of each time stamp.

        0: System at maximum power point.
        1: System at open circuit conditions.
        2: Clipped or curtailed. DC operating point is not necessarily at MPP.
        -1: No power/inverter off
        -2: Other
    """

    cls = np.zeros(np.shape(voltage)) - 1

    # Inverter on
    cls[np.logical_and(
        voltage > voltage.max() * 0.01,
        current > current.max() * 0.01,
    )] = 0

    # Nighttime, low voltage and irradiance (inverter off)
    cls[voltage < voltage.max() * 0.01] = -1

    # Open circuit condition
    cls[np.logical_and(current < current.max() * 0.01,
                       voltage > voltage.max() * 0.01)] = 1

    if clipped_times is None:
        clipped_times = clipping.geometric(ac_power=voltage * current,
                                           freq=freq)

    # Clipped data.
    cls[clipped_times] = 2

    return cls
Exemplo n.º 7
0
def test_geometric_clipping_window_overrides_tracking(power_pvwatts):
    power = power_pvwatts.resample('15T').asfreq()
    clipped = clipping.geometric(power, tracking=True)
    assert clipped.any()
    clipped_override = clipping.geometric(power, tracking=True, window=24)
    assert not clipped_override.any()
Exemplo n.º 8
0
def test_geometric_clipping_tracking(power_pvwatts):
    power = power_pvwatts.resample('15T').asfreq()
    clipped = clipping.geometric(power)
    assert clipped.any()
    clipped = clipping.geometric(power, tracking=True)
    assert not clipped.any()
Exemplo n.º 9
0
def test_geometric_clipping_window(power_pvwatts):
    power = power_pvwatts.resample('15T').asfreq()
    clipped = clipping.geometric(power)
    assert clipped.any()
    clipped_window = clipping.geometric(power, window=24)
    assert not clipped_window.any()
Exemplo n.º 10
0
def test_geometric_clipping(power_pvwatts, freq):
    clipped = clipping.geometric(power_pvwatts.resample(freq).asfreq())
    assert clipped.any()
Exemplo n.º 11
0
freq = "15T"

data['value_normalized'].plot()
data.loc[data['label'], 'value_normalized'].plot(ls='', marker='o')
plt.legend(labels=["AC Power", "Labeled Clipping"],
           title="Clipped")
plt.xticks(rotation=20)
plt.xlabel("Date")
plt.ylabel("Normalized AC Power")
plt.tight_layout()
plt.show()

# %%
# Now, use :py:func:`pvanalytics.features.clipping.geometric` to identify
# clipping periods in the time series. Re-plot the data subset with this mask.
predicted_clipping_mask = geometric(ac_power=data['value_normalized'],
                                    freq=freq)
data['value_normalized'].plot()
data.loc[predicted_clipping_mask, 'value_normalized'].plot(ls='', marker='o')
plt.legend(labels=["AC Power", "Detected Clipping"],
           title="Clipped")
plt.xticks(rotation=20)
plt.xlabel("Date")
plt.ylabel("Normalized AC Power")
plt.tight_layout()
plt.show()


# %%
# Compare the filter results to the ground-truth labeled data side-by-side,
# and generate an accuracy metric.
acc = 100 * np.sum(np.equal(data.label,