Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 47 additions & 15 deletions tests/test_modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@

import windpowerlib.wind_turbine as wt
import windpowerlib.modelchain as mc
from windpowerlib.tools import WindpowerlibUserWarning


class TestModelChain:
@classmethod
def setup_class(self):
def setup_class(cls):
"""Setup default values"""
self.test_turbine = {
cls.test_turbine = {
"hub_height": 100,
"turbine_type": "E-126/4200",
"power_curve": pd.DataFrame(
Expand All @@ -31,7 +32,7 @@ def setup_class(self):
wind_speed_8m = np.array([[4.0], [5.0]])
wind_speed_10m = np.array([[5.0], [6.5]])
roughness_length = np.array([[0.15], [0.15]])
self.weather_df = pd.DataFrame(
cls.weather_df = pd.DataFrame(
np.hstack(
(
temperature_2m,
Expand Down Expand Up @@ -434,23 +435,54 @@ def test_modelchain_with_power_coefficient_curve_as_dict(self):

def test_heigths_as_string(self):
"""Test run_model if data heights are of type string."""
test_turbine = {'hub_height': 100,
'rotor_diameter': 80,
'turbine_type': 'E-126/4200'}
test_turbine = {
"hub_height": 100,
"rotor_diameter": 80,
"turbine_type": "E-126/4200",
}

# Convert data heights to str
string_weather = self.weather_df.copy()
string_weather.columns = pd.MultiIndex.from_arrays([
string_weather.columns.get_level_values(0),
string_weather.columns.get_level_values(1).astype(str)])
string_weather.columns = pd.MultiIndex.from_arrays(
[
string_weather.columns.get_level_values(0),
string_weather.columns.get_level_values(1).astype(str),
]
)

# Heights in the original DataFrame are of type np.int64
assert isinstance(self.weather_df.columns.get_level_values(1)[0],
np.int64)
assert isinstance(
self.weather_df.columns.get_level_values(1)[0], np.int64
)
assert isinstance(string_weather.columns.get_level_values(1)[0], str)

test_modelchain = {'power_output_model': 'power_curve',
'density_corr': True}
test_mc = mc.ModelChain(wt.WindTurbine(**test_turbine),
**test_modelchain)
test_modelchain = {
"power_output_model": "power_curve",
"density_corr": True,
}
test_mc = mc.ModelChain(
wt.WindTurbine(**test_turbine), **test_modelchain
)
test_mc.run_model(string_weather)

def test_weather_with_nan_values(self, recwarn):
"""Test warning if weather data contain nan values."""
test_turbine = {
"hub_height": 100,
"rotor_diameter": 80,
"turbine_type": "E-126/4200",
}
nan_weather = self.weather_df.copy()
nan_weather.loc[1, ("temperature", 10)] = np.nan
test_modelchain = {
"power_output_model": "power_curve",
"density_corr": True,
}
test_mc = mc.ModelChain(
wt.WindTurbine(**test_turbine), **test_modelchain
)
msg = "'temperature', 10"
with pytest.warns(WindpowerlibUserWarning, match=msg):
test_mc.run_model(nan_weather)
test_mc.run_model(self.weather_df)
assert len(recwarn) == 0
8 changes: 2 additions & 6 deletions windpowerlib/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
"""
import logging
import pandas as pd
from windpowerlib import (wind_speed, density, temperature, power_output,
tools)
from windpowerlib import wind_speed, density, temperature, power_output, tools


class ModelChain(object):
Expand Down Expand Up @@ -511,10 +510,7 @@ def run_model(self, weather_df):
'wind_speed'

"""
# Convert data heights to integer. In some case they are strings.
weather_df.columns = pd.MultiIndex.from_arrays([
weather_df.columns.get_level_values(0),
pd.to_numeric(weather_df.columns.get_level_values(1))])
weather_df = tools.check_weather_data(weather_df)

wind_speed_hub = self.wind_speed_hub(weather_df)
density_hub = (
Expand Down
28 changes: 28 additions & 0 deletions windpowerlib/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""
import numpy as np
import warnings
import pandas as pd


class WindpowerlibUserWarning(UserWarning):
Expand Down Expand Up @@ -221,3 +222,30 @@ def estimate_turbulence_intensity(height, roughness_length):

"""
return 1 / (np.log(height / roughness_length))


def check_weather_data(weather_df):
"""
Check weather Data Frame.

- Raise warning if there are nan values.
- Convert columns if heights are string and not numeric.

"""
# Convert data heights to integer. In some case they are strings.
weather_df.columns = pd.MultiIndex.from_arrays(
[
weather_df.columns.get_level_values(0),
pd.to_numeric(weather_df.columns.get_level_values(1)),
]
)

# check for nan values
if weather_df.isnull().any().any():
nan_columns = list(weather_df.columns[weather_df.isnull().any()])
msg = (
"The following columns of the weather data contain invalid "
"values like 'nan': {0}"
)
warnings.warn(msg.format(nan_columns), WindpowerlibUserWarning)
return weather_df
7 changes: 2 additions & 5 deletions windpowerlib/turbine_cluster_modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import logging
import pandas as pd
from windpowerlib import wake_losses
from windpowerlib.modelchain import ModelChain
from windpowerlib.modelchain import ModelChain, tools


class TurbineClusterModelChain(ModelChain):
Expand Down Expand Up @@ -289,10 +289,7 @@ def run_model(self, weather_df):
'wind_speed'

"""
# Convert data heights to integer. In some case they are strings.
weather_df.columns = pd.MultiIndex.from_arrays([
weather_df.columns.get_level_values(0),
pd.to_numeric(weather_df.columns.get_level_values(1))])
weather_df = tools.check_weather_data(weather_df)

self.assign_power_curve(weather_df)
self.power_plant.mean_hub_height()
Expand Down