<jupyter_start><jupyter_text>Perform energy yield assessment (EYA)-operational assessment (OA) gap analysisThis notebook will explore the use of the energy yield assessment (EYA) gap analysis method in OpenOA. This method attributes differences in an EYA-estimate and an operational assessment (OA) estimate of annual energy production (AEP; or net energy, P50). Differences in availability loss estimates, electrical loss estimates, and turbine ideal energy estimates are analyzed. The latter metric incorporates many aspects of an EYA, including the wind resource estimate, wake loss estimate, turbine performance, and blade degradation. The gap analysis is based on comparing the following three key metrics:1. Availability loss2. Electrical loss3. Sum of turbine ideal energy        Here turbine ideal energy is defined as the energy produced during 'normal' or 'ideal' turbine operation, i.e., no downtime or considerable underperformance events. This value encompasses several different aspects of an EYA (wind resource estimate, wake losses, turbine performance, and blade degradation) and in most casesshould have the largest impact in a gap analysis relative to the first two metrics.    This gap analysis method is fairly straighforward. Relevant EYA and OA metrics are passed in when definingthe class, differences in EYA estimates and OA results are calculated, and then a 'waterfall' plot is createdshowing the differences between the EYA and OA-estimated AEP values and how they are linked from differences in the three key metrics.    Waterfall plot code was taken and modified from the following post: https://pbpython.com/waterfall-chart.html<jupyter_code># Import required packages
from project_ENGIE import Project_Engie
from operational_analysis.methods import plant_analysis
from operational_analysis.methods import turbine_long_term_gross_energy
from operational_analysis.methods import electrical_losses
from operational_analysis.methods import eya_gap_analysis
# Load plant object and process plant data
project = Project_Engie('./data/la_haute_borne')
project.prepare()<jupyter_output>INFO:project_ENGIE:Loading SCADA data
INFO:operational_analysis.types.timeseries_table:Loading name:la-haute-borne-data-2014-2015
INFO:project_ENGIE:SCADA data loaded
INFO:project_ENGIE:Timestamp QC and conversion to UTC
INFO:project_ENGIE:Correcting for out of range of temperature variables
INFO:numexpr.utils:NumExpr defaulting to 8 threads.
INFO:project_ENGIE:Flagging unresponsive sensors
INFO:project_ENGIE:Converting field names to IEC 61400-25 standard
INFO:operational_analysis.types.timeseries_table:Loading name:plant_data
INFO:operational_analysis.types.timeseries_table:Loading name:plant_data
INFO:operational_analysis.types.timeseries_table:Loading name:merra2_la_haute_borne
INFO:operational_analysis.types.timeseries_table:Loading name:era5_wind_la_haute_borne<jupyter_text>Calculate AEP, TIE, and electrical losses from operational dataThe first step is to calculate annual energy production (AEP) for the wind farm (Example 02), turbine ideal energy (TIE) for the wind farm (Example 03) and calculate electrical losses (Example 04). Please refer to detailed documentation of these methods in the previous example notebooks.<jupyter_code># Calculate AEP
pa = plant_analysis.MonteCarloAEP(project, reanal_products = ['era5', 'merra2'])
pa.run(num_sim=20000, reanal_subset=['era5', 'merra2'])
# Calculate TIE
ta = turbine_long_term_gross_energy.TurbineLongTermGrossEnergy(project, UQ=False)
ta.run(reanal_subset = ['era5', 'merra2'], 
       max_power_filter = 0.85, 
       wind_bin_thresh = 2.0,
       correction_threshold = 0.90, 
       enable_plotting = False,
       plot_dir = None)
# Calculate electrical losses
el = electrical_losses.ElectricalLosses(project)
el.run()<jupyter_output>INFO:operational_analysis.methods.electrical_losses:Initializing Electrical Losses Object
INFO:operational_analysis.methods.electrical_losses:Note: uncertainty quantification will NOT be performed in the calculation
INFO:operational_analysis.methods.electrical_losses:Processing SCADA data
INFO:operational_analysis.methods.electrical_losses:Processing meter data
INFO:operational_analysis.methods.electrical_losses:Calculating electrical losses
100%|██████████| 1/1 [00:00<00:00, 85.36it/s]<jupyter_text>Now that we've calculated the key operational metrics, we setup some arrays that the gap analysis method needs to run.  Summarize operational results and create EYA data for comparison<jupyter_code># First summarize key operational results
aep = pa.results.aep_GWh.mean()
avail = pa.results.avail_pct.mean()
elec = el._electrical_losses[0][0]
tie = ta._plant_gross[0][0]/1e6

print(aep, avail, elec, tie)
# Define operational data list
oa_list = [aep, avail, elec, tie] 
# AEP (GWh/yr), availability loss (fraction), electrical loss (fraction), turbine ideal energy (GWh/yr)

# Define EYA data list (we are fabricating these values here as an example)
eya_list = [16.46, 20., 0.04, 0.014, 0.037, 0.011, 0.087] 
# AEP (GWh/yr), Gross energy (GWh/yr), availability loss (fraction), electrical loss (fraction), turbine performance loss (fraction)
# blade degradation loss (fraction), wake loss (fraction)<jupyter_output><empty_output><jupyter_text>Perform gap analysisNow that we have the data we need, we first create a gap analysis object<jupyter_code>gap_anal = eya_gap_analysis.EYAGapAnalysis(plant = 'La Haute Borne', eya_estimates = eya_list, oa_results = oa_list)<jupyter_output>INFO:operational_analysis.methods.eya_gap_analysis:Initializing EYA Gap Analysis Object<jupyter_text>Now we run the analysis, which by default outputs a waterfall plot showing how the gap between EYA-reported AEP and plant-measured AEP can be explained:<jupyter_code>gap_anal.run()<jupyter_output>INFO:operational_analysis.methods.eya_gap_analysis:Gap analysis complete
{'fraction_non_alphanumeric': 0.06874255572571039, 'fraction_numerical': 0.01633486472690148, 'mean_word_length': 6.6337662337662335, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 17, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '339453', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1769, 'n_tokens_neox': 1617, 'n_words': 584, 'path': 'examples/05_eya_gap_analysis.ipynb', 'repo_name': 'NREL/open-oa', 'size': '5877'}