Skip to content

Commit bc786f1

Browse files
committed
Merge dev to solve merge conflicts
2 parents 28b541d + 66678d0 commit bc786f1

32 files changed

+2117
-1261
lines changed

.stickler.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
linters:
2+
flake8:
3+
python: 3
4+
max-line-length: 79
5+
select: C,E,F,W,B,B950
6+
ignore: E203, E501, W503
7+
black:
8+
config: ./pyproject.toml
9+
fixer: true
10+
11+
fixers:
12+
enable: true

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ matrix:
55
- python: 3.5
66
- python: 3.6
77
- python: 3.7
8-
dist: xenial
9-
sudo: true
8+
- python: 3.8
109

1110
# command to install dependencies
1211
#before_install:

README.rst

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
:target: https://coveralls.io/github/wind-python/windpowerlib?branch=dev
55
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.824267.svg
66
:target: https://doi.org/10.5281/zenodo.824267
7+
.. image:: https://mybinder.org/badge_logo.svg
8+
:target: https://mybinder.org/v2/gh/wind-python/windpowerlib/dev?filepath=example
79

810
Introduction
911
=============
@@ -50,26 +52,28 @@ Matplotlib can be installed using pip:
5052
Examples and basic usage
5153
=========================
5254

55+
The simplest way to run the example notebooks without installing windpowerlib is to click `here <https://mybinder.org/v2/gh/wind-python/windpowerlib/dev?filepath=example>`_ and open them with Binder.
56+
5357
The basic usage of the windpowerlib is shown in the `ModelChain example <http://windpowerlib.readthedocs.io/en/stable/modelchain_example_notebook.html>`_ that is available as jupyter notebook and python script:
5458

55-
* `ModelChain example (Python script) <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/modelchain_example.py>`_
56-
* `ModelChain example (Jupyter notebook) <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/modelchain_example.ipynb>`_
59+
* `ModelChain example (Python script) <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/modelchain_example.py>`_
60+
* `ModelChain example (Jupyter notebook) <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/modelchain_example.ipynb>`_
5761

5862
To run the example you need the example weather and turbine data used:
5963

60-
* `Example weather data file <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/weather.csv>`_
61-
* `Example power curve data file <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/data/example_power_curves.csv>`_
62-
* `Example power coefficient curve data file <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/data/example_power_coefficient_curves.csv>`_
63-
* `Example nominal power data file <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/data/example_turbine_data.csv>`_
64+
* `Example weather data file <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/weather.csv>`_
65+
* `Example power curve data file <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/data/example_power_curves.csv>`_
66+
* `Example power coefficient curve data file <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/data/example_power_coefficient_curves.csv>`_
67+
* `Example nominal power data file <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/data/example_turbine_data.csv>`_
6468

65-
Furthermore, you have to install the windpowerlib. To run the notebook you also need to install `notebook` using pip3. To launch jupyter notebook type ``jupyter notebook`` in the terminal.
69+
To run the examples locally you have to install windpowerlib. To run the notebook you also need to install `notebook` using pip3. To launch jupyter notebook type ``jupyter notebook`` in the terminal.
6670
This will open a browser window. Navigate to the directory containing the notebook to open it. See the jupyter notebook quick start guide for more information on `how to install <http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/install.html>`_ and
67-
`how to run <http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/execute.html>`_ jupyter notebooks.
71+
`how to run <http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/execute.html>`_ jupyter notebooks. In order to reproduce the figures in a notebook you need to install `matplotlib`.
6872

6973
Further functionalities, like the modelling of wind farms and wind turbine clusters, are shown in the `TurbineClusterModelChain example <http://windpowerlib.readthedocs.io/en/stable/turbine_cluster_modelchain_example_notebook.html>`_. As the ModelChain example it is available as jupyter notebook and as python script. The weather and turbine datadata used in this example is the same as in the example above.
7074

