@@ -171,6 +171,10 @@ def fetch_turbine_data(self, fetch_curve, data_source):
171171 4200000.0
172172
173173 """
174+ if fetch_curve not in ['power_curve' , 'power_coefficient_curve' ]:
175+ raise ValueError ("'{0}' is an invalid value for " .format (
176+ fetch_curve ) + "`fetch_curve`. Must be " +
177+ "'power_curve' or 'power_coefficient_curve'." )
174178 if data_source == 'oedb' :
175179 curve_df , nominal_power = get_turbine_data_from_oedb (
176180 turbine_type = self .name , fetch_curve = fetch_curve )
@@ -181,10 +185,6 @@ def fetch_turbine_data(self, fetch_curve, data_source):
181185 self .power_curve = curve_df
182186 elif fetch_curve == 'power_coefficient_curve' :
183187 self .power_coefficient_curve = curve_df
184- else :
185- raise ValueError ("'{0}' is an invalid value. " .format (
186- fetch_curve ) + "`fetch_curve` must be " +
187- "'power_curve' or 'power_coefficient_curve'." )
188188 if self .nominal_power is None :
189189 self .nominal_power = nominal_power
190190 return self
@@ -202,15 +202,15 @@ def get_turbine_data_from_file(turbine_type, file_):
202202
203203 Parameters
204204 ----------
205- turbine_type : string
205+ turbine_type : str
206206 Specifies the turbine type data is fetched for.
207- file_ : string
207+ file_ : str
208208 Specifies the source of the turbine data.
209209 See the example below for how to use the example data.
210210
211211 Returns
212212 -------
213- Tuple (pandas.DataFrame, float)
213+ tuple (pandas.DataFrame, float)
214214 Power curve or power coefficient curve (pandas.DataFrame) and nominal
215215 power (float). Power (coefficient) curve DataFrame contains power
216216 coefficient curve values (dimensionless) or power curve values in W
@@ -246,11 +246,17 @@ def isfloat(x):
246246 df = pd .read_csv (file_ , index_col = 0 )
247247 except FileNotFoundError :
248248 raise FileNotFoundError ("The file '{}' was not found." .format (file_ ))
249- wpp_df = df [df .turbine_id == turbine_type ]
249+ # todo: note: this try except statement will be removed in 0.2.0 and only
250+ # the exception will stay. The example power (coefficient) curve files
251+ # will then be adapted
252+ try :
253+ wpp_df = df [df ['turbine_id' ] == turbine_type ]
254+ except KeyError :
255+ wpp_df = df [df .index == turbine_type ]
250256 # if turbine not in data file
251257 if wpp_df .shape [0 ] == 0 :
252258 pd .set_option ('display.max_rows' , len (df ))
253- logging .info ('Possible types: \n {0}' .format (df . turbine_id ))
259+ logging .info ('Possible types: \n {0}' .format (df [ ' turbine_id' ] ))
254260 pd .reset_option ('display.max_rows' )
255261 sys .exit ('Cannot find the wind converter type: {0}' .format (
256262 turbine_type ))
@@ -261,73 +267,62 @@ def isfloat(x):
261267 df = curve_data .transpose ().reset_index ()
262268 df .columns = ['wind_speed' , 'value' ]
263269 df ['wind_speed' ] = df ['wind_speed' ].apply (lambda x : float (x ))
264- nominal_power = wpp_df ['p_nom' ].iloc [0 ]
270+ # todo: note: this try except statement will be removed in 0.2.0 and only
271+ # the exception will stay. The example power (coefficient) curve files
272+ # will then be adapted
273+ try :
274+ nominal_power = wpp_df ['p_nom' ].iloc [0 ]
275+ except KeyError :
276+ nominal_power = float (wpp_df ['nominal_power' ].iloc [0 ])
265277 return df , nominal_power
266278
267279
268280def get_turbine_data_from_oedb (turbine_type , fetch_curve , overwrite = False ):
269281 r"""
270- Fetches data for one wind turbine type from the OpenEnergy Database (oedb).
282+ Fetches wind turbine data from the OpenEnergy database (oedb).
271283
272284 If turbine data exists in local repository it is loaded from this file. The
273- file is created when turbine data was loaded from oedb in
285+ file is created when turbine data is loaded from oedb in
274286 :py:func:`~.load_turbine_data_from_oedb`. Use this function with
275287 `overwrite=True` to overwrite your file with newly fetched data.
276- Use :py:func:`~.check_local_turbine_data` to check
277- weather your local file is up to date.
278288
279289 Parameters
280290 ----------
281- turbine_type : string
291+ turbine_type : str
282292 Specifies the turbine type data is fetched for.
283293 Use :py:func:`~.get_turbine_types` to see a table of all wind turbines
284- for which power (coefficient) curve data is provided.
285- fetch_curve : string
294+ in oedb containing information about whether power (coefficient) curve
295+ data is provided.
296+ fetch_curve : str
286297 Parameter to specify whether a power or power coefficient curve
287298 should be retrieved from the provided turbine data. Valid options are
288299 'power_curve' and 'power_coefficient_curve'. Default: None.
289- overwrite : boolean
290- If True local file is overwritten by newly fetch data from oedb, if
300+ overwrite : bool
301+ If True local file is overwritten by newly fetched data from oedb, if
291302 False turbine data is fetched from previously saved file.
292303
293304 Returns
294305 -------
295- Tuple (pandas.DataFrame, float)
306+ tuple (pandas.DataFrame, float)
296307 Power curve or power coefficient curve (pandas.DataFrame) and nominal
297308 power (float) of one wind turbine type. Power (coefficient) curve
298309 DataFrame contains power coefficient curve values (dimensionless) or
299310 power curve values in W with the corresponding wind speeds in m/s.
300311
301312 """
302- # hdf5 filename
303313 filename = os .path .join (os .path .dirname (__file__ ), 'data' ,
304- 'turbine_data_oedb.h5' )
305- if os .path .isfile (filename ) and not overwrite :
306- logging .debug ("Turbine data is fetched from {}" .format (filename ))
307- with pd .HDFStore (filename ) as hdf_store :
308- turbine_data = hdf_store .get ('turbine_data' )
309- else :
310- turbine_data = load_turbine_data_from_oedb ()
311- turbine_data .set_index ('turbine_type' , inplace = True )
312- # Set `curve` depending on `fetch_curve` to match names in oedb
313- curve = ('cp_curve' if fetch_curve == 'power_coefficient_curve'
314- else fetch_curve )
315- # Select curve and nominal power of turbine type
316- try :
317- df = turbine_data .loc [turbine_type ]
318- except KeyError :
319- raise KeyError ("Turbine type '{}' not in database. " .format (
320- turbine_type ) + "Use 'get_turbine_types()' to see a table of " +
321- "possible wind turbine types." )
322- if df [curve ] is not None :
323- df = pd .DataFrame (df [curve ])
314+ 'oedb_{}s.csv' .format (fetch_curve ))
315+ if not os .path .isfile (filename ) or overwrite :
316+ # Load data from oedb and save to csv file
317+ load_turbine_data_from_oedb ()
324318 else :
325- sys .exit ("{} of {} not available in " .format (curve , turbine_type ) +
326- "oedb. Use 'get_turbine_types()' to see for which turbine " +
327- "types power coefficient curves are available." )
328- nominal_power = turbine_data .loc [turbine_type ][
329- 'installed_capacity_kw' ] * 1000
330- df .columns = ['wind_speed' , 'value' ]
319+ logging .debug ("Turbine data is fetched from {}" .format (filename ))
320+ # turbine_data = pd.read_csv(filename, index_col=0)
321+ df , nominal_power = get_turbine_data_from_file (turbine_type = turbine_type ,
322+ file_ = filename )
323+
324+ # nominal power and power curve values in W
325+ nominal_power = nominal_power * 1000
331326 if fetch_curve == 'power_curve' :
332327 # power in W
333328 df ['value' ] = df ['value' ] * 1000
@@ -336,64 +331,103 @@ def get_turbine_data_from_oedb(turbine_type, fetch_curve, overwrite=False):
336331
337332def load_turbine_data_from_oedb ():
338333 r"""
339- Loads turbine data from the OpenEnergy Database (oedb).
334+ Loads turbine data from the OpenEnergy database (oedb).
340335
341- Turbine data is saved to `filename` for offline usage of windpowerlib.
336+ Turbine data is saved to csv files ('oedb_power_curves.csv' and
337+ 'oedb_power_coefficient_curves.csv') for offline usage of windpowerlib.
338+ If the files already exist they are overwritten.
342339
343340 Returns
344341 -------
345- turbine_data : pd.DataFrame
342+ pd.DataFrame
346343 Contains turbine data of different turbines such as 'manufacturer',
347- 'turbine_type', nominal power ('installed_capacity_kw') .
344+ 'turbine_type', 'nominal_power' .
348345
349346 """
350347 # url of OpenEnergy Platform that contains the oedb
351348 oep_url = 'http://oep.iks.cs.ovgu.de/'
352349 # location of data
353- schema = 'model_draft '
354- table = 'openfred_windpower_powercurve '
350+ schema = 'supply '
351+ table = 'turbine_library '
355352 # load data
356353 result = requests .get (
357354 oep_url + '/api/v0/schema/{}/tables/{}/rows/?' .format (
358355 schema , table ), )
359356 if not result .status_code == 200 :
360357 raise ConnectionError ("Database connection not successful. "
361358 "Response: [{}]" .format (result .status_code ))
362- # extract data to data frame
359+ # extract data to dataframe
363360 turbine_data = pd .DataFrame (result .json ())
364- # store data as hdf5
361+ # standard file name for saving data
365362 filename = os .path .join (os .path .dirname (__file__ ), 'data' ,
366- 'turbine_data_oedb.h5' )
367- with pd .HDFStore (filename ) as hdf_store :
368- hdf_store .put ('turbine_data' , turbine_data )
369- logging .debug ("Turbine data is fetched from oedb and saved "
370- "to {}" .format (filename ))
363+ 'oedb_{}.csv' )
364+ # get all power (coefficient) curves and save to file
365+ # for curve_type in ['power_curve', 'power_coefficient_curve']:
366+ for curve_type in ['power_curve' , 'power_coefficient_curve' ]:
367+ curves_df = pd .DataFrame (columns = ['wind_speed' ])
368+ for index in turbine_data .index :
369+ if (turbine_data ['{}_wind_speeds' .format (curve_type )][index ]
370+ and turbine_data ['{}_values' .format (curve_type )][index ]):
371+ df = pd .DataFrame (data = [
372+ eval (turbine_data ['{}_wind_speeds' .format (curve_type )][
373+ index ]),
374+ eval (turbine_data ['{}_values' .format (curve_type )][
375+ index ])]).transpose ().rename (
376+ columns = {0 : 'wind_speed' ,
377+ 1 : turbine_data ['turbine_type' ][index ]})
378+ curves_df = pd .merge (left = curves_df , right = df , how = 'outer' ,
379+ on = 'wind_speed' )
380+ curves_df = curves_df .set_index ('wind_speed' ).sort_index ().transpose ()
381+ curves_df ['turbine_type' ] = curves_df .index
382+ # add nominal power to power (coefficient) data frame
383+ curves_df = pd .merge (
384+ left = curves_df , right = turbine_data [['turbine_type' ,
385+ 'installed_capacity' ]],
386+ on = 'turbine_type' ).set_index ('turbine_type' ).rename (
387+ columns = {'installed_capacity' : 'nominal_power' })
388+ curves_df .to_csv (filename .format ('{}s' .format (curve_type )))
389+
371390 return turbine_data
372391
373392
374- def get_turbine_types (print_out = True ):
393+ def get_turbine_types (print_out = True , filter_ = True ):
375394 r"""
376- Get the names of all possible wind turbine types for which the power
377- coefficient curve or power curve is provided in the OpenEnergy Data Base
378- (oedb).
395+ Get all wind turbine types provided in the OpenEnergy database (oedb).
396+
397+ By default only turbine types for which a power coefficient curve or power
398+ curve is provided are returned. Set `filter_=False` to see all turbine
399+ types for which any data (f.e. hub height, rotor diameter, ...) is
400+ provided.
379401
380402 Parameters
381403 ----------
382- print_out : boolean
404+ print_out : bool
383405 Directly prints a tabular containing the turbine types in column
384406 'turbine_type', the manufacturer in column 'manufacturer' and
385407 information about whether a power (coefficient) curve exists (True) or
386408 not (False) in columns 'has_power_curve' and 'has_cp_curve'.
387409 Default: True.
410+ filter_ : bool
411+ If True only turbine types for which a power coefficient curve or
412+ power curve is provided in the OpenEnergy database (oedb) are
413+ returned. Default: True.
388414
389415 Returns
390416 -------
391- curves_df : pd.DataFrame
417+ pd.DataFrame
392418 Contains turbine types in column 'turbine_type', the manufacturer in
393419 column 'manufacturer' and information about whether a power
394420 (coefficient) curve exists (True) or not (False) in columns
395421 'has_power_curve' and 'has_cp_curve'.
396422
423+ Notes
424+ -----
425+ If the power (coefficient) curve of the desired turbine type (or the
426+ turbine type itself) is missing you can contact us via github or
427+ [email protected] . You can help us by providing data in the 428+ format as shown in
429+ `the data base <https://openenergy-platform.org/dataedit/view/model_draft/openfred_windpower_powercurve>`_.
430+
397431 Examples
398432 --------
399433 >>> from windpowerlib import wind_turbine
@@ -412,14 +446,17 @@ def get_turbine_types(print_out=True):
412446 Name: 1, dtype: object
413447
414448 """
415-
416449 df = load_turbine_data_from_oedb ()
417- cp_curves_df = df .iloc [df .loc [df ['has_cp_curve' ]].index ][
418- ['manufacturer' , 'turbine_type' , 'has_cp_curve' ]]
419- p_curves_df = df .iloc [df .loc [df ['has_power_curve' ]].index ][
420- ['manufacturer' , 'turbine_type' , 'has_power_curve' ]]
421- curves_df = pd .merge (p_curves_df , cp_curves_df , how = 'outer' ,
422- sort = True ).fillna (False )
450+ if filter_ :
451+ cp_curves_df = df .loc [df ['has_cp_curve' ]][
452+ ['manufacturer' , 'turbine_type' , 'has_cp_curve' ]]
453+ p_curves_df = df .loc [df ['has_power_curve' ]][
454+ ['manufacturer' , 'turbine_type' , 'has_power_curve' ]]
455+ curves_df = pd .merge (p_curves_df , cp_curves_df , how = 'outer' ,
456+ sort = True ).fillna (False )
457+ else :
458+ curves_df = df [['manufacturer' , 'turbine_type' , 'has_power_curve' ,
459+ 'has_cp_curve' ]]
423460 if print_out :
424461 pd .set_option ('display.max_rows' , len (curves_df ))
425462 print (curves_df )
0 commit comments