reskit.wind
===========

.. py:module:: reskit.wind


Submodules
----------

.. toctree::
   :maxdepth: 1

   /_readthedocs/reskit/wind/core/index
   /_readthedocs/reskit/wind/economic/index
   /_readthedocs/reskit/wind/workflows/index


Attributes
----------

.. autoapisummary::

   reskit.wind.DATAFOLDER


Classes
-------

.. autoapisummary::

   reskit.wind.PowerCurve
   reskit.wind.WindWorkflowManager
   reskit.wind.WindWorkflowManager


Functions
---------

.. autoapisummary::

   reskit.wind.apply_air_density_adjustment
   reskit.wind.onshore_turbine_from_avg_wind_speed
   reskit.wind.apply_logarithmic_profile_projection
   reskit.wind.roughness_from_clc
   reskit.wind.roughness_from_land_cover_classification
   reskit.wind.roughness_from_land_cover_source
   reskit.wind.roughness_from_levels
   reskit.wind.compute_specific_power
   reskit.wind.alpha_from_levels
   reskit.wind.apply_power_profile_projection
   reskit.wind.TurbineLibrary
   reskit.wind.offshore_turbine_capex
   reskit.wind.onshore_turbine_capex
   reskit.wind.build_ws_correction_function
   reskit.wind.wind_era5_PenaSanchezDunkelWinklerEtAl2025
   reskit.wind.onshore_wind_merra_ryberg2019_europe
   reskit.wind.offshore_wind_merra_caglayan2019
   reskit.wind.onshore_wind_iconlam_2023
   reskit.wind.wind_config
   reskit.wind.wind_era5_2023
   reskit.wind.onshore_wind_era5
   reskit.wind.offshore_wind_era5
   reskit.wind.onshore_wind_era5_pure_2023


Package Contents
----------------

.. py:function:: apply_air_density_adjustment(wind_speed, pressure, temperature, height=0)

   Applies air density corrections to the wind speed values following suggestions by the IEC 61400-12-1:2017 [1].

   :param wind_speed: The wind speed values in m/s.
   :type wind_speed: float or array-like
   :param pressure: Air preassure in Pa.
   :type pressure: float or array-like
   :param temperature: Air temperature in degree Celsius.
   :type temperature: float or array-like
   :param height: The (hub) height of that the air density is going to be adjusted to in m, by default 0
   :type height: float or array-like, optional

   :returns: The air density corrected wind speed in m/s at the given height.
   :rtype: numeric or array-like

   .. rubric:: Notes

   Ideal gas equation applied since it is nearly equivalent to a real-gas equation at humidity = 0, and humidity does not have a significant impact until high temperatures are considered.
   Pressure projection using barometric equation and density correction from assuming equal energy in the wind.

   .. rubric:: References

   [1] International Electrotechnical Commission (ICE). (2017). IEC 61400-12-1:2017 (p. 558). https://webstore.iec.ch/publication/26603


.. py:function:: onshore_turbine_from_avg_wind_speed(wind_speed, constant_rotor_diam=None, base_capacity=None, base_hub_height=None, base_rotor_diam=None, reference_wind_speed=None, min_tip_height=None, min_specific_power=None, max_hub_height=None, tech_year=2050, baseline_turbine_fp=None)

   Suggest onshore turbine design characteristics (capacity, hub height, rotor diameter, specific power) for a 2050 European context based on an average wind speed value.
   The default values and the function's normalization correspond to the baseline turbine design considered by Ryberg et al. [1] for a wind speed equal to 6.7 m/s. See notes.

   :param wind_speed: Local average wind speed close to or at the hub height.
   :type wind_speed: numeric or array_like
   :param constant_rotor_diam: Whether the rotor diameter is maintained constant or not, by default True
   :type constant_rotor_diam: bool, optional
   :param base_capacity: Baseline turbine capacity in kW, by default 4200.
   :type base_capacity: numeric or array_like, optional
   :param base_hub_height: Baseline turbine hub height in m, by default 120.
   :type base_hub_height: numeric or array_like, optional
   :param base_rotor_diam: Baseline turbine rotor diameter in m, by default 136.
   :type base_rotor_diam: numeric or array_like, optional
   :param reference_wind_speed: Average wind speed corresponding to the baseline turbine design, by default 6.7.
   :type reference_wind_speed: numeric, optional
   :param min_tip_height: Minimum distance in m between the lower tip of the blades and the ground, by default 20.
   :type min_tip_height: numeric, optional.
   :param min_specific_power: Minimum specific power allowed in kw/m2, by default 180.
   :type min_specific_power: numeric, optional
   :param max_hub_height: Maximum allowed hub height, any higher optimal hub height will be reduced to this
                          value, by default 200.
   :type max_hub_height: numeric, optional
   :param tech_year: The year defining the baseline turbine design that shall be used.
   :type tech_year: int, optional
   :param baseline_turbine_fp: A json or csv file that contains baseline turbine parameters. Will
                               replace the default data.
   :type baseline_turbine_fp: str, optional

   :returns: Returns a the suggested values of hub height in m, specific power in W/m2, and capacity in kW as dictionary when numeric values are input or as a pandas DataFrame when array-like objects are input.
   :rtype: dict or pandas DataFrame

   .. rubric:: Notes

   The default baseline onshore turbine has 4200 kW capacity, 120m hub height, and 136m rotor diameter [1]

   .. rubric:: References

   [1] David S. Ryberg, Dilara C. Caglayan, Sabrina Schmitt, Jochen Linssen, Detlef Stolten, Martin Robinius - The Future of European Onshore Wind Energy Potential:
   Detailed Distributionand Simulation of Advanced Turbine Designs, Energy, 2019, available at https://www.sciencedirect.com/science/article/abs/pii/S0360544219311818


.. py:function:: apply_logarithmic_profile_projection(measured_wind_speed, measured_height, target_height, roughness, displacement=0, stability=0)

   Estimates wind speeds at a target height based on measured wind speeds values at a known measurement height.
   Estimation is subject to surface roughness, displacement height, and a stability factor.

   :param measured_wind_speed: The input wind speeds in m/s that are going to be adjusted
                               If an array is given with a single dimension, it is assumed to represent timeseries values for a single location
                               If multidimensional array is given, the assumed dimensional context is (time, locations).
   :type measured_wind_speed: numeric or array-like
   :param measured_height: The measurement height in m of the input wind speeds.
                           Must either be a single value, or an array of values with the same length as the "locations" dimension of `measured_wind_speed`
   :type measured_height: numeric or array-like
   :param target_height: The height in m to project each wind speed timeseries to.
                         Must either be a single value, or an array of values with the same length as the "locations" dimension of `measured_wind_speed`
   :type target_height: numeric or array-like
   :param roughness: The roughness value used to project each wind speed timeseries.
                     Must either be a single value, or an array of values with the same length as the "locations" dimension of `measured_wind_speed`
   :type roughness: numeric or array-like
   :param displacement: The displacement value used to project each wind speed timeseries, by default 0.
                        Must either be a single value, or an array of values with the same length as the "locations" dimension of `measured_wind_speed`
   :type displacement: numeric or array-like, optional
   :param stability: The stability value used to project each wind speed timeseries, by default 0.
                     Must either be a single value, or an array of values with the same length as the "locations" dimension of `measured_wind_speed`
   :type stability: numeric or array-like, optional

   :returns: Wind speed values in m/s at target height with of the same dimensions as `measured_wind_speed`.
   :rtype: multidimensional array-like

   .. rubric:: Notes

   Roughness values can be generated by the following functions:
   roughness_from_levels(low_wind_speed, low_height, high_wind_speed, high_height)
   roughness_from_clc(clc_path, loc, window_range)
   roughness_from_land_cover_classification(classification, land_cover_type)
   roughness_from_land_cover_source(source, loc, land_cover_type)


