Wind Energy: pass file path (instead of dict) to _compute_density_harvested_fields to prevent excessive debug logging
This commit is contained in:
parent
edebed084b
commit
63a3a91a58
|
@ -42,6 +42,10 @@ Unreleased Changes
|
|||
* Updated the documentation for the ``mean_t_air`` attribute of the
|
||||
``buildings_with_stats.shp`` output to clarify how the value is
|
||||
calculated. https://github.com/natcap/invest/issues/1746
|
||||
* Wind Energy
|
||||
* Fixed a bug that could cause the Workbench to crash when running the Wind
|
||||
Energy model with ``Taskgraph`` logging set to ``DEBUG`` (`InVEST #1497
|
||||
<https://github.com/natcap/invest/issues/1497>`_).
|
||||
|
||||
3.14.3 (2024-12-19)
|
||||
-------------------
|
||||
|
|
|
@ -694,14 +694,6 @@ def execute(args):
|
|||
|
||||
number_of_turbines = int(args['number_of_turbines'])
|
||||
|
||||
# Create a list of the biophysical parameters we are looking for from the
|
||||
# input csv files
|
||||
biophysical_params = [
|
||||
'cut_in_wspd', 'cut_out_wspd', 'rated_wspd', 'hub_height',
|
||||
'turbine_rated_pwr', 'air_density', 'exponent_power_curve',
|
||||
'air_density_coefficient', 'loss_parameter'
|
||||
]
|
||||
|
||||
# Read the biophysical turbine parameters into a dictionary
|
||||
turbine_dict = validation.get_validated_dataframe(
|
||||
args['turbine_parameters_path'],
|
||||
|
@ -753,31 +745,13 @@ def execute(args):
|
|||
for time_step in range(int(time) + 1):
|
||||
price_list.append(wind_price * (1 + change_rate)**(time_step))
|
||||
|
||||
# Hub Height to use for setting Weibull parameters
|
||||
hub_height = parameters_dict['hub_height']
|
||||
|
||||
LOGGER.debug('hub_height : %s', hub_height)
|
||||
|
||||
# Read the wind energy data into a dictionary
|
||||
LOGGER.info('Reading in Wind Data into a dictionary')
|
||||
wind_point_df = validation.get_validated_dataframe(
|
||||
args['wind_data_path'], **MODEL_SPEC['args']['wind_data_path'])
|
||||
wind_point_df.columns = wind_point_df.columns.str.upper()
|
||||
# Calculate scale value at new hub height given reference values.
|
||||
# See equation 3 in users guide
|
||||
wind_point_df.rename(columns={'LAM': 'REF_LAM'}, inplace=True)
|
||||
wind_point_df['LAM'] = wind_point_df.apply(
|
||||
lambda row: row.REF_LAM * (hub_height / row.REF)**_ALPHA, axis=1)
|
||||
wind_point_df.drop(['REF'], axis=1) # REF is not needed after calculation
|
||||
wind_data = wind_point_df.to_dict('index') # so keys will be 0, 1, 2, ...
|
||||
|
||||
# Compute Wind Density and Harvested Wind Energy, adding the values to the
|
||||
# points to the dictionary, and pickle the dictionary
|
||||
# Compute Wind Density and Harvested Wind Energy,
|
||||
# and pickle the resulting dictionary
|
||||
wind_data_pickle_path = os.path.join(
|
||||
inter_dir, 'wind_data%s.pickle' % suffix)
|
||||
compute_density_harvested_task = task_graph.add_task(
|
||||
func=_compute_density_harvested_fields,
|
||||
args=(wind_data, parameters_dict, number_of_turbines,
|
||||
args=(args['wind_data_path'], parameters_dict, number_of_turbines,
|
||||
wind_data_pickle_path),
|
||||
target_path_list=[wind_data_pickle_path],
|
||||
task_name='compute_density_harvested_fields')
|
||||
|
@ -1911,14 +1885,12 @@ def _create_distance_raster(base_raster_path, base_vector_path,
|
|||
|
||||
|
||||
def _compute_density_harvested_fields(
|
||||
wind_dict, parameters_dict, number_of_turbines,
|
||||
wind_data_path, parameters_dict, number_of_turbines,
|
||||
target_pickle_path):
|
||||
"""Compute the density and harvested energy based on scale and shape keys.
|
||||
|
||||
Args:
|
||||
wind_dict (dict): a dictionary whose values are a dictionary with
|
||||
keys ``LAM``, ``LATI``, ``K``, ``LONG``, ``REF_LAM``, and ``REF``,
|
||||
and numbers indicating their corresponding values.
|
||||
wind_data_path (str): path to wind data input.
|
||||
|
||||
parameters_dict (dict): a dictionary where the 'parameter_list'
|
||||
strings are the keys that have values pulled from bio-parameters
|
||||
|
@ -1928,13 +1900,30 @@ def _compute_density_harvested_fields(
|
|||
for the wind farm.
|
||||
|
||||
target_pickle_path (str): a path to the pickle file that has
|
||||
wind_dict_copy, a modified dictionary with new fields computed
|
||||
from the existing fields and bio-parameters.
|
||||
wind_dict_copy, a modified dictionary of wind data with additional
|
||||
fields computed from the existing fields and bio-parameters.
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
"""
|
||||
# Hub Height to use for setting Weibull parameters
|
||||
hub_height = parameters_dict['hub_height']
|
||||
LOGGER.debug('hub_height : %s', hub_height)
|
||||
|
||||
# Read the wind energy data into a dictionary
|
||||
LOGGER.info('Reading in Wind Data into a dictionary')
|
||||
wind_point_df = validation.get_validated_dataframe(
|
||||
wind_data_path, **MODEL_SPEC['args']['wind_data_path'])
|
||||
wind_point_df.columns = wind_point_df.columns.str.upper()
|
||||
# Calculate scale value at new hub height given reference values.
|
||||
# See equation 3 in users guide
|
||||
wind_point_df.rename(columns={'LAM': 'REF_LAM'}, inplace=True)
|
||||
wind_point_df['LAM'] = wind_point_df.apply(
|
||||
lambda row: row.REF_LAM * (hub_height / row.REF)**_ALPHA, axis=1)
|
||||
wind_point_df.drop(['REF'], axis=1) # REF is not needed after calculation
|
||||
wind_dict = wind_point_df.to_dict('index') # so keys will be 0, 1, 2, ...
|
||||
|
||||
wind_dict_copy = wind_dict.copy()
|
||||
|
||||
# The rated power is expressed in units of MW but the harvested energy
|
||||
|
@ -1952,9 +1941,6 @@ def _compute_density_harvested_fields(
|
|||
air_density_coef = parameters_dict['air_density_coefficient']
|
||||
losses = parameters_dict['loss_parameter']
|
||||
|
||||
# Hub Height to use for setting Weibull parameters
|
||||
hub_height = parameters_dict['hub_height']
|
||||
|
||||
# Compute the mean air density, given by CKs formulas
|
||||
mean_air_density = air_density_standard - air_density_coef * hub_height
|
||||
|
||||
|
|
|
@ -274,7 +274,7 @@ class WindEnergyUnitTests(unittest.TestCase):
|
|||
from natcap.invest import wind_energy
|
||||
|
||||
srs = osr.SpatialReference()
|
||||
srs.ImportFromEPSG(3157) #UTM Zone 10N
|
||||
srs.ImportFromEPSG(3157) # UTM Zone 10N
|
||||
projection_wkt = srs.ExportToWkt()
|
||||
origin = (443723.127327877911739, 4956546.905980412848294)
|
||||
pos_x = origin[0]
|
||||
|
@ -284,7 +284,7 @@ class WindEnergyUnitTests(unittest.TestCase):
|
|||
fields = {'id': ogr.OFTReal}
|
||||
attrs = [{'id': 1}]
|
||||
|
||||
# Square polygon that will overlap the 4 pixels of the raster in the
|
||||
# Square polygon that will overlap the 4 pixels of the raster in the
|
||||
# upper left corner
|
||||
poly_geometry = [box(pos_x, pos_y - 17, pos_x + 17, pos_y)]
|
||||
poly_vector_path = os.path.join(
|
||||
|
@ -306,7 +306,7 @@ class WindEnergyUnitTests(unittest.TestCase):
|
|||
dist_raster_path = os.path.join(self.workspace_dir, 'dist.tif')
|
||||
# Call function to test given testing inputs
|
||||
wind_energy._create_distance_raster(
|
||||
base_raster_path, poly_vector_path, dist_raster_path,
|
||||
base_raster_path, poly_vector_path, dist_raster_path,
|
||||
self.workspace_dir)
|
||||
|
||||
# Compare the results
|
||||
|
@ -348,11 +348,9 @@ class WindEnergyUnitTests(unittest.TestCase):
|
|||
price_list = [0.10, 0.10, 0.10, 0.10, 0.10]
|
||||
|
||||
srs = osr.SpatialReference()
|
||||
srs.ImportFromEPSG(3157) #UTM Zone 10N
|
||||
srs.ImportFromEPSG(3157) # UTM Zone 10N
|
||||
projection_wkt = srs.ExportToWkt()
|
||||
origin = (443723.127327877911739, 4956546.905980412848294)
|
||||
pos_x = origin[0]
|
||||
pos_y = origin[1]
|
||||
|
||||
# Create harvested raster
|
||||
harvest_val = 1000000
|
||||
|
@ -360,8 +358,8 @@ class WindEnergyUnitTests(unittest.TestCase):
|
|||
[[harvest_val, harvest_val + 1e5, harvest_val + 2e5,
|
||||
harvest_val + 3e5, harvest_val + 4e5],
|
||||
[harvest_val, harvest_val + 1e5, harvest_val + 2e5,
|
||||
harvest_val + 3e5, harvest_val + 4e5],
|
||||
], dtype=numpy.float32)
|
||||
harvest_val + 3e5, harvest_val + 4e5]],
|
||||
dtype=numpy.float32)
|
||||
base_harvest_path = os.path.join(self.workspace_dir, 'harvest_raster.tif')
|
||||
# Create raster to use for testing input
|
||||
pygeoprocessing.numpy_array_to_raster(
|
||||
|
@ -386,9 +384,9 @@ class WindEnergyUnitTests(unittest.TestCase):
|
|||
# Compare the results that were "eye" tested.
|
||||
desired_npv_array = numpy.array(
|
||||
[[309332320.0, 348331200.0, 387330020.0, 426328930.0,
|
||||
465327800.0],
|
||||
465327800.0],
|
||||
[309332320.0, 348331200.0, 387330020.0, 426328930.0,
|
||||
465327800.0]], dtype=numpy.float32)
|
||||
465327800.0]], dtype=numpy.float32)
|
||||
actual_npv_array = pygeoprocessing.raster_to_numpy_array(
|
||||
target_npv_raster_path)
|
||||
numpy.testing.assert_allclose(actual_npv_array, desired_npv_array)
|
||||
|
@ -402,6 +400,7 @@ class WindEnergyUnitTests(unittest.TestCase):
|
|||
numpy.testing.assert_allclose(
|
||||
actual_levelized_array, desired_levelized_array)
|
||||
|
||||
|
||||
class WindEnergyRegressionTests(unittest.TestCase):
|
||||
"""Regression tests for the Wind Energy module."""
|
||||
|
||||
|
@ -428,8 +427,8 @@ class WindEnergyRegressionTests(unittest.TestCase):
|
|||
SAMPLE_DATA, 'global_wind_energy_parameters.csv'),
|
||||
'turbine_parameters_path': os.path.join(
|
||||
SAMPLE_DATA, '3_6_turbine.csv'),
|
||||
'number_of_turbines': '80', # pass str to test casting
|
||||
'min_depth': '3', # pass str to test casting
|
||||
'number_of_turbines': '80', # pass str to test casting
|
||||
'min_depth': '3', # pass str to test casting
|
||||
'max_depth': 180,
|
||||
'n_workers': -1
|
||||
}
|
||||
|
@ -534,13 +533,13 @@ class WindEnergyRegressionTests(unittest.TestCase):
|
|||
args['max_distance'] = 200000
|
||||
args['valuation_container'] = True
|
||||
args['foundation_cost'] = 2000000
|
||||
args['discount_rate'] = '0.07' # pass str to test casting
|
||||
args['discount_rate'] = '0.07' # pass str to test casting
|
||||
# Test that only grid points are provided in grid_points_path
|
||||
args['grid_points_path'] = os.path.join(
|
||||
SAMPLE_DATA, 'resampled_grid_pts.csv')
|
||||
args['price_table'] = False
|
||||
args['wind_price'] = 0.187
|
||||
args['rate_change'] = '0.2' # pass str to test casting
|
||||
args['rate_change'] = '0.2' # pass str to test casting
|
||||
|
||||
wind_energy.execute(args)
|
||||
|
||||
|
|
Loading…
Reference in New Issue