Skip to content

Commit

Permalink
Merge 08c3b61 into 89ca403
Browse files Browse the repository at this point in the history
  • Loading branch information
uvchik committed Feb 24, 2020
2 parents 89ca403 + 08c3b61 commit ddc1556
Show file tree
Hide file tree
Showing 15 changed files with 153 additions and 77 deletions.
3 changes: 3 additions & 0 deletions README.rst
Expand Up @@ -8,6 +8,9 @@
:target: https://mybinder.org/v2/gh/wind-python/windpowerlib/dev?filepath=example
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/psf/black

.. image:: https://img.shields.io/lgtm/grade/python/g/wind-python/windpowerlib.svg?logo=lgtm&logoWidth=18
:target: https://lgtm.com/projects/g/wind-python/windpowerlib/context:python

Introduction
=============
Expand Down
3 changes: 3 additions & 0 deletions doc/getting_started.rst
Expand Up @@ -13,6 +13,9 @@ Getting started
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/psf/black

.. image:: https://img.shields.io/lgtm/grade/python/g/wind-python/windpowerlib.svg?logo=lgtm&logoWidth=18
:target: https://lgtm.com/projects/g/wind-python/windpowerlib/context:python

Introduction
=============

Expand Down
2 changes: 1 addition & 1 deletion example/modelchain_example.ipynb
Expand Up @@ -288,7 +288,7 @@
"source": [
"# specification of wind turbine where power coefficient curve and nominal\n",
"# power is provided in an own csv file\n",
"csv_path = 'data'\n",
"csv_path = ''\n",
"dummy_turbine = {\n",
" 'turbine_type': 'DUMMY 1', # turbine type as in file\n",
" 'hub_height': 100, # in m\n",
Expand Down
176 changes: 107 additions & 69 deletions example/modelchain_example.py
Expand Up @@ -10,27 +10,29 @@
you need to specify your wind turbine, and in the last step call the
windpowerlib functions to calculate the feed-in time series.
Install the windpowerlib and optionally matplotlib to see the plots:
pip install windpowerlib
pip install matplotlib
Go down to the "run_example()" function to start the example.
SPDX-FileCopyrightText: 2019 oemof developer group <contact@oemof.org>
SPDX-License-Identifier: MIT
"""
import os
import pandas as pd
import requests
import logging
from windpowerlib import ModelChain, WindTurbine, create_power_curve

try:
from matplotlib import pyplot as plt
except ImportError:
plt = None

from windpowerlib import ModelChain
from windpowerlib import WindTurbine

# You can use the logging package to get logging messages from the windpowerlib
# Change the logging level if you want more or less messages
import logging
logging.getLogger().setLevel(logging.DEBUG)


def get_weather_data(filename='weather.csv', **kwargs):
def get_weather_data(filename="weather.csv", **kwargs):
r"""
Imports weather data from a file.
Expand Down Expand Up @@ -65,11 +67,16 @@ def get_weather_data(filename='weather.csv', **kwargs):
"""

if "datapath" not in kwargs:
kwargs["datapath"] = os.path.join(
os.path.split(os.path.dirname(__file__))[0], "example"
)
kwargs["datapath"] = os.path.dirname(__file__)

file = os.path.join(kwargs["datapath"], filename)

if not os.path.isfile(file):
logging.debug("Download weather data for example.")
req = requests.get("https://osf.io/59bqn/download")
with open(file, "wb") as fout:
fout.write(req.content)

# read csv file
weather_df = pd.read_csv(
file,
Expand Down Expand Up @@ -108,18 +115,19 @@ def initialize_wind_turbines():
:class:`~.wind_turbine.WindTurbine`)
"""
# ************************************************************************
# **** Data is provided in the oedb turbine library **********************

# specification of wind turbine where data is provided in the oedb
# turbine library
enercon_e126 = {
"turbine_type": "E-126/4200", # turbine type as in register
"hub_height": 135, # in m
}
# initialize WindTurbine object
e126 = WindTurbine(**enercon_e126)

# specification of own wind turbine (Note: power values and nominal power
# have to be in Watt)
# ************************************************************************
# **** Specification of wind turbine with your own data ******************
# **** NOTE: power values and nominal power have to be in Watt

my_turbine = {
"nominal_power": 3e6, # in W
"hub_height": 105, # in m
Expand All @@ -133,25 +141,36 @@ def initialize_wind_turbines():
}
), # in m/s
}
# initialize WindTurbine object
my_turbine = WindTurbine(**my_turbine)

