Skip to content

Commit

Permalink
Enhancement/update rated power in tie (#268)
Browse files Browse the repository at this point in the history
* changing turbine capacity to rated power from asset table in TIE

* rerunning example 3 notebook

* update plantdata TIE test for asset table

* remove unused prepare_scada method in TIE

* update TIE test results

* updating TIE example notebook 3

* updating changelog for TIE power curve filtering change

* rerun schema generation

---------

Co-authored-by: RHammond2 <[email protected]>
  • Loading branch information
ejsimley and RHammond2 authored Feb 9, 2024
1 parent a117550 commit 4fbdfd1
Show file tree
Hide file tree
Showing 25 changed files with 258 additions and 399 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ All notable changes to this project will be documented in this file. If you make
results for the TIE and wake loss regression tests.
- `openoa.utils.timeseries.gap_fill_data_frame()` now returns the original data if there is no data
to fill in, avoiding a Pandas `concat` deprecation warning about pending behavioral changes.
- The turbine capacity value used for power curve filtering in `TurbineLongTermGrossEnergy` is
changed to the rated power from the asset table instead of the maximum power from SCADA. This
makes the power curve filtering more robust to turbine power outliers above rated power.

## [3.0.1 - 2023-12-22]

Expand Down
96 changes: 15 additions & 81 deletions examples/03_turbine_ideal_energy.ipynb

Large diffs are not rendered by default.

61 changes: 15 additions & 46 deletions openoa/analysis/turbine_long_term_gross_energy.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,45 +310,6 @@ def setup_inputs(self) -> None:

self._inputs = pd.DataFrame(inputs)

@logged_method_call
def prepare_scada(self) -> None:
"""
Performs the following manipulations:
1. Creates a copy of the SCADA data
2. Sorts it by turbine asset_id, then timestamp (the two index columns)
3. Drops any rows that don't have any windspeed or energy data
4. Flags windspeed values outside the range [0, 40]
5. Flags windspeed values that have stayed the same for at least 3 straight readings
6. Flags power values outside the range [0, turbine capacity]
7. Flags windspeed and power values that don't mutually coincide within a reasonable range
8. Combine the flags using an "or" combination to be a new column in scada: "valid"
"""
self.scada = (
self.plant.scada.swaplevel().sort_index().dropna(subset=["WMET_HorWdSpd", "WTUR_SupWh"])
)
turbine_capacity = self.scada.groupby(level="asset_id").max()["WTUR_W"]
flag_range = filters.range_flag(self.scada.loc[:, "WMET_HorWdSpd"], below=0, above=40)
flag_frozen = filters.unresponsive_flag(self.scada.loc[:, "WMET_HorWdSpd"], threshold=3)
flag_neg = pd.Series(index=self.scada.index, dtype=bool)
flag_window = pd.Series(index=self.scada.index, dtype=bool)
for t in self.turbine_ids:
ix_turb = self.scada.index.get_level_values("asset_id") == t
flag_neg.loc[ix_turb] = filters.range_flag(
self.scada.loc[ix_turb, "power"], below=0, above=turbine_capacity.loc[t]
)
flag_window.loc[ix_turb] = filters.window_range_flag(
window_col=self.scada.loc[ix_turb, "WMET_HorWdSpd"],
window_start=5.0,
window_end=40,
value_col=self.scada.loc[ix_turb, "WTUR_W"],
value_min=0.02 * turbine_capacity.loc[t],
value_max=1.2 * turbine_capacity.loc[t],
)

flag_final = ~(flag_range | flag_frozen | flag_neg | flag_window).values
self.scada.assign(valid=flag_final)
self.scada.assign(valid_run=flag_final)

def sort_scada_by_turbine(self) -> None:
"""
Sorts the SCADA DataFrame by the asset_id and timestamp index columns, respectively.
Expand All @@ -370,42 +331,50 @@ def filter_turbine_data(self) -> None:
"""
Apply a set of filtering algorithms to the turbine wind speed vs power curve to flag
data not representative of normal turbine operation
Performs the following manipulations:
1. Drops any scada rows that don't have any windspeed or energy data
2. Flags windspeed values outside the range [0, 40]
3. Flags windspeed values that have stayed the same for at least 3 straight readings
4. Flags power values less than 2% of turbine capacity when wind speed above cut-in
5. Flags windspeed and power values that don't mutually coincide within a reasonable range
6. Combine the flags using an "or" combination to be a new column in scada: "flag_final"
"""

dic = self.scada_dict

# Loop through turbines
for t in self.turbine_ids:
scada_df = self.scada_dict[t]
turbine_capacity_real = scada_df.WTUR_W.max()
turbine_capacity = self.plant.asset.loc[t, "rated_power"]

max_bin = (
self._run.max_power_filter * turbine_capacity_real
self._run.max_power_filter * turbine_capacity
) # Set maximum range for using bin-filter

scada_df.dropna(
subset=["WMET_HorWdSpd", "WTUR_SupWh"], inplace=True
) # Drop any data where scada wind speed or energy is NaN

scada_df = scada_df.assign(
flag_neg=filters.range_flag(scada_df.WTUR_W, lower=0, upper=turbine_capacity_real),
flag_neg=filters.range_flag(scada_df.WTUR_W, lower=0, upper=scada_df.WTUR_W.max()),
flag_range=filters.range_flag(scada_df.WMET_HorWdSpd, lower=0, upper=40),
flag_frozen=filters.unresponsive_flag(scada_df.WMET_HorWdSpd, threshold=3),
flag_window=filters.window_range_flag(
window_col=dic[t].loc[:, "WMET_HorWdSpd"],
window_start=5.0,
window_end=40,
value_col=dic[t].loc[:, "WTUR_W"],
value_min=0.02 * turbine_capacity_real,
value_max=1.2 * turbine_capacity_real,
value_min=0.02 * turbine_capacity,
value_max=1.2 * turbine_capacity,
),
flag_bin=filters.bin_filter(
bin_col=dic[t].loc[:, "WTUR_W"],
value_col=dic[t].loc[:, "WMET_HorWdSpd"],
bin_width=0.06 * turbine_capacity_real,
bin_width=0.06 * turbine_capacity,
threshold=self._run.wind_bin_thresh,
center_type="median",
bin_min=np.round(0.01 * turbine_capacity_real),
bin_min=np.round(0.01 * turbine_capacity),
bin_max=np.round(max_bin),
threshold_type="std",
direction="all",
Expand Down
18 changes: 9 additions & 9 deletions openoa/schema/base_electrical_losses_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
"units": "kWh"
},
"frequency": [
"us",
"ns",
"ME",
"W",
"ns",
"D",
"s",
"MS",
"h",
"ms",
"min"
"MS",
"min",
"us",
"s",
"W"
]
},
"scada": {
Expand All @@ -30,13 +30,13 @@
"units": null
},
"frequency": [
"us",
"ns",
"D",
"s",
"h",
"ms",
"min"
"min",
"us",
"s"
]
}
}
14 changes: 7 additions & 7 deletions openoa/schema/base_electrical_losses_schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,26 @@ scada:
dtype: float
units: kW
frequency:
- us
- ns
- D
- s
- h
- ms
- min
- us
- s
meter:
MMTR_SupWh:
name: MMTR_SupWh
dtype: float
units: kWh
frequency:
- us
- ns
- ME
- W
- ns
- D
- s
- MS
- h
- ms
- MS
- min
- us
- s
- W
36 changes: 18 additions & 18 deletions openoa/schema/base_monte_carlo_aep_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@
"units": "kWh"
},
"frequency": [
"us",
"ns",
"ME",
"W",
"ns",
"D",
"s",
"MS",
"h",
"ms",
"min"
"MS",
"min",
"us",
"s",
"W"
]
},
"meter": {
Expand All @@ -30,16 +30,16 @@
"units": "kWh"
},
"frequency": [
"us",
"ns",
"ME",
"W",
"ns",
"D",
"s",
"MS",
"h",
"ms",
"min"
"MS",
"min",
"us",
"s",
"W"
]
},
"reanalysis": {
Expand All @@ -54,16 +54,16 @@
"units": "m/s"
},
"frequency": [
"us",
"ns",
"ME",
"W",
"ns",
"D",
"s",
"MS",
"h",
"ms",
"min"
"MS",
"min",
"us",
"s",
"W"
]
}
}
30 changes: 15 additions & 15 deletions openoa/schema/base_monte_carlo_aep_schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ meter:
dtype: float
units: kWh
frequency:
- us
- ns
- ME
- W
- ns
- D
- s
- MS
- h
- ms
- MS
- min
- us
- s
- W
curtail:
IAVL_ExtPwrDnWh:
name: IAVL_ExtPwrDnWh
Expand All @@ -24,16 +24,16 @@ curtail:
dtype: float
units: kWh
frequency:
- us
- ns
- ME
- W
- ns
- D
- s
- MS
- h
- ms
- MS
- min
- us
- s
- W
reanalysis:
WMETR_HorWdSpd:
name: WMETR_HorWdSpd
Expand All @@ -44,13 +44,13 @@ reanalysis:
dtype: float
units: kg/m^3
frequency:
- us
- ns
- ME
- W
- ns
- D
- s
- MS
- h
- ms
- MS
- min
- us
- s
- W
19 changes: 13 additions & 6 deletions openoa/schema/base_tie_schema.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"asset": {
"rated_power": {
"dtype": "float",
"name": "rated_power",
"units": "kW"
}
},
"reanalysis": {
"WMETR_AirDen": {
"dtype": "float",
Expand All @@ -16,13 +23,13 @@
"units": "m/s"
},
"frequency": [
"us",
"ns",
"D",
"s",
"h",
"ms",
"min"
"min",
"us",
"s"
]
},
"scada": {
Expand All @@ -42,13 +49,13 @@
"units": null
},
"frequency": [
"us",
"ns",
"D",
"s",
"h",
"ms",
"min"
"min",
"us",
"s"
]
}
}
13 changes: 9 additions & 4 deletions openoa/schema/base_tie_schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ scada:
dtype: float
units: m/s
frequency:
- us
- ns
- D
- s
- h
- ms
- min
- us
- s
asset:
rated_power:
name: rated_power
dtype: float
units: kW
reanalysis:
WMETR_HorWdSpd:
name: WMETR_HorWdSpd
Expand All @@ -33,10 +38,10 @@ reanalysis:
dtype: float
units: kg/m^3
frequency:
- us
- ns
- D
- s
- h
- ms
- min
- us
- s
Loading

0 comments on commit 4fbdfd1

Please sign in to comment.