.. py:function:: roughness_from_clc(clc_path, loc, window_range=0)

   Estimates a roughness factor according to suggestions by Silva et al. [1] by the prominent land cover at given locations according to the Corine Land Cover dataset [2].

   :param clc_path: The path to the Corine Land Cover (CLC) raster file on the disk.
                    This function currently only works for CLC versions before 2018.
   :type clc_path: str
   :param loc: The locations for which roughness should be estimated.
               Arguments accepted include: str, OGR point object (must have an SRS within the object, default = 4326 (for Europe)), lat and lon coordinates tuple (lat,lon).
               Refers to https://github.com/FZJ-IEK3-VSA/geokit/blob/master/geokit/core/location.py for more information.
   :type loc: Anything acceptable to geokit.LocationSet
   :param window_range: An extra number of pixels to extract around the indicated locations, by default 0.
                        A window_range = 0 means that only the CLC pixel value for each location is returned. A window_range of 1 means an extra pixel is extracted around each location in all directions. Leading to a 3x3 matrix of roughness values
                        Use this if you need to do some operation on the roughnesses found around the indicated location
   :type window_range: int; optional

   :returns: Roughness lengths factors
             A single float is returned in the event that a single location is specified in `locations`.
             A one-dimensional Numpy array is returned in the event that multiple locations are specified in `locations`.
   :rtype: float or numpy.ndarray

   Sources
   --------
       [1] Silva, J., Ribeiro, C., & Guedes, R. (2007). Roughness length classification of corine land cover classes. European Wind Energy Conference and Exhibition 2007, EWEC 2007.
       [2] Copernicus (European Union’s Earth Observation Programme). (2018). Corine Land Cover (CLC) 2000, Version 2018. Copernicus. http://land.copernicus.eu/pan-european/corine-land-cover/clc-2000/view

   Roughness values [1]
   --------------------

       Continuous urban fabric : 1.2
       Broad-leaved forest : 0.75
       Coniferous-leaved forest : 0.75
       Mixed-leaved forest : 0.75
       Green urban areas : 0.6
       Transitional woodland/shrub : 0.6
       Burnt areas : 0.6
       Discontinuous urban fabric : 0.5
       Construction sites : 0.5
       Industrial or commercial units : 0.5
       Sport and leisure facilities : 0.5
       Port areas : 0.5
       Agro-forestry areas : 0.3
       Complex cultivation patterns : 0.3
       Land principally occupied by agriculture, with significant areas of natural vegetation : 0.3
       Annual crops associated with permanent crops : 0.1
       Fruit trees and berry plantations : 0.1
       Vineyard : 0.1
       Olive groves : 0.1
       Road and rail networks and associated land : 0.075
       Non-irrigated arable land : 0.05
       Permanently irrigated land : 0.05
       Rice fields : 0.05
       Inland marshes : 0.05
       Salt marshes : 0.05
       Sclerophylous vegetation : 0.03
       Moors and heathland : 0.03
       Natural grassland : 0.03
       Pastures : 0.03
       Dump sites : 0.005
       Mineral extraction sites : 0.005
       Airports : 0.005
       Bare rock : 0.005
       Sparsely vegetated areas : 0.005
       Glaciers and perpetual snow : 0.001
       Peatbogs : 0.0005
       Salines : 0.0005
       Intertidal flats : 0.0005
       Beaches, dunes, and sand plains : 0.0003
       Water courses # SUSPICIOUS : 0.001
       Water bodies # SUSPISCIOUS : 0.0005
       Costal lagoons # SUSPISCIOUS : 0.0005
       Estuaries # SUSPISCIOUS : 0.0008
       Sea and ocean # SUSPISCIOUS : 0.0002



.. py:function:: roughness_from_land_cover_classification(classification, land_cover_type='clc')

   Estimates roughness value from land cover classifications

   :param classification: land cover classification
   :type classification: int
   :param land_cover_type: Accepted arguments are 'clc', 'clc-code', 'globCover', 'modis', or 'cci', by default 'clc'
                           'clc': Corine Land Cover (CLC)
                           'clc-code': Corine Land Cover (CLC) codes values
                           'globCover': Global Wind Atlas roughness lengths values
                           'modis': Modis number for "no data" points of Global Wind Atlas (mostly in areas North of 60°)
                           'cci': Climate Change Initiative land cover classification
   :type land_cover_type: str, optional

   :returns: Roughness lengths factors
             A single int is returned in the event that a single location is specified in `locations`.
             A one-dimensional Numpy array is returned in the event that multiple locations are specified in `locations`.
   :rtype: int or numpy.ndarray


.. py:function:: roughness_from_land_cover_source(source, loc, land_cover_type='clc')

   Estimate roughness value from a given land cover raster source

   :param source: The path to the Corine Land Cover raster file on the disk.
   :type source: str
   :param loc: Arguments accepted include: str, OGR point object (must have an SRS within the object, default = 4326 (for Europe)), lat and lon coordinates (tuple (lat,lon)).
               Refers to https://github.com/FZJ-IEK3-VSA/geokit/blob/master/geokit/core/location.py for more information.
   :type loc: Anything acceptable to geokit.LocationSet
   :param land_cover_type: Accepted arguments are 'clc', 'clc-code', 'globCover', 'modis', or 'cci', by default 'clc'
                           'clc': Corine Land Cover (CLC)
                           'clc-code': Corine Land Cover (CLC) codes
                           'globCover': Global Wind Atlas
                           'modis': Modis number for "no data" points of Global Wind Atlas (mostly in areas North of 60°)
                           'cci': Climate Change Initiative land cover classification
   :type land_cover_type: str, optional

   :returns: Roughness lengths factors
             A single int is returned in the event that a single location is specified in `locations`.
             A one-dimensional Numpy array is returned in the event that multiple locations are specified in `locations`.
   :rtype: int or numpy.ndarray


.. py:function:: roughness_from_levels(low_wind_speed, low_height, high_wind_speed, high_height)

   Computes a roughness factor from two windspeed values at two distinct heights.

   :param low_wind_speed: The measured wind speed in m/s at the lower height.
   :type low_wind_speed: numeric or numpy.ndarray
   :param low_height: The lower height in m.
   :type low_height: numeric or numpy.ndarray
   :param high_wind_speed: The measured wind speed in m/s at the higher height.
   :type high_wind_speed: numeric or numpy.ndarray
   :param high_height: The higher height in m.
   :type high_height: numeric or numpy.ndarray

   :returns: Roughness factor
   :rtype: numeric or arrray-like


