Skip to content

Commit 200bf5b

Browse files
committed
Adapt modelchain to multiindex dataframe
1 parent 1fa50b5 commit 200bf5b

File tree

1 file changed

+85
-81
lines changed

1 file changed

+85
-81
lines changed

windpowerlib/modelchain.py

Lines changed: 85 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class ModelChain(object):
9292
def __init__(self, wind_turbine,
9393
obstacle_height=0,
9494
wind_model='logarithmic',
95+
temp_model='temperature_gradient',
9596
rho_model='barometric',
9697
power_output_model='p_values',
9798
density_corr=False,
@@ -100,13 +101,14 @@ def __init__(self, wind_turbine,
100101
self.wind_turbine = wind_turbine
101102
self.obstacle_height = obstacle_height
102103
self.wind_model = wind_model
104+
self.temp_model = temp_model
103105
self.rho_model = rho_model
104106
self.power_output_model = power_output_model
105107
self.density_corr = density_corr
106108
self.hellman_exp = hellman_exp
107109
self.power_output = None
108110

109-
def rho_hub(self, weather, data_height):
111+
def rho_hub(self, weather):
110112
r"""
111113
Calculates the density of air at hub height.
112114
@@ -122,62 +124,68 @@ def rho_hub(self, weather, data_height):
122124
optionally the temperature `temp_air_2` in K at a different height.
123125
If a Dictionary is used the data inside the dictionary has to be of
124126
the types pandas.Series or numpy.array.
125-
data_height : Dictionary
126-
Containing columns or keys with the heights in m for which the
127-
corresponding parameters in `weather` apply.
128127
129128
Returns
130129
-------
131130
rho_hub : pandas.Series or numpy.array
132131
Density of air in kg/m³ at hub height.
133132
134133
"""
135-
# Check if temperature data is at hub height.
136-
if 'temp_air_2' not in weather:
137-
weather['temp_air_2'] = None
138-
data_height['temp_air_2'] = None
139-
temperature_height = data_height['temp_air']
140-
temperature_closest = weather['temp_air']
141-
else:
142-
# Select temperature closer to hub height using
143-
# smallest_difference()
144-
temperature_height, temperature_closest = tools.smallest_difference(
145-
pd.DataFrame(data={'temp_air': [weather['temp_air'],
146-
weather['temp_air_2']]},
147-
index=[data_height['temp_air'],
148-
data_height['temp_air_2']]),
149-
self.wind_turbine.hub_height, 'temp_air')
150-
# Check if temperature data is at hub height.
151-
if temperature_height == self.wind_turbine.hub_height:
152-
logging.debug('Using given temperature at hub height.')
153-
temp_hub = temperature_closest
154-
# Calculation of temperature in K at hub height.
155-
else:
156-
logging.debug('Calculating temperature using a temp. gradient.')
157-
temp_hub = density.temperature_gradient(
158-
temperature_closest, temperature_height,
159-
self.wind_turbine.hub_height)
134+
try:
135+
temp_hub = weather['temp'][self.wind_turbine.hub_height]
136+
except:
137+
if self.temp_model == 'temperature_gradient':
138+
logging.debug('Calculating temperature using temperature'
139+
'gradient.')
140+
closest_height = weather['temp_air'].columns[
141+
min(range(len(weather['temp_air'].columns)),
142+
key=lambda i: abs(weather['temp_air'].columns[i] -
143+
self.wind_turbine.hub_height))]
144+
temp_hub = density.temperature_gradient(
145+
weather['temp_air'][closest_height], closest_height,
146+
self.obstacle_height)
147+
elif self.temp_model == 'linear':
148+
logging.debug('Calculating wind using linear inter- or'
149+
'extrapolation.')
150+
temp_hub = tools.linear_extra_interpolation(
151+
weather['temp_air'], self.wind_turbine.hub_height)
152+
else:
153+
raise ValueError("'{0}' is an invalid value.".format(
154+
self.wind_model) + "`wind_model` must be 'logarithmic',"
155+
"'hellman' or 'linear'.")
160156

161157
# Calculation of density in kg/m³ at hub height
162158
if self.rho_model == 'barometric':
163-
logging.debug('Calculating density using barometric height eq.')
164-
rho_hub = density.rho_barometric(weather['pressure'],
165-
data_height['pressure'],
166-
self.wind_turbine.hub_height,
167-
temp_hub)
159+
logging.debug('Calculating density using barometric height'
160+
'equation.')
161+
closest_height = weather['pressure'].columns[
162+
min(range(len(weather['pressure'].columns)),
163+
key=lambda i: abs(weather['pressure'].columns[i] -
164+
self.wind_turbine.hub_height))]
165+
rho_hub = density.rho_barometric(
166+
weather['pressure'][closest_height], closest_height,
167+
self.wind_turbine.hub_height, temp_hub)
168168
elif self.rho_model == 'ideal_gas':
169169
logging.debug('Calculating density using ideal gas equation.')
170-
rho_hub = density.rho_ideal_gas(weather['pressure'],
171-
data_height['pressure'],
172-
self.wind_turbine.hub_height,
173-
temp_hub)
170+
closest_height = weather['pressure'].columns[
171+
min(range(len(weather['pressure'].columns)),
172+
key=lambda i: abs(weather['pressure'].columns[i] -
173+
self.wind_turbine.hub_height))]
174+
rho_hub = density.rho_ideal_gas(
175+
weather['pressure'][closest_height], closest_height,
176+
self.wind_turbine.hub_height, temp_hub)
177+
elif self.rho_model == 'linear':
178+
logging.debug('Calculating density using linear inter- or'
179+
'extrapolation.')
180+
rho_hub = tools.linear_extra_interpolation(
181+
weather['density'], self.wind_turbine.hub_height)
174182
else:
175183
raise ValueError("'{0}' is an invalid value.".format(
176184
self.rho_model) + "`rho_model` " +
177-
"must be 'barometric' or 'ideal_gas'.")
185+
"must be 'barometric', 'ideal_gas' or 'linear'.")
178186
return rho_hub
179187

180-
def v_wind_hub(self, weather, data_height):
188+
def v_wind_hub(self, weather):
181189
r"""
182190
Calculates the wind speed at hub height.
183191
@@ -191,9 +199,6 @@ def v_wind_hub(self, weather, data_height):
191199
optionally wind speed `v_wind_2` in m/s at different height.
192200
If a Dictionary is used the data inside the dictionary has to be of
193201
the types pandas.Series or numpy.array.
194-
data_height : Dictionary
195-
Containing columns or keys with the heights in m for which the
196-
corresponding parameters in `weather` apply.
197202
198203
Returns
199204
-------
@@ -206,38 +211,40 @@ def v_wind_hub(self, weather, data_height):
206211
with `v_wind` of which data height is closer to hub height.
207212
208213
"""
209-
if 'v_wind_2' not in weather:
210-
weather['v_wind_2'] = None
211-
data_height['v_wind_2'] = None
212-
v_wind_height = data_height['v_wind']
213-
v_wind_closest = weather['v_wind']
214-
else:
215-
# Select wind speed closer to hub height using smallest_difference()
216-
v_wind_height, v_wind_closest = tools.smallest_difference(
217-
pd.DataFrame(data={'v_wind': [weather['v_wind'],
218-
weather['v_wind_2']]},
219-
index=[data_height['v_wind'],
220-
data_height['v_wind_2']]),
221-
self.wind_turbine.hub_height, 'v_wind')
222-
# Check if wind speed data is at hub height.
223-
if v_wind_height == self.wind_turbine.hub_height:
224-
logging.debug('Using given wind speed at hub height.')
225-
v_wind = v_wind_closest
226-
# Calculation of wind speed in m/s at hub height.
227-
elif self.wind_model == 'logarithmic':
228-
logging.debug('Calculating v_wind using logarithmic wind profile.')
229-
v_wind = wind_speed.logarithmic_wind_profile(
230-
v_wind_closest, v_wind_height, self.wind_turbine.hub_height,
231-
weather['z0'], self.obstacle_height)
232-
elif self.wind_model == 'hellman':
233-
logging.debug('Calculating v_wind using hellman equation.')
234-
v_wind = wind_speed.v_wind_hellman(v_wind_closest, v_wind_height,
235-
self.wind_turbine.hub_height,
236-
weather['z0'], self.hellman_exp)
237-
else:
238-
raise ValueError("'{0}' is an invalid value.".format(
239-
self.wind_model) + "`wind_model` " +
240-
"must be 'logarithmic' or 'hellman'.")
214+
try:
215+
v_wind = weather['v_wind'][self.wind_turbine.hub_height]
216+
except:
217+
if self.wind_model == 'logarithmic':
218+
logging.debug('Calculating wind speed using logarithmic wind'
219+
'profile.')
220+
closest_height = weather['v_wind'].columns[
221+
min(range(len(weather['v_wind'].columns)),
222+
key=lambda i: abs(weather['v_wind'].columns[i] -
223+
self.wind_turbine.hub_height))]
224+
v_wind = wind_speed.logarithmic_wind_profile(
225+
weather['v_wind'][closest_height], closest_height,
226+
self.wind_turbine.hub_height, weather['z0'].ix[:,0],
227+
self.obstacle_height)
228+
elif self.wind_model == 'hellman':
229+
logging.debug('Calculating windspeed using hellman equation.')
230+
closest_height = weather['v_wind'].columns[
231+
min(range(len(weather['v_wind'].columns)),
232+
key=lambda i: abs(weather['v_wind'].columns[i] -
233+
self.wind_turbine.hub_height))]
234+
v_wind = wind_speed.v_wind_hellman(
235+
weather['v_wind'][closest_height], closest_height,
236+
self.wind_turbine.hub_height, weather['z0'].ix[:,0],
237+
self.hellman_exp)
238+
elif self.wind_model == 'linear':
239+
logging.debug('Calculating wind speed using linear inter- or'
240+
'extrapolation.')
241+
v_wind = tools.linear_extra_interpolation(
242+
weather['v_wind'], self.wind_turbine.hub_height)
243+
else:
244+
raise ValueError("'{0}' is an invalid value.".format(
245+
self.wind_model) + "`wind_model` must be 'logarithmic',"
246+
"'hellman' or 'linear'.")
247+
241248
return v_wind
242249

243250
def turbine_power_output(self, wind_speed, density):
@@ -304,7 +311,7 @@ def turbine_power_output(self, wind_speed, density):
304311
"must be 'cp_values' or 'p_values'.")
305312
return output
306313

307-
def run_model(self, weather, data_height):
314+
def run_model(self, weather):
308315
r"""
309316
Runs the model.
310317
@@ -318,18 +325,15 @@ def run_model(self, weather, data_height):
318325
`temp_air_2` in K at different height.
319326
If a Dictionary is used the data inside the dictionary has to be of
320327
the types pandas.Series or numpy.array.
321-
data_height : Dictionary
322-
Containing columns or keys with the heights in m for which the
323-
corresponding parameters in `weather` apply.
324328
325329
Returns
326330
-------
327331
self
328332
329333
"""
330-
wind_speed = self.v_wind_hub(weather, data_height)
334+
wind_speed = self.v_wind_hub(weather)
331335
density = None if (self.power_output_model == 'p_values' and
332336
self.density_corr is False) \
333-
else self.rho_hub(weather, data_height)
337+
else self.rho_hub(weather)
334338
self.power_output = self.turbine_power_output(wind_speed, density)
335339
return self

0 commit comments

Comments
 (0)