71-
* `TurbineClusterModelChain example (Python script) <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/turbine_cluster_modelchain_example.py>`_
72-
* `TurbineClusterModelChain example (Jupyter notebook) <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/turbine_cluster_modelchain_example.ipynb>`_
75+
* `TurbineClusterModelChain example (Python script) <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/turbine_cluster_modelchain_example.py>`_
76+
* `TurbineClusterModelChain example (Jupyter notebook) <https://raw.githubusercontent.com/wind-python/windpowerlib/master/example/turbine_cluster_modelchain_example.ipynb>`_
7377

7478
You can also look at the examples in the `Examples section <http://windpowerlib.readthedocs.io/en/stable/examples.html>`_.
7579

@@ -153,4 +157,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
153157
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
154158
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
155159
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
156-
SOFTWARE.
160+
SOFTWARE.

example/modelchain_example.ipynb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,6 @@
139139
" weather_df.index = pd.to_datetime(weather_df.index).tz_convert(\n",
140140
" 'Europe/Berlin')\n",
141141
" \n",
142-
" # change type of height from str to int by resetting columns\n",
143-
" l0 = [_[0] for _ in weather_df.columns]\n",
144-
" l1 = [int(_[1]) for _ in weather_df.columns]\n",
145-
" weather_df.columns = [l0, l1]\n",
146-
" \n",
147142
" return weather_df\n",
148143
"\n",
149144
"\n",