# specification of wind turbine where power coefficient curve and nominal
# power is provided in an own csv file
csv_path = os.path.join(os.path.dirname(__file__), "data")
dummy_turbine = {
"turbine_type": "DUMMY 1",
"hub_height": 100, # in m
"rotor_diameter": 70, # in m
"path": csv_path,
# ************************************************************************
# **** Specification of wind turbine with data in own file ***************

# Read your turbine data from your data file using functions like
# pandas.read_csv().
# >>> import pandas as pd
# >>> my_data = pd.read_csv("path/to/my/data/file")
# >>> my_power = my_data["my_power"]
# >>> my_wind_speed = my_data["my_wind_speed"]

my_power = pd.Series(
[0.0, 39000.0, 270000.0, 2250000.0, 4500000.0, 4500000.0]
)
my_wind_speed = (0.0, 3.0, 5.0, 10.0, 15.0, 25.0)

my_turbine2 = {
"nominal_power": 6e6, # in W
"hub_height": 115, # in m
"power_curve": create_power_curve(
wind_speed=my_wind_speed, power=my_power
),
}
# initialize WindTurbine object
dummy_turbine = WindTurbine(**dummy_turbine)
my_turbine2 = WindTurbine(**my_turbine2)

return my_turbine, e126, dummy_turbine
return my_turbine, e126, my_turbine2


def calculate_power_output(weather, my_turbine, e126, dummy_turbine):
def calculate_power_output(weather, my_turbine, e126, my_turbine2):
r"""
Calculates power output of wind turbines using the
:class:`~.modelchain.ModelChain`.
Expand All @@ -172,20 +191,14 @@ def calculate_power_output(weather, my_turbine, e126, dummy_turbine):
e126 : :class:`~.wind_turbine.WindTurbine`
WindTurbine object with power curve from the OpenEnergy Database
turbine library.
dummy_turbine : :class:`~.wind_turbine.WindTurbine`
my_turbine2 : :class:`~.wind_turbine.WindTurbine`
WindTurbine object with power coefficient curve from example file.
"""

# power output calculation for my_turbine
# initialize ModelChain with default parameters and use run_model method
# to calculate power output
mc_my_turbine = ModelChain(my_turbine).run_model(weather)
# write power output time series to WindTurbine object
my_turbine.power_output = mc_my_turbine.power_output

# power output calculation for e126
# own specifications for ModelChain setup
# ************************************************************************
# **** Data is provided in the oedb turbine library **********************
# **** ModelChain with non-default specifications
modelchain_data = {
"wind_speed_model": "logarithmic", # 'logarithmic' (default),
# 'hellman' or
Expand All @@ -206,17 +219,25 @@ def calculate_power_output(weather, my_turbine, e126, dummy_turbine):
# write power output time series to WindTurbine object
e126.power_output = mc_e126.power_output

# power output calculation for example_turbine
# own specification for 'power_output_model'
# ************************************************************************
# **** Specification of wind turbine with your own data ******************
# **** ModelChain with default parameter
mc_my_turbine = ModelChain(my_turbine).run_model(weather)
# write power output time series to WindTurbine object
my_turbine.power_output = mc_my_turbine.power_output

# ************************************************************************
# **** Specification of wind turbine with data in own file ***************
# **** Using "power_coefficient_curve" as "power_output_model".
mc_example_turbine = ModelChain(
dummy_turbine, power_output_model="power_coefficient_curve"
my_turbine2, power_output_model="power_curve"
).run_model(weather)
dummy_turbine.power_output = mc_example_turbine.power_output
my_turbine2.power_output = mc_example_turbine.power_output

return


def plot_or_print(my_turbine, e126, dummy_turbine):
def plot_or_print(my_turbine, e126, my_turbine2):
r"""
Plots or prints power output and power (coefficient) curves.
Expand All @@ -227,44 +248,55 @@ def plot_or_print(my_turbine, e126, dummy_turbine):
e126 : :class:`~.wind_turbine.WindTurbine`
WindTurbine object with power curve from the OpenEnergy Database
turbine library.
dummy_turbine : :class:`~.wind_turbine.WindTurbine`
my_turbine2 : :class:`~.wind_turbine.WindTurbine`
WindTurbine object with power coefficient curve from example file.
"""

# plot or print turbine power output
if plt:
e126.power_output.plot(legend=True, label='Enercon E126')
my_turbine.power_output.plot(legend=True, label='myTurbine')
dummy_turbine.power_output.plot(legend=True, label='dummyTurbine')
plt.xlabel('Time')
plt.ylabel('Power in W')
e126.power_output.plot(legend=True, label="Enercon E126")
my_turbine.power_output.plot(legend=True, label="myTurbine")
my_turbine2.power_output.plot(legend=True, label="dummyTurbine")
plt.xlabel("Time")
plt.ylabel("Power in W")
plt.show()
else:
print(e126.power_output)
print(my_turbine.power_output)
print(dummy_turbine.power_output)
print(my_turbine2.power_output)

# plot or print power curve
if plt:
if e126.power_curve is not False:
e126.power_curve.plot(x='wind_speed', y='value', style='*',
title='Enercon E126 power curve')
plt.xlabel('Wind speed in m/s')
plt.ylabel('Power in W')
e126.power_curve.plot(
x="wind_speed",
y="value",
style="*",
title="Enercon E126 power curve",
)
plt.xlabel("Wind speed in m/s")
plt.ylabel("Power in W")
plt.show()
if my_turbine.power_curve is not False:
my_turbine.power_curve.plot(x='wind_speed', y='value', style='*',
title='myTurbine power curve')
plt.xlabel('Wind speed in m/s')
plt.ylabel('Power in W')
my_turbine.power_curve.plot(
x="wind_speed",
y="value",
style="*",
title="myTurbine power curve",
)
plt.xlabel("Wind speed in m/s")
plt.ylabel("Power in W")
plt.show()
if dummy_turbine.power_coefficient_curve is not False:
dummy_turbine.power_coefficient_curve.plot(
x='wind_speed', y='value', style='*',
title='dummyTurbine power coefficient curve')
plt.xlabel('Wind speed in m/s')
plt.ylabel('Power coefficient')
if my_turbine2.power_curve is not False:
my_turbine2.power_curve.plot(
x="wind_speed",
y="value",
style="*",
title="myTurbine2 power curve",
)
plt.xlabel("Wind speed in m/s")
plt.ylabel("Power in W")
plt.show()
else:
if e126.power_coefficient_curve is not False:
Expand All @@ -278,10 +310,16 @@ def run_example():
Runs the basic example.
"""
# You can use the logging package to get logging messages from the
# windpowerlib. Change the logging level if you want more or less messages:
# logging.DEBUG -> many messages
# logging.INFO -> few messages
logging.getLogger().setLevel(logging.DEBUG)

weather = get_weather_data("weather.csv")
my_turbine, e126, dummy_turbine = initialize_wind_turbines()
calculate_power_output(weather, my_turbine, e126, dummy_turbine)
plot_or_print(my_turbine, e126, dummy_turbine)
my_turbine, e126, my_turbine2 = initialize_wind_turbines()
calculate_power_output(weather, my_turbine, e126, my_turbine2)
plot_or_print(my_turbine, e126, my_turbine2)


if __name__ == "__main__":
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions tests/data/power_coefficient_curves.csv
@@ -0,0 +1,3 @@
turbine_type,0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5,10,10.5,11,11.5,12,12.5,13,13.5,14,14.5,15,15.5,16,16.5,17,17.5,18,18.5,19,19.5,20,20.5,21,21.5,22,22.5,23,23.5,24,24.5,25,25.5,26
DUMMY 1,0,,0,,0,,0,0,0.13,,0.38,,0.46,,0.48,,0.47,,0.44,,0.4,,0.36,,0.31,,0.26,,0.23,,0.2,,0.18,,0.14,,0.11,,0.1,,0.09,,0.07,,0.05,,0.04,,0.04,,0.03,,0
DUMMY 2,0,,0,,0,,0.16,0.29,0.35,0.38,0.4,0.41,0.42,0.43,0.43,0.44,0.44,0.44,0.44,0.43,0.42,0.39,0.36,0.32,0.29,0.26,0.23,0.2,0.18,0.16,0.15,0.14,0.12,0.11,0.1,0.09,0.09,0.08,0.07,0.07,0.06,0.06,0.05,0.05,0.05,0.04,0.04,0.04,0.04,0.03,0.03,0,0
3 changes: 3 additions & 0 deletions tests/data/power_curves.csv
@@ -0,0 +1,3 @@
turbine_type,0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5,10,10.5,11,11.5,12,12.5,13,13.5,14,14.5,15,15.5,16,16.5,17,17.5,18,18.5,19,19.5,20,20.5,21,21.5,22,22.5,23,23.5,24,24.5,25,25.5,26
DUMMY 3,0,0,0,0,0,0,0,18000,34000,70000,10000,150000,190000,260000,330000,420000,510000,620000,740000,880000,1020000,1180000,1330000,1420000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,1500000,0,
DUMMY 4,0,,0,,0,,0,,4000,,22000,,46000,,76000,,111000,,147000,,184000,,219000,,249000,,274000,,290000,,297000,,302000,,307000,,307000,,305000,,295000,,280000,,260000,,240000,,230000,,225000,0,
5 changes: 5 additions & 0 deletions tests/data/turbine_data.csv
@@ -0,0 +1,5 @@
turbine_type,nominal_power
DUMMY 1,4200000
DUMMY 2,4200000
DUMMY 3,1500000
DUMMY 4,225000
2 changes: 1 addition & 1 deletion tests/test_wind_turbine.py
Expand Up @@ -22,7 +22,7 @@ class TestWindTurbine:
@classmethod
def setup_class(cls):
"""Setup default values"""
cls.source = os.path.join(os.path.dirname(__file__), "../example/data")
cls.source = os.path.join(os.path.dirname(__file__), "data")

def test_warning(self, recwarn):
test_turbine_data = {
Expand Down
3 changes: 2 additions & 1 deletion windpowerlib/__init__.py
Expand Up @@ -3,8 +3,9 @@
__version__ = "0.2.1dev"

from windpowerlib.wind_turbine import WindTurbine
from windpowerlib.wind_turbine import get_turbine_types
from windpowerlib.wind_turbine import create_power_curve
from windpowerlib.wind_farm import WindFarm
from windpowerlib.wind_turbine_cluster import WindTurbineCluster
from windpowerlib.modelchain import ModelChain
from windpowerlib.turbine_cluster_modelchain import TurbineClusterModelChain
from windpowerlib.wind_turbine import get_turbine_types
2 changes: 1 addition & 1 deletion windpowerlib/power_curves.py
Expand Up @@ -159,7 +159,7 @@ def smooth_power_curve(power_curve_wind_speeds, power_curve_values,
# Get standard deviation for Gauss function
standard_deviation = (
(power_curve_wind_speed * normalized_standard_deviation + 0.6)
if standard_deviation_method is "Staffell_Pfenninger"
if standard_deviation_method == "Staffell_Pfenninger"
else power_curve_wind_speed * normalized_standard_deviation
)
# Get the smoothed value of the power output
Expand Down
1 change: 0 additions & 1 deletion windpowerlib/wind_farm.py
Expand Up @@ -9,7 +9,6 @@
from windpowerlib import tools, power_curves, WindTurbine
import numpy as np
import pandas as pd
import logging
import warnings


Expand Down

0 comments on commit ddc1556

Please sign in to comment.