.. py:class:: PowerCurve(wind_speed, capacity_factor)

   Creates a wind turbine's power curve represented by a set of (wind-speed,capacity-factor) pairs.

   Initialization:

   :param wind_speed: The wind speeds values
   :type wind_speed: array-like
   :param capacity_factor: The corresponding capacity factor
   :type capacity_factor: array-like

   :rtype: PowerCurve object


   .. py:attribute:: wind_speed


   .. py:attribute:: capacity_factor


   .. py:method:: __str__()


   .. py:method:: _repr_svg_()


   .. py:method:: from_specific_power(specific_power, cutout=25)
      :staticmethod:


      Creates a synthetic wind turbine power curve based on observed relationships between turbine specific power and known power curves according to Ryberg et al. [1].

      :param specific_power: Turbines's specific power in m/s
      :type specific_power: float
      :param cutout: Cut out wind speed in m/s, by default 25
      :type cutout: int, optional

      :returns: * *PowerCurve*
                * *Sources*
                * *-------*
                * **[1] Ryberg, D. S., Caglayan, D. G., Schmitt, S., Linßen, J., Stolten, D., & Robinius, M. (2019). The future of European onshore wind energy potential** (*Detailed distribution and simulation of advanced turbine designs. Energy. https://doi.org/10.1016/j.energy.2019.06.052*)



   .. py:method:: from_capacity_and_rotor_diam(capacity, rotor_diam, cutout=25)
      :staticmethod:


      Creates a synthetic wind turbine power curve based on observed relationships between turbine's capacity, rotor diameter and known power curves according to Ryberg et al. [1].

      :param capacity: Baseline turbine capacity in kW.
      :type capacity: numeric
      :param rotor_diam: turbine rotor diameter in m
      :type rotor_diam: numeric
      :param cutout: Cut out wind speed in m/s, by default 25
      :type cutout: int, optional

      :returns: * *PowerCurve*
                * *Sources*
                * *-------*
                * **[1] Ryberg, D. S., Caglayan, D. G., Schmitt, S., Linßen, J., Stolten, D., & Robinius, M. (2019). The future of European onshore wind energy potential** (*Detailed distribution and simulation of advanced turbine designs. Energy. https://doi.org/10.1016/j.energy.2019.06.052*)



   .. py:method:: simulate(wind_speed)

      Applies the invoking power curve to the given wind speeds.

      :param wind_speed: Local average wind speed close to or at the hub height.
      :type wind_speed: array_like

      :returns: CorrespongDing capacity fators for the given wind speeds
      :rtype: array_like



   .. py:method:: expected_capacity_factor_from_weibull(mean_wind_speed=5, weibull_shape=2)

      Computes the expected average capacity factor of a wind turbine based on a Weibull distribution of wind speeds.

      :param mean_wind_speed: mean wind speed at the location in m/s, by default 5
      :type mean_wind_speed: int, optional
      :param weibull_shape: Weibull shape parameter, by default 2
      :type weibull_shape: int, optional

      :returns: Average capacity factor
      :rtype: numeric



   .. py:method:: expected_capacity_factor_from_distribution(wind_speed_values, wind_speed_counts)

      Computes the expected average capacity factor of a wind turbine based on an explicitly-provided wind speed distribution

      :param wind_speed_values: wind speed values in m/s
      :type wind_speed_values: numeric or array-like
      :param wind_speed_counts: corresponding counts (number of occurrence) of the given wind speed values.
                                Counts will be normalized within the function
      :type wind_speed_counts: numeric or array-like

      .. rubric:: Example

      pc.expected_capacity_factor_from_distribution(
          wind_speed_values=[  1,   2,   3,   4,   5,      6], # Units of m/s
          wind_speed_counts=[0.1, 0.3, 0.5, 0.3, 0.1, 0.025 ]  # Units of "counts"
          )

      :returns: Average capacity factor
      :rtype: numeric



   .. py:method:: convolute_by_gaussian(scaling=0.06, base=0.1, extend_beyond_cut_out=True, _min_speed=0.01, _max_speed=40, _steps=4000)

      Convolutes a turbine power curve by a normal distribution function with wind-speed-dependent standard deviation.

      :param scaling: scaling factor, by default 0.06
      :type scaling: float, optional
      :param base: base value, by default 0.1
      :type base: float, optional
      :param extend_beyond_cut_out: extend the estimation beyond the turbine's cut out wind speed, by default True
      :type extend_beyond_cut_out: bool, optional
      :param _min_speed: minimum wind speed value in m/s to be considered, by default 0.01
      :type _min_speed: float, optional
      :param _max_speed: maximum wind speed value in m/s to be considered, by default 40
      :type _max_speed: int, optional
      :param _steps: number of steps in between the wind speed range, by default 4000
      :type _steps: int, optional

      :returns: The resulting convoluted power curve
      :rtype: PowerCurve

      .. rubric:: Notes

      The wind-speed-dependent standard deviation is computed with: std = wind_speed * scaling + base



   .. py:method:: apply_loss_factor(loss)

      Applies a loss factor onto the power curve. It can be a single value, or a function which takes a 'capacity factor' array as input.

      :param loss:
                   If numeric, the value is applied at all capacity factors with:
                       new_capacity_factors = [1-loss] * previous_capacity_factors
                   If a function, it must take a numpy array representing capacity factor values as input, resulting in the equation:
                       new_capacity_factors = [1-loss(previous_capacity_factors)] * previous_capacity_factors
      :type loss: numeric or function

      :returns: The corrected power curve.
      :rtype: PowerCurve



.. py:function:: compute_specific_power(capacity, rotor_diam, **k)

   Calculates the corresponding specific power for a wind turbine in W/m2 from values of capacity in kW and rotor diameter in m.

   :param capacity: Turbine's nominal capacity in kW.
   :type capacity: float or array-like
   :param rotor_diam: Turbine's hub height in m.
   :type rotor_diam: float or array-like

   :returns: Specific power in W/m2
   :rtype: float or array-like


.. py:function:: alpha_from_levels(low_wind_speed, low_height, high_wind_speed, high_height)

   Obtains the scaling factor given two wind speeds measured at two different known heights.

   :param low_wind_speed: The measured windspeed at the 'lower height'
   :type low_wind_speed: numeric or array_like
   :param low_height: The measured height at the 'lower height'
   :type low_height: numeric or array_like
   :param high_wind_speed: The measured windspeed at the 'higher height'
   :type high_wind_speed: numeric or array_like
   :param high_height: The measured height at the 'higher height'
   :type high_height: numeric or array_like

   :returns: The corresponding scaling factor
             The output dimensionality follows the broadcasting rules of Numpy
   :rtype: numeric or array-like

   .. rubric:: Notes

   The projection of wind speed values at a given height using the returned scaling factors can be computed using the following function:
           apply_power_profile_projection(measured_wind_speed, measured_height, target_height, alpha)


.. py:function:: apply_power_profile_projection(measured_wind_speed, measured_height, target_height, alpha=1 / 7)

   Estimates wind speed values at target height based on another measured wind speed at a known height subject to a power-law scaling factor.

   :param measured_wind_speed: The raw wind speeds to be adjusted.
                               If a single dimension array is given, it is assumed to represent timeseries values for a single location
                               If a multidimensional array is given, the assumed dimensional context is (time, locations), and 'targetLoc' must be an iterable with the same length as the 'locations' dimension

                               measured_height : array_like
                               The measurement height of the raw windspeeds.
                               Must either be a single value, or an array of values with the same length as the "locations" dimension of `measured_wind_speed`

                               target_height : numeric or array_like
                               The (hub) height to project each wind speed timeseries to
                               Must either be a single value, or an array of values with the same length as the "locations" dimension of `measured_wind_speed`

                               alpha : numeric or array_like, optional
                               The scaling factor used to project each wind speed timeseries, by default 1/7
                               Must either be a single value, or an array of values with the same length as the "locations" dimension of `measured_wind_speed`
   :type measured_wind_speed: array_like

   .. rubric:: Notes

   The default scaling factor, alpha, equal to 1/7 corresponds to neutral stability conditions.
   Alpha values can also be computed using the following function:
           alpha_from_levels(low_wind_speed, low_height, high_wind_speed, high_height)

   :returns: * *array_like*
             * projected wind speeds with the same dimensions as `measured_wind_speed`


.. py:function:: TurbineLibrary()

   A dataframe of internally configured wind turbines accessible to later simulations


.. py:function:: offshore_turbine_capex(capacity, hub_height, rotor_diam, depth, distance_to_shore, distance_to_bus=None, foundation=None, mooring_count=None, anchor=None, turbine_count=None, turbine_spacing=None, turbine_row_spacing=None)

   A cost and scaling model (CSM) to calculate the total cost of a 3-bladed, direct drive offshore wind turbine according to the cost model proposed by Fingersh et al. [1] and Maples et al. [2].
   The CSM distinguishes between seaflor-fixed foundation types; "monopile" and "jacket" and floating foundation types; "semisubmersible" and "spar".
   The total turbine cost includes the contributions of the turbine capital cost (TCC), amounting 32.9% for fixed or 23.9% for floating structures, the balance of system costs (BOS) contribution, amounting 46.2% and 60.8% respectively, as well as the finantial costs as the complementary percentage contribution (15.9% and 20.9%) in the same manner [3].
   A CSM normalization is done such that a chosen baseline offshore turbine taken by Caglayan et al. [4] (see notes for details) corresponds to an expected specific cost of 2300 €/kW in a 2050 European context as suggested by the 2016 cost of wind energy review by Stehly [3].

   :param capacity: Turbine's nominal capacity in kW.
   :type capacity: numeric or array-like
   :param hub_height: Turbine's hub height in m.
   :type hub_height: numeric or array-like
   :param rotor_diam: Turbine's rotor diameter in m.
   :type rotor_diam: numeric or array-like
   :param depth: Water depth in m (absolute value) at the turbine's location.
   :type depth: numeric or array-like
   :param distance_to_shore: Distance from the turbine's location to the nearest shore in km.
   :type distance_to_shore: numeric or array-like
   :param distance_to_bus: Distance from the wind farm's bus in km from the turbine's location.
   :type distance_to_bus: numeric or array-like, optional
   :param foundation: Turbine's foundation type. Accepted  types are: "monopile", "jacket", "semisubmersible" or "spar", by default "monopile"
   :type foundation: str or array-like of strings, optional
   :param mooring_count: Refers to the number of mooring lines are there attaching a turbine only applicable for floating foundation types. By default 3 assuming a triangular attachment to the seafloor.
   :type mooring_count: numeric, optional
   :param anchor: Turbine's anchor type only applicable for floating foundation types, by default as recommended by [1].
                  Arguments accepted are "dea" (drag embedment anchor) or "spa" (suction pile anchor).
   :type anchor: str, optional
   :param turbine_count: Number of turbines in the offshore windpark. CSM valid for the range [3-200], by default 80
   :type turbine_count: numeric, optional
   :param turbine_spacing: Spacing distance in a row of turbines (turbines that share the electrical connection) to the bus. The value must be a multiplier of rotor diameter. CSM valid for the range [4-9], by default 5
   :type turbine_spacing: numeric, optional
   :param turbine_row_spacing: Spacing distance between rows of turbines. The value must be a multiplier of rotor diameter. CSM valid for the range [4-10], by default 9
   :type turbine_row_spacing: numeric, optional

   :returns: Offshore turbine total cost
   :rtype: numeric or array-like

   .. rubric:: Notes

   The baseline offshore turbine correspongs to the optimal design for Europe according to Caglayan et al. [4]: capacity = 9400 kW, hub height = 135 m, rotor diameter = 210 m, "monopile" foundation, reference water depth = 40 m, and reference distance to shore = 60 km.

   Sources
   -------
   [1] Fingersh, L., Hand, M., & Laxson, A. (2006). Wind Turbine Design Cost and Scaling Model. Nrel. https://www.nrel.gov/docs/fy07osti/40566.pdf
   [2] Maples, B., Hand, M., & Musial, W. (2010). Comparative Assessment of Direct Drive High Temperature Superconducting Generators in Multi-Megawatt Class Wind Turbines. Energy. https://doi.org/10.2172/991560
   [3] Stehly, T., Heimiller, D., & Scott, G. (2016). Cost of Wind Energy Review. Technical Report. https://www.nrel.gov/docs/fy18osti/70363.pdf
   [4] Caglayan, D. G., Ryberg, D. S., Heinrichs, H., Linssen, J., Stolten, D., & Robinius, M. (2019). The techno-economic potential of offshore wind energy with optimized future turbine designs in Europe. Applied Energy. https://doi.org/10.1016/j.apenergy.2019.113794
   [5] Maness, M., Maples, B., & Smith, A. (2017). NREL Offshore Balance-of- System Model NREL Offshore Balance-of- System Model. https://www.nrel.gov/docs/fy17osti/66874.pdf
   [6] Myhr, A., Bjerkseter, C., Ågotnes, A., & Nygaard, T. A. (2014). Levelised cost of energy for offshore floating wind turbines in a life cycle perspective. Renewable Energy, 66, 714–728. https://doi.org/10.1016/j.renene.2014.01.017
   [7] Bjerkseter, C., & Ågotnes, A. (2013). Levelised Costs Of Energy For Offshore Floating Wind Turbine Concepts [Norwegian University of Life Sciences]. https://nmbu.brage.unit.no/nmbu-xmlui/bitstream/handle/11250/189073/Bjerkseter%2C C. %26 Ågotnes%2C A. %282013%29 - Levelised Costs of Energy for Offshore Floating Wind Turbine Concepts.pdf?sequence=1&isAllowed=y
   [8] Smart, G., Smith, A., Warner, E., Sperstad, I. B., Prinsen, B., & Lacal-Arantegui, R. (2016). IEA Wind Task 26: Offshore Wind Farm Baseline Documentation. https://doi.org/10.2172/1259255
   [9] RPG CABLES, & KEC International limited. (n.d.). EXTRA HIGH VOLTAGE cables. RPG CABLES. www.rpgcables.com/images/product/EHV-catalogue.pdf



.. py:function:: onshore_turbine_capex(capacity, hub_height, rotor_diam, base_capex=None, base_capacity=None, base_hub_height=None, base_rotor_diam=None, tcc_share=None, bos_share=None)

   A cost and scaling model (CSM) to calculate the total cost of a 3-bladed, direct drive onshore wind turbine according to Fingersh et al. [1] and Maples et al. [2].
   A CSM normalization is done such that a chosen baseline turbine, with a capacity of 4200 kW, hub height of 120 m, and rotor diameter of 136 m, corresponds to a expected typical specific cost of 1100 Eur/kW in a 2050 European context according to Ryberg et al. [4]
   The turbine cost includes the turbine capital cost (TCC) and balance of system costs (BOS), amounting to 67.3% and 22.9% respectively [3], as well as finantial costs equivalent to the the complementary percentage.


   :param capacity: Turbine's nominal capacity in kW.
   :type capacity: numeric or array-like
   :param hub_height: Turbine's hub height in m.
   :type hub_height: numeric or array-like
   :param rotor_diam: Turbine's hub height in m.
   :type rotor_diam: numeric or array-like
   :param base_capex: The baseline turbine's capital costs in €, by default 1100*4200 [€/kW * kW]
   :type base_capex: numeric, optional
   :param base_capacity: The baseline turbine's capacity in kW, by default 4200
   :type base_capacity: int, optional
   :param base_hub_height: The baseline turbine's hub height in m, by default 120
   :type base_hub_height: int, optional
   :param base_rotor_diam: The baseline turbine's rotor diameter in m, by default 136
   :type base_rotor_diam: int, optional
   :param tcc_share: The baseline turbine's turbine capital cost (TCC) percentage contribution in the total cost, by default 0.673
   :type tcc_share: float, optional
   :param bos_share: The baseline turbine's balance of system costs (BOS) percentage contribution in the total cost, by default 0.229
   :type bos_share: float, optional

   :returns: Onshore turbine total cost
   :rtype: numeric or array-like

   .. rubric:: Notes

   The expected turbine cost shares by Stehly et al. [3] are claimed to be derived from real cost data and valid until 10 MW capacity.

   Sources
   -------
   [1] Fingersh, L., Hand, M., & Laxson, A. (2006). Wind Turbine Design Cost and Scaling Model. NREL. https://www.nrel.gov/docs/fy07osti/40566.pdf
   [2] Maples, B., Hand, M., & Musial, W. (2010). Comparative Assessment of Direct Drive High Temperature Superconducting Generators in Multi-Megawatt Class Wind Turbines. Energy. https://doi.org/10.2172/991560
   [3] Stehly, T., Heimiller, D., & Scott, G. (2016). Cost of Wind Energy Review. Technical Report. https://www.nrel.gov/docs/fy18osti/70363.pdf
   [4] Ryberg, D. S., Caglayan, D. G., Schmitt, S., Linßen, J., Stolten, D., & Robinius, M. (2019). The future of European onshore wind energy potential: Detailed distribution and simulation of advanced turbine designs. Energy. https://doi.org/10.1016/j.energy.2019.06.052


.. py:class:: WindWorkflowManager(placements, synthetic_power_curve_cut_out=25, synthetic_power_curve_rounding=1)

   Bases: :py:obj:`reskit.workflow_manager.WorkflowManager`


   Helps managing the logical workflow for simulations relating to wind turbines.

   Initialization:

   :param placements: A Pandas DataFrame describing the wind turbine placements to be simulated.
                      It must include the following columns:
                          'geom' or 'lat' and 'lon'
                          'hub_height'
                          'capacity'
                          'rotor_diam' or 'powerCurve'
   :type placements: pandas.DataFrame
   :param synthetic_power_curve_cut_out: cut out wind speed, by default 25
   :type synthetic_power_curve_cut_out: int, optional
   :param synthetic_power_curve_rounding: rounding floor, by default 1
   :type synthetic_power_curve_rounding: int, optional

   :returns: A corrected power curve.
   :rtype: numpy array


   .. py:attribute:: powerCurveLibrary


   .. py:method:: project_windspeeds_to_hub_height(height_scaling_method, height_scaling_data, consider_boundary_layer_height=True, allow_extrapolation=True)

      Projects wind speeds to hub heights for a given projection/scaling method.

      :param height_scaling_method: The method to project the windspeeds from the default height (here
                                    100m in ERA-5/GWA3) to hub height (possibly affected by the planetary
                                    boundary layer height). First tuple entry (str) describes the general
                                    approach (e.g. logarithmic scaling or based on long-run-average
                                    windspeeds). No height scaling will be applied when None. Options are:
                                    ("lra", [vertical method]) : Calculation based on the long-run average
                                        wind speeds (e.g. GWA) of the 2 nearest available height levels.
                                        [vertical method] (str) describes the form of interpolation, e.g.
                                        "linear".
                                    ("log", [landcover]) : Logarithmic height scaling based on surface
                                        roughness defined via a mapping of the land cover category.
                                        [landcover] (str) defines the landcover data used for roughness
                                        mapping. All landcover types accepted as land_cover_type in
                                        logarithmic_profile.roughness_from_land_cover_classification() are
                                        allowed, by default "cci" (ESA CCI raster).
      :type height_scaling_method: tuple
      :param height_scaling_data: The data required for the selected height_scaling_method (see above).
                                  The expected data formats are, depending on height_scaling_method:
                                  ("log", [landcover]) : str
                                      Path to the respective "landcover" raster file.
                                  ("lra", [vertical method]) : {int : str}
                                      Dict with heights as keys and paths to the LRA-windspeeds at the
                                      respective heights as values. Must contain at least one higher and
                                      one lower height than the reference height of real_lra_ws_path.
      :type height_scaling_data: str, dict
      :param consider_boundary_layer_height: Corrects the given hub heights for locations by planetary boundary
                                             layer (PBL) effects if True, see consider_boundary_height() for
                                             details. By default True.
      :type consider_boundary_layer_height: bool, optional
      :param allow_extrapolation: Takes effect only in interpolating methods, will then allow to
                                  extrapolate beyond the min/max height range, by default True.
      :type allow_extrapolation: bool, optional

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: set_roughness(roughness)

      Sets the 'roughness' column in the placements DataFrame.

      :param roughness: If a numeric is given, sets the same roughness values to all placements.
                        If an iterable is given, sets the corresponding roughness value in the iterable to the placements.
                        The length of the iterable must match the number of placements
      :type roughness: numeric, iterable

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: estimate_roughness_from_land_cover(path, source_type)

      Estimates the 'roughness' value column in the placements DataFrame from a given land cover classification raster file.

      :param path: path to the raster file
      :type path: str
      :param source_type: string value to get the corresponding key-value pairs. Accepted types 'clc', 'clc-code', 'globCover', 'modis', or 'cci', by default 'clc'
      :type source_type: str

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: consider_boundary_height()

      Corrects the given target heights for locations by planetary boundary
      layer (PBL) effects, by limiting the target height either to the PBL
      height when elevated (starting) height < PBL < target height or avoiding
      scaling altogether when PBL <= elevated (startig) height (by setting
      target height to elevated starting height).

      :returns: The adapted target heights.
      :rtype: numpy array



   .. py:method:: logarithmic_projection_of_wind_speeds_to_hub_height(consider_boundary_layer_height=False)

      Projects the wind speed values to the hub height.

      consider_boundary_layer_height : bool, optional
          If True, the wind speed will be scaled only to max. the
          boundary layer height. By default False.

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: wind_shear_projection_of_wind_speeds_to_hub_height(alternative_wind_speed_rasters, consider_boundary_layer_height=False, allow_extrapolation=True)

      Projects the wind speed values to the hub height.

      consider_boundary_layer_height : bool, optional
          If True, the wind speed will be scaled only to max. the
          boundary layer height. By default False.
      allow_extrapolation . BOOL; OPTIONAL
          If False, target heights must be between minimum and maximum
          height keys provided in alternative_wind_speed_rasters. By
          default True.

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: apply_air_density_correction_to_wind_speeds()

      Applies air density corrections to the wind speeds at the hub height.

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: apply_wake_correction_of_wind_speeds(wake_curve='dena_mean')

      Applies a wind-speed dependent reduction factor to the wind speeds at elevated height,
      based on

      :param wake_curve: string value to describe the wake reduction method. None will
                         cause no reduction. Location-sepcific values can also be
                         given in a 'wake_curve' column of the placements dataframe,
                         the latter will be overridden by the 'wake_curve' argument.
                         By default "dena_mean". Choose from (see more information
                         here under wind_efficiency_curve_name[1]):
                         * "dena_mean",
                         * "knorr_mean",
                         * "dena_extreme1",
                         * "dena_extreme2",
                         * "knorr_extreme1",
                         * "knorr_extreme2",
                         * "knorr_extreme3",
      :type wake_curve: str, optional

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: convolute_power_curves(scaling, base, **kwargs)

      Convolutes a turbine power curve from a normal distribution function with wind-speed-dependent standard deviation.

      :param scaling: scaling factor, by default 0.06
      :type scaling: float, optional
      :param base: base value, by default 0.1
      :type base: float, optional

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: simulate(max_batch_size=None, cf_correction_factor=1.0, tolerance=0.01, max_iterations=10, verbose=True)

      Applies the invoking power curve to the given wind speeds.
      A max_batch_size can be set, splitting the simulation in batches.
      If set, cf_correction_factor is applied iteratively to adjust avreage cf output.
      Capacity factors are calculated in the subfunction _sim(), which is called iteratively.

      max_batch_size : int, optional
          The maximum number of locations to be simulated simultaneously.
          If None, no limits will be applied, by default None.

      cf_correction_factor : float, optional
          The average cf output will be adjusted by this ratio
          via wind speed adaptations (no linear scaling). By default 1.0.

      tolerance : float, optional
          The max. deviation of the simulated average cf from the enforced
          corrected value, by default 0.03, i.e. 3% absolute.

      max_iterations : int, optional
          The max. No. of simulation iterations allowed for iterative
          simulation of one batch until the tolerance is met, else a
          TimeOutError will be raised. By default 10 iterations.

      verbose : bool, optional
          If True, additional status information will be printed, by
          default True.

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: apply_availability_factor(availability_factor)

      Applies a relative reduction factor to the energy output (capacity factor) time series
      to statistically account for non-availabilities.

      :param availability_factor: Factor that will be applied to the output time series.
      :type availability_factor: float

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: interpolate_raster_vals_to_hub_height(name, height_to_raster_dict, **kwargs)

      Given several raster datasets which correspond to a desired value (e.g. average wind speed) at
      different altitudes, this function will read values for each placement location from each of these
      datasets, and will then linearly interpolate them to the hub height of each turbine

      :param name: The name of the variable to create (will be placed in the `self.placements` member)
      :type name: str
      :param height_to_raster_dict: A dictionary which maps altitude values to raster datasets
      :type height_to_raster_dict: dict

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: set_correction_factors(correction_factors, verbose=True)

      Gets the correction factors if necessary and sets them as class attribute.

      :param correction_factors: correction factor as float or path to the correction factor raster file
      :type correction_factors: str, float

      :rtype: A reference to the invoking WindWorkflowManager



.. py:data:: DATAFOLDER

.. py:function:: build_ws_correction_function(type, data_dict)

   type: str
       type of correction function
   data_dict: dict, str
       dictionary or json file containing the data needed to
       build the correction function


.. py:class:: WindWorkflowManager(placements, synthetic_power_curve_cut_out=25, synthetic_power_curve_rounding=1)

   Bases: :py:obj:`reskit.workflow_manager.WorkflowManager`


   Helps managing the logical workflow for simulations relating to wind turbines.

   Initialization:

   :param placements: A Pandas DataFrame describing the wind turbine placements to be simulated.
                      It must include the following columns:
                          'geom' or 'lat' and 'lon'
                          'hub_height'
                          'capacity'
                          'rotor_diam' or 'powerCurve'
   :type placements: pandas.DataFrame
   :param synthetic_power_curve_cut_out: cut out wind speed, by default 25
   :type synthetic_power_curve_cut_out: int, optional
   :param synthetic_power_curve_rounding: rounding floor, by default 1
   :type synthetic_power_curve_rounding: int, optional

   :returns: A corrected power curve.
   :rtype: numpy array


   .. py:attribute:: powerCurveLibrary


   .. py:method:: project_windspeeds_to_hub_height(height_scaling_method, height_scaling_data, consider_boundary_layer_height=True, allow_extrapolation=True)

      Projects wind speeds to hub heights for a given projection/scaling method.

      :param height_scaling_method: The method to project the windspeeds from the default height (here
                                    100m in ERA-5/GWA3) to hub height (possibly affected by the planetary
                                    boundary layer height). First tuple entry (str) describes the general
                                    approach (e.g. logarithmic scaling or based on long-run-average
                                    windspeeds). No height scaling will be applied when None. Options are:
                                    ("lra", [vertical method]) : Calculation based on the long-run average
                                        wind speeds (e.g. GWA) of the 2 nearest available height levels.
                                        [vertical method] (str) describes the form of interpolation, e.g.
                                        "linear".
                                    ("log", [landcover]) : Logarithmic height scaling based on surface
                                        roughness defined via a mapping of the land cover category.
                                        [landcover] (str) defines the landcover data used for roughness
                                        mapping. All landcover types accepted as land_cover_type in
                                        logarithmic_profile.roughness_from_land_cover_classification() are
                                        allowed, by default "cci" (ESA CCI raster).
      :type height_scaling_method: tuple
      :param height_scaling_data: The data required for the selected height_scaling_method (see above).
                                  The expected data formats are, depending on height_scaling_method:
                                  ("log", [landcover]) : str
                                      Path to the respective "landcover" raster file.
                                  ("lra", [vertical method]) : {int : str}
                                      Dict with heights as keys and paths to the LRA-windspeeds at the
                                      respective heights as values. Must contain at least one higher and
                                      one lower height than the reference height of real_lra_ws_path.
      :type height_scaling_data: str, dict
      :param consider_boundary_layer_height: Corrects the given hub heights for locations by planetary boundary
                                             layer (PBL) effects if True, see consider_boundary_height() for
                                             details. By default True.
      :type consider_boundary_layer_height: bool, optional
      :param allow_extrapolation: Takes effect only in interpolating methods, will then allow to
                                  extrapolate beyond the min/max height range, by default True.
      :type allow_extrapolation: bool, optional

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: set_roughness(roughness)

      Sets the 'roughness' column in the placements DataFrame.

      :param roughness: If a numeric is given, sets the same roughness values to all placements.
                        If an iterable is given, sets the corresponding roughness value in the iterable to the placements.
                        The length of the iterable must match the number of placements
      :type roughness: numeric, iterable

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: estimate_roughness_from_land_cover(path, source_type)

      Estimates the 'roughness' value column in the placements DataFrame from a given land cover classification raster file.

      :param path: path to the raster file
      :type path: str
      :param source_type: string value to get the corresponding key-value pairs. Accepted types 'clc', 'clc-code', 'globCover', 'modis', or 'cci', by default 'clc'
      :type source_type: str

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: consider_boundary_height()

      Corrects the given target heights for locations by planetary boundary
      layer (PBL) effects, by limiting the target height either to the PBL
      height when elevated (starting) height < PBL < target height or avoiding
      scaling altogether when PBL <= elevated (startig) height (by setting
      target height to elevated starting height).

      :returns: The adapted target heights.
      :rtype: numpy array



   .. py:method:: logarithmic_projection_of_wind_speeds_to_hub_height(consider_boundary_layer_height=False)

      Projects the wind speed values to the hub height.

      consider_boundary_layer_height : bool, optional
          If True, the wind speed will be scaled only to max. the
          boundary layer height. By default False.

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: wind_shear_projection_of_wind_speeds_to_hub_height(alternative_wind_speed_rasters, consider_boundary_layer_height=False, allow_extrapolation=True)

      Projects the wind speed values to the hub height.

      consider_boundary_layer_height : bool, optional
          If True, the wind speed will be scaled only to max. the
          boundary layer height. By default False.
      allow_extrapolation . BOOL; OPTIONAL
          If False, target heights must be between minimum and maximum
          height keys provided in alternative_wind_speed_rasters. By
          default True.

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: apply_air_density_correction_to_wind_speeds()

      Applies air density corrections to the wind speeds at the hub height.

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: apply_wake_correction_of_wind_speeds(wake_curve='dena_mean')

      Applies a wind-speed dependent reduction factor to the wind speeds at elevated height,
      based on

      :param wake_curve: string value to describe the wake reduction method. None will
                         cause no reduction. Location-sepcific values can also be
                         given in a 'wake_curve' column of the placements dataframe,
                         the latter will be overridden by the 'wake_curve' argument.
                         By default "dena_mean". Choose from (see more information
                         here under wind_efficiency_curve_name[1]):
                         * "dena_mean",
                         * "knorr_mean",
                         * "dena_extreme1",
                         * "dena_extreme2",
                         * "knorr_extreme1",
                         * "knorr_extreme2",
                         * "knorr_extreme3",
      :type wake_curve: str, optional

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: convolute_power_curves(scaling, base, **kwargs)

      Convolutes a turbine power curve from a normal distribution function with wind-speed-dependent standard deviation.

      :param scaling: scaling factor, by default 0.06
      :type scaling: float, optional
      :param base: base value, by default 0.1
      :type base: float, optional

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: simulate(max_batch_size=None, cf_correction_factor=1.0, tolerance=0.01, max_iterations=10, verbose=True)

      Applies the invoking power curve to the given wind speeds.
      A max_batch_size can be set, splitting the simulation in batches.
      If set, cf_correction_factor is applied iteratively to adjust avreage cf output.
      Capacity factors are calculated in the subfunction _sim(), which is called iteratively.

      max_batch_size : int, optional
          The maximum number of locations to be simulated simultaneously.
          If None, no limits will be applied, by default None.

      cf_correction_factor : float, optional
          The average cf output will be adjusted by this ratio
          via wind speed adaptations (no linear scaling). By default 1.0.

      tolerance : float, optional
          The max. deviation of the simulated average cf from the enforced
          corrected value, by default 0.03, i.e. 3% absolute.

      max_iterations : int, optional
          The max. No. of simulation iterations allowed for iterative
          simulation of one batch until the tolerance is met, else a
          TimeOutError will be raised. By default 10 iterations.

      verbose : bool, optional
          If True, additional status information will be printed, by
          default True.

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: apply_availability_factor(availability_factor)

      Applies a relative reduction factor to the energy output (capacity factor) time series
      to statistically account for non-availabilities.

      :param availability_factor: Factor that will be applied to the output time series.
      :type availability_factor: float

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: interpolate_raster_vals_to_hub_height(name, height_to_raster_dict, **kwargs)

      Given several raster datasets which correspond to a desired value (e.g. average wind speed) at
      different altitudes, this function will read values for each placement location from each of these
      datasets, and will then linearly interpolate them to the hub height of each turbine

      :param name: The name of the variable to create (will be placed in the `self.placements` member)
      :type name: str
      :param height_to_raster_dict: A dictionary which maps altitude values to raster datasets
      :type height_to_raster_dict: dict

      :rtype: A reference to the invoking WindWorkflowManager



   .. py:method:: set_correction_factors(correction_factors, verbose=True)

      Gets the correction factors if necessary and sets them as class attribute.

      :param correction_factors: correction factor as float or path to the correction factor raster file
      :type correction_factors: str, float

      :rtype: A reference to the invoking WindWorkflowManager



.. py:function:: wind_era5_PenaSanchezDunkelWinklerEtAl2025(placements, era5_path, gwa_100m_path, height_scaling_data, gwa_nodata_fallback=1.0, output_netcdf_path=None, cf_correction=True, output_variables=None, max_batch_size=15000, **simulate_kwargs)

   Simulates wind turbine locations onshore and offshore using ECMWF's
   ERA5 database [1], with an optional correction loop to ensure that
   generated capacity factors for historic wind fleets meet reported
   generation/capacity based on Renewables Market Report [2] by the
   International Energy Agency (IEA).

   Please cite the following publication when using the workflow [3]:
   Peña-Sánchez, Dunkel, Winkler et al. (2025): Towards high resolution,
   validated and open global wind power assessments.
   https://doi.org/10.48550/arXiv.2501.07937

   :param placements: A Dataframe object with the parameters needed by the simulation.
   :type placements: pandas Dataframe
   :param era5_path: Path to the ERA5 data.
   :type era5_path: str
   :param gwa_100m_path: Path to the Global Wind Atlas v4 (GWA4) at 100m [4] raster file.
   :type gwa_100m_path: str
   :param height_scaling_data: The data required for the height_scaling_method ("lra", "linear").
                               Dict with integer heights as keys and str paths to the Global Wind Atlas
                               windspeeds [4] at the respective heights as values. Must contain at
                               least one higher and one lower height than 100 [m].
   :type height_scaling_data: dict
   :param gwa_nodata_fallback: If no GWA data is available, use for simulation:
                               (1) float value for a multiple of the respective ERA-5 value
                                   (ERA5 raw), i.e. 1.0 means fall back on unscaled ERA-5 value
                               (2) np.nan for nan output
                               (3) a callable function to be applied to the ERA-5 value in the format:
                                   nodata_fallback(locs, ERA5_value)
                               (4) a filepath to a raster file containing the fallback values
   :type gwa_nodata_fallback: str, optional
   :param output_netcdf_path: Path to a directory to put the output files, by default None
   :type output_netcdf_path: str, optional
   :param cf_correction: If False, the capacity factors will be calculated based on a
                         calibrated physical model only, else an additional correction
                         step will be added to ensure that historic capacity factors based
                         on [2] are met if historic wind fleets are simulated. By default
                         True.
   :type cf_correction: bool, optional
   :param output_variables: Restrict the output variables to these variables, by default None
   :type output_variables: str, optional
   :param max_batch_size: The maximum number of locations to be simulated simultaneously,
                          else multiple batches will be simulated iteratively. Helps
                          limiting RAM requirements but may affect runtime. Should be
                          adapted to individual computation system (roughly 7GB RAM per
                          10k locations), by default 25 000.
   :type max_batch_size: int
   :param simulate_kwargs: Will be passed on to simulate().
   :type simulate_kwargs: optional

   :returns: * *xarray.Dataset* -- A xarray dataset including all the output variables you defined as your output variables.
             * *Sources*
             * *-------*
             * **[1] European Centre for Medium-Range Weather Forecasts. (2019). ERA5 dataset. https** (*//www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5*)
             * **[2] International Energy Agency. (2023). Renewables Market Report. https** (*//www.iea.org/reports/renewables-2023*)
             * **[3] Peña-Sánchez, Dunkel, Winkler et al. (2025)** (*Towards high resolution, validated and open global wind power assessments. https://doi.org/10.48550/arXiv.2501.07937*)
             * **[4] DTU Wind Energy. (2025). Global Wind Atlas v4. https** (*//globalwindatlas.info/*)


.. py:function:: onshore_wind_merra_ryberg2019_europe(placements, merra_path, gwa_50m_path, clc2012_path, output_netcdf_path=None, output_variables=None, max_batch_size=25000)

   Simulates onshore wind generation in Europe using NASA's MERRA2 database [1].

   :param placements: A Dataframe object with the parameters needed by the simulation.
   :type placements: pandas Dataframe
   :param merra_path: Path to the MERRA2 data.
   :type merra_path: str
   :param gwa_50m_path: Path to the Global Wind Atlas at 50m [2] rater file.
   :type gwa_50m_path: str
   :param clc2012_path: Path to the CLC 2012 raster file [3].
   :type clc2012_path: str
   :param output_netcdf_path: Path to a directory to put the output files, by default None
   :type output_netcdf_path: str, optional
   :param output_variables: Restrict the output variables to these variables, by default None
   :type output_variables: str, optional
   :param max_batch_size: The maximum number of locations to be simulated simultaneously, else multiple batches will be simulated
                          iteratively. Helps limiting RAM requirements but may affect runtime. By default 25 000. Roughly 7GB RAM per 10k locations.
   :type max_batch_size: int

   :returns: * *xarray.Dataset* -- A xarray dataset including all the output variables you defined as your output variables.
             * *Sources*
             * *-------*
             * **[1] NASA (National Aeronautics and Space Administration). (2019). Modern-Era Retrospective analysis for Research and Applications, Version 2. NASA Goddard Earth Sciences (GES) Data and Information Services Center (DISC). https** (*//disc.gsfc.nasa.gov/datasets?keywords=%22MERRA-2%22&page=1&source=Models%2FAnalyses MERRA-2*)
             * **[2] DTU Wind Energy. (2019). Global Wind Atlas. https** (*//globalwindatlas.info/*)
             * **[3] Copernicus (European Union’s Earth Observation Programme). (2012). Corine Land Cover 2012. Copernicus. https** (*//land.copernicus.eu/pan-european/corine-land-cover/clc-2012*)


.. py:function:: offshore_wind_merra_caglayan2019(placements, merra_path, output_netcdf_path=None, output_variables=None, max_batch_size=25000)

   Simulates offshore wind generation using NASA's MERRA2 database [1].

   :param placements: A Dataframe object with the parameters needed by the simulation.
   :type placements: pandas Dataframe
   :param merra_path: Path to the MERRA2 data.
   :type merra_path: str
   :param output_netcdf_path: Path to a directory to put the output files, by default None
   :type output_netcdf_path: str, optional
   :param output_variables: Restrict the output variables to these variables, by default None
   :type output_variables: str, optional
   :param max_batch_size: The maximum number of locations to be simulated simultaneously, else multiple batches will be simulated
                          iteratively. Helps limiting RAM requirements but may affect runtime. By default 25 000. Roughly 7GB RAM per 10k locations.
   :type max_batch_size: int

   :returns: * *xarray.Dataset* -- A xarray dataset including all the output variables you defined as your output variables.
             * *Sources*
             * *-------*
             * **[1] National Aeronautics and Space Administration. (2019). Modern-Era Retrospective analysis for Research and Applications, Version 2. NASA Goddard Earth Sciences (GES) Data and Information Services Center (DISC). https** (*//disc.gsfc.nasa.gov/datasets?keywords=%22MERRA-2%22&page=1&source=Models%2FAnalyses MERRA-2*)


.. py:function:: onshore_wind_iconlam_2023(placements, icon_lam_path, esa_cci_path, output_netcdf_path=None, output_variables=None, max_batch_size=25000)

   Simulates onshore wind generation using high-resolution dynamically downscaled dataset ICON-LAM over southern Africa.
   This workflow was used in the publicaiton [1].

   :param placements: A Dataframe object with the parameters needed by the simulation.
   :type placements: pandas Dataframe
   :param icon_lam_path: Path to the specified weather data.
                         May contain '<X-TILE>' and <Y-TILE>' spacers, in that case,
                         a zoom level value is expected and the correct tiles will be assigned for every
                         loation individually.
   :type icon_lam_path: str
   :param esa_cci_path: Path to the ESA CCI raster file [2].
   :type esa_cci_path: str
   :param output_netcdf_path: Path to a directory to put the output files, by default None
   :type output_netcdf_path: str, optional
   :param output_variables: Restrict the output variables to these variables, by default None
   :type output_variables: str, optional
   :param max_batch_size: The maximum number of locations to be simulated simultaneously, else multiple batches will be simulated
                          iteratively. Helps limiting RAM requirements but may affect runtime. By default 20 000.
   :type max_batch_size: int

   :returns: * *xarray.Dataset* -- A xarray dataset including all the output variables.
             * *Sources*
             * *-------*
             * **[1] Chen, S., Goergen, K., Hendricks Franssen, H. J., Winkler, C., Poll, S., Houssoukri Zounogo Wahabou, Y., ... & Heinrichs, H. (2024). Higher onshore wind energy potentials revealed by kilometer‐scale atmospheric modeling. Geophysical Research Letters, 51(19), e2024GL110122. https** (*//doi.org/10.1029/2024GL110122*)
             * **[2] ESA. Land Cover CCI Product User Guide Version 2. Tech. Rep. (2017). Available at** (*maps.elie.ucl.ac.be/CCI/viewer/download/ESACCI-LC-Ph2-PUGv2_2.0.pdf*)


.. py:function:: wind_config(placements, weather_path, weather_source_type, weather_lra_ws_path, real_lra_ws_path, real_lra_ws_scaling, real_lra_ws_spatial_interpolation, real_lra_ws_nodata_fallback, height_scaling_method, height_scaling_data, ws_correction_func, cf_correction_factor, wake_curve, availability_factor, consider_boundary_layer_height, allow_height_extrapolation, power_curve_scaling, power_curve_base, convolute_power_curves_args={}, loss_factor_args={}, output_variables=None, max_batch_size=25000, output_netcdf_path=None, elevated_wind_speed=None)

   A generic configuration workflow for wind simulations that allows
   flexible calibration of all arguments used in the workflow.
   NOTE: Only for calibration/validation purposes!

   :param placements: A Dataframe object with the parameters needed by the simulation.
   :type placements: pandas Dataframe
   :param weather_path: Path to the temporally resolved weather data, e.g. ERA-5 or MERRA-2 etc.
   :type weather_path: str
   :param weather_lra_ws_path: The path to a raster with the corresponding long-run-average
                               windspeeds of the actual weather data (will be corrected to the
                               real lra if given, else weather_lra_path has no effect)
   :type weather_lra_ws_path: str
   :param real_lra_ws_path: Either a float/int (1.0 means no scaling) or a path to a raster
                            with real long-run-average wind speeds, e.g. the Global Wind Atlas
                            at the same height as the weather data.
   :type real_lra_ws_path: str, float
   :param real_lra_ws_scaling: Accounts for unit differences, set to 1.0 if both weather data and
                               real_lra_ws are in the same unit.
   :type real_lra_ws_scaling: float
   :param real_lra_ws_spatial_interpolation: The spatial interpolation how the real lra ws shall be extracted,
                                             e.g. 'near', 'average', 'linear_spline', 'cubic_spline'
   :type real_lra_ws_spatial_interpolation: str
   :param real_lra_ws_nodata_fallback: If no GWA available, use for simulation:
                                       (1) float value for a multiple of the 'weather_lra_ws_path' value
                                           (ERA5 raw), i.e. 1.0 means weather_lra_ws_path value
                                       (2) np.nan for nan output
                                       (3) a callable function to be applied to the weather_lra_ws_path
                                           (ERA-5) value in the format:
                                           nodata_fallback(locs, weather_lra_ws_path_value)
                                       (4) a filepath to a raster file containing the fallback values
   :type real_lra_ws_nodata_fallback: str, optional
   :param height_scaling_method: The method to project the windspeeds from the default height (here
                                 100m in ERA-5/GWA3) to hub height (possibly affected by the planetary
                                 boundary layer height). First tuple entry (str) describes the general
                                 approach (e.g. logarithmic scaling or based on long-run-average
                                 windspeeds). No height scaling will be applied when None. Options are:
                                 ("lra", [vertical method]) : Calculation based on the long-run average
                                     wind speeds (e.g. GWA) of the 2 nearest available height levels.
                                     [vertical method] (str) describes the form of interpolation. By
                                     default "linear".
                                 ("log", [landcover]) : Logarithmic height scaling based on surface
                                     roughness defined via a mapping of the land cover category.
                                     [landcover] (str) defines the landcover data used for roughness
                                     mapping. All landcover types accepted as land_cover_type in
                                     logarithmic_profile.roughness_from_land_cover_classification() are
                                     allowed, by default "cci" (ESA CCI raster).
   :type height_scaling_method: tuple
   :param height_scaling_data: The data required for the selected height_scaling_method (see above).
                               The expected data formats are, depending on height_scaling_method:
                               ("log", [landcover]) : str
                                   Path to the respective "landcover" raster file.
                               ("lra", [vertical method]) : {int : str}
                                   Dict with heights as keys and paths to the LRA-windspeeds at the
                                   respective heights as values. Must contain at least one higher and
                                   one lower height than the reference height of real_lra_ws_path.
   :type height_scaling_data: str, dict
   :param ws_correction_func: An executable function that takes a numpy array as single input
                              argument and returns an adapted windspeed. If 1.0 is passed, no
                              windspeed correction will be applied. Can also be passed as tuple
                              or list of length 2 with data_type (e.g. 'linear' or 'ws_bins')
                              and data dict (dict or path to yaml) with parameters.
   :type ws_correction_func: float, callable, tuple, list
   :param cf_correction_factor: The factor by which the output capacity factors will be corrected
                                indirectly (via corresponding adaptation of the windspeeds). Can
                                be str formatted path to a raster with spatially resolved correction
                                factors, set to 1.0 to not apply any correction.
   :type cf_correction_factor: float, str
   :param wake_curve: string value to describe the wake reduction method. None will
                      cause no reduction, by default "dena_mean". Choose from (see more
                      information here under wind_efficiency_curve_name[1]): "dena_mean",
                      "knorr_mean", "dena_extreme1", "dena_extreme2", "knorr_extreme1",
                      "knorr_extreme2", "knorr_extreme3". Alternatively, the
                      'wake_curve' str can also be provided per each location in a
                      'wake_curve' column of the placements dataframe, 'wake_curve'
                      argument must then be None.
   :type wake_curve: str, optional
   :param availability_factor: This factor accounts for all downtimes and applies an average reduction to the output curve,
                               assuming a statistical deviation of the downtime occurrences and a large enough turbine fleet.
                               Suggested availability is 0.98 including technical availability of turbine and connector
                               as well as outages for ecological reasons (e.g. bat protection). This does not include wake effects
                               (see above) or curtailment/outage for economical reasons or transmission grid congestion.
   :type availability_factor: float, optional
   :param consider_boundary_layer_height: If True, boundary layer height will be considered.
   :type consider_boundary_layer_height: bool
   :param allow_height_extrapolation: Takes effect only if a height scaling method based on interpolation is
                                      chosen, will then allow or forbid extrapolation beyond the min/max
                                      provided height range.
   :type allow_height_extrapolation: bool
   :param power_curve_scaling: The scaling factor to smoothen the power curve, for details see:
                               convolute_power_curves()
   :type power_curve_scaling: float
   :param power_curve_base: The base factor to smoothen the power curve, for details see:
                            convolute_power_curves()
   :type power_curve_base: float
   :param convolute_power_curves_args: Further convolute_power_curve() arguments, for details see:
                                       convolute_power_curves(). By default {}.
   :type convolute_power_curves_args: dict, optional
   :param loss_factor_args: Arguments that are passed to reskit.utils.low_generation_loss()
                            besides the capacity factor. If empty dict ({}), no loss will be
                            applied. For details see: reskit.utils.loss_factors.low_generation_loss()
                            By default {}.
   :type loss_factor_args: dict, optional
   :param output_variables: Restrict the output variables to these variables, by default None
   :type output_variables: str, optional
   :param max_batch_size: The maximum number of locations to be simulated simultaneously, else multiple batches will be simulated
                          iteratively. Helps limiting RAM requirements but may affect runtime. By default 25 000. Roughly 7GB RAM per 10k locations.
   :type max_batch_size: int
   :param output_netcdf_path: Path to a directory to put the output files, by default None
   :type output_netcdf_path: str, optional

   :returns: A xarray dataset including all the output variables you defined as your output variables.
   :rtype: xarray.Dataset


.. py:function:: wind_era5_2023(**kwargs)

   Simulates onshore and offshore (200km from shoreline) wind generation using ECMWF's ERA5 database [1].

   Sources
   -------
   [1] European Centre for Medium-Range Weather Forecasts. (2019). ERA5 dataset. https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5


.. py:function:: onshore_wind_era5(**kwargs)

   Simulates onshore wind generation using ECMWF's ERA5 database [1].

   Sources
   -------
   [1] European Centre for Medium-Range Weather Forecasts. (2019). ERA5 dataset. https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5


.. py:function:: offshore_wind_era5(**kwargs)

   Simulates offshore wind generation using NASA's ERA5 database [1].

   Sources
   -------
   [1] European Centre for Medium-Range Weather Forecasts. (2019). ERA5 dataset. https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5.



.. py:function:: onshore_wind_era5_pure_2023(**kwargs)

   Simulates onshore wind generation using pure ECMWF's ERA5 database [1]
   without further disaggregation or correction besides height projection
   and power curve convolution.

   Sources
   -------
   [1] European Centre for Medium-Range Weather Forecasts. (2019). ERA5 dataset. https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5