example/modelchain_example.py

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,24 @@ def get_weather_data(filename='weather.csv', **kwargs):
6464
6565
"""
6666

67-
if 'datapath' not in kwargs:
68-
kwargs['datapath'] = os.path.join(os.path.split(
69-
os.path.dirname(__file__))[0], 'example')
70-
file = os.path.join(kwargs['datapath'], filename)
67+
if "datapath" not in kwargs:
68+
kwargs["datapath"] = os.path.join(
69+
os.path.split(os.path.dirname(__file__))[0], "example"
70+
)
71+
file = os.path.join(kwargs["datapath"], filename)
7172

7273
# read csv file
7374
weather_df = pd.read_csv(
74-
file, index_col=0, header=[0, 1],
75-
date_parser=lambda idx: pd.to_datetime(idx, utc=True))
75+
file,
76+
index_col=0,
77+
header=[0, 1],
78+
date_parser=lambda idx: pd.to_datetime(idx, utc=True),
79+
)
7680

7781
# change type of index to datetime and set time zone
7882
weather_df.index = pd.to_datetime(weather_df.index).tz_convert(
79-
'Europe/Berlin')
80-
81-
# change type of height from str to int by resetting columns
82-
l0 = [_[0] for _ in weather_df.columns]
83-
l1 = [int(_[1]) for _ in weather_df.columns]
84-
weather_df.columns = [l0, l1]
83+
"Europe/Berlin"
84+
)
8585

8686
return weather_df
8787

@@ -112,33 +112,38 @@ def initialize_wind_turbines():
112112
# specification of wind turbine where data is provided in the oedb
113113
# turbine library
114114
enercon_e126 = {
115-
'turbine_type': 'E-126/4200', # turbine type as in register
116-
'hub_height': 135 # in m
115+
"turbine_type": "E-126/4200", # turbine type as in register
116+
"hub_height": 135, # in m
117117
}
118118
# initialize WindTurbine object
119119
e126 = WindTurbine(**enercon_e126)
120120

121121
# specification of own wind turbine (Note: power values and nominal power
122122
# have to be in Watt)
123123
my_turbine = {
124-
'nominal_power': 3e6, # in W
125-
'hub_height': 105, # in m
126-
'power_curve': pd.DataFrame(
127-
data={'value': [p * 1000 for p in [
128-
0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]], # in W
129-
'wind_speed': [0.0, 3.0, 5.0, 10.0, 15.0, 25.0]}) # in m/s
124+
"nominal_power": 3e6, # in W
125+
"hub_height": 105, # in m
126+
"power_curve": pd.DataFrame(
127+
data={
128+
"value": [
129+
p * 1000
130+
for p in [0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]
131+
], # in W
132+
"wind_speed": [0.0, 3.0, 5.0, 10.0, 15.0, 25.0],
133+
}
134+
), # in m/s
130135
}
131136
# initialize WindTurbine object
132137
my_turbine = WindTurbine(**my_turbine)
133138

134139
# specification of wind turbine where power coefficient curve and nominal
135140
# power is provided in an own csv file
136-
csv_path = os.path.join(os.path.dirname(__file__), 'data')
141+
csv_path = os.path.join(os.path.dirname(__file__), "data")
137142
dummy_turbine = {
138-
'turbine_type': "DUMMY 1",
139-
'hub_height': 100, # in m
140-
'rotor_diameter': 70, # in m
141-
'path': csv_path
143+
"turbine_type": "DUMMY 1",
144+
"hub_height": 100, # in m
145+
"rotor_diameter": 70, # in m
146+
"path": csv_path,
142147
}
143148
# initialize WindTurbine object
144149
dummy_turbine = WindTurbine(**dummy_turbine)
@@ -182,18 +187,19 @@ def calculate_power_output(weather, my_turbine, e126, dummy_turbine):
182187
# power output calculation for e126
183188
# own specifications for ModelChain setup
184189
modelchain_data = {
185-
'wind_speed_model': 'logarithmic', # 'logarithmic' (default),
186-
# 'hellman' or
187-
# 'interpolation_extrapolation'
188-
'density_model': 'ideal_gas', # 'barometric' (default), 'ideal_gas' or
189-
# 'interpolation_extrapolation'
190-
'temperature_model': 'linear_gradient', # 'linear_gradient' (def.) or
191-
# 'interpolation_extrapolation'
192-
'power_output_model': 'power_curve', # 'power_curve' (default) or
193-
# 'power_coefficient_curve'
194-
'density_correction': True, # False (default) or True
195-
'obstacle_height': 0, # default: 0
196-
'hellman_exp': None} # None (default) or None
190+
"wind_speed_model": "logarithmic", # 'logarithmic' (default),
191+
# 'hellman' or
192+
# 'interpolation_extrapolation'
193+
"density_model": "ideal_gas", # 'barometric' (default), 'ideal_gas' or
194+
# 'interpolation_extrapolation'
195+
"temperature_model": "linear_gradient", # 'linear_gradient' (def.) or
196+
# 'interpolation_extrapolation'
197+
"power_output_model": "power_curve", # 'power_curve' (default) or
198+
# 'power_coefficient_curve'
199+
"density_correction": True, # False (default) or True
200+
"obstacle_height": 0, # default: 0
201+
"hellman_exp": None,
202+
} # None (default) or None
197203
# initialize ModelChain with own specifications and use run_model method
198204
# to calculate power output
199205
mc_e126 = ModelChain(e126, **modelchain_data).run_model(weather)
@@ -203,8 +209,8 @@ def calculate_power_output(weather, my_turbine, e126, dummy_turbine):
203209
# power output calculation for example_turbine
204210
# own specification for 'power_output_model'
205211
mc_example_turbine = ModelChain(
206-
dummy_turbine,
207-
power_output_model='power_coefficient_curve').run_model(weather)
212+
dummy_turbine, power_output_model="power_coefficient_curve"
213+
).run_model(weather)
208214
dummy_turbine.power_output = mc_example_turbine.power_output
209215

210216
return
@@ -272,7 +278,7 @@ def run_example():
272278
Runs the basic example.
273279
274280
"""
275-
weather = get_weather_data('weather.csv')
281+
weather = get_weather_data("weather.csv")
276282
my_turbine, e126, dummy_turbine = initialize_wind_turbines()
277283
calculate_power_output(weather, my_turbine, e126, dummy_turbine)
278284
plot_or_print(my_turbine, e126, dummy_turbine)

example/test_examples.py

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,45 @@
1515

1616

1717
class TestExamples:
18-
1918
def test_modelchain_example_flh(self):
2019
# tests full load hours
21-
weather = mc_e.get_weather_data('weather.csv')
20+
weather = mc_e.get_weather_data("weather.csv")
2221
my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()
2322
mc_e.calculate_power_output(weather, my_turbine, e126, dummy_turbine)
2423

25-
assert_allclose(2764.194772, (e126.power_output.sum() /
26-
e126.nominal_power), 0.01)
27-
assert_allclose(1882.7567, (my_turbine.power_output.sum() /
28-
my_turbine.nominal_power), 0.01)
24+
assert_allclose(
25+
2764.194772, (e126.power_output.sum() / e126.nominal_power), 0.01
26+
)
27+
assert_allclose(
28+
1882.7567,
29+
(my_turbine.power_output.sum() / my_turbine.nominal_power),
30+
0.01,
31+
)
2932

3033
def test_turbine_cluster_modelchain_example_flh(self):
3134
# tests full load hours
32-
weather = mc_e.get_weather_data('weather.csv')
35+
weather = mc_e.get_weather_data("weather.csv")
3336
my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()
3437
example_farm, example_farm_2 = tc_mc_e.initialize_wind_farms(
35-
my_turbine, e126)
38+
my_turbine, e126
39+
)
3640
example_cluster = tc_mc_e.initialize_wind_turbine_cluster(
37-
example_farm, example_farm_2)
41+
example_farm, example_farm_2
42+
)
3843
tc_mc_e.calculate_power_output(weather, example_farm, example_cluster)
39-
assert_allclose(1956.164053, (example_farm.power_output.sum() /
40-
example_farm.nominal_power), 0.01)
41-
assert_allclose(2156.794154, (example_cluster.power_output.sum() /
42-
example_cluster.nominal_power), 0.01)
44+
assert_allclose(
45+
1956.164053,
46+
(example_farm.power_output.sum() / example_farm.nominal_power),
47+
0.01,
48+
)
49+
assert_allclose(
50+
2156.794154,
51+
(
52+
example_cluster.power_output.sum()
53+
/ example_cluster.nominal_power
54+
),
55+
0.01,
56+
)
4357

4458
def _notebook_run(self, path):
4559
"""
@@ -49,30 +63,44 @@ def _notebook_run(self, path):
4963
dirname, __ = os.path.split(path)
5064
os.chdir(dirname)
5165
with tempfile.NamedTemporaryFile(suffix=".ipynb") as fout:
52-
args = ["jupyter", "nbconvert", "--to", "notebook", "--execute",
53-
"--ExecutePreprocessor.timeout=60",
54-
"--output", fout.name, path]
66+
args = [
67+
"jupyter",
68+
"nbconvert",
69+
"--to",
70+
"notebook",
71+
"--execute",
72+
"--ExecutePreprocessor.timeout=60",
73+
"--output",
74+
fout.name,
75+
path,
76+
]
5577
subprocess.check_call(args)
5678

5779
fout.seek(0)
5880
nb = nbformat.read(fout, nbformat.current_nbformat)
5981

60-
errors = [output for cell in nb.cells if "outputs" in cell
61-
for output in cell["outputs"]
62-
if output.output_type == "error"]
82+
errors = [
83+
output
84+
for cell in nb.cells
85+
if "outputs" in cell
86+
for output in cell["outputs"]
87+
if output.output_type == "error"
88+
]
6389

6490
return nb, errors
6591

6692
@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6")
6793
def test_modelchain_example_ipynb(self):
6894
dir_path = os.path.dirname(os.path.realpath(__file__))
6995
nb, errors = self._notebook_run(
70-
os.path.join(dir_path, 'modelchain_example.ipynb'))
96+
os.path.join(dir_path, "modelchain_example.ipynb")
97+
)
7198
assert errors == []
7299

73100
@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6")
74101
def test_turbine_cluster_modelchain_example_ipynb(self):
75102
dir_path = os.path.dirname(os.path.realpath(__file__))
76103
nb, errors = self._notebook_run(
77-
os.path.join(dir_path, 'turbine_cluster_modelchain_example.ipynb'))
104+
os.path.join(dir_path, "turbine_cluster_modelchain_example.ipynb")
105+
)
78106
assert errors == []

0 commit comments

Comments
 (0)