Skip to content

Commit

Permalink
Merge pull request #437 from NREL/pp/tm_fix
Browse files Browse the repository at this point in the history
Fix missing techmap bug
  • Loading branch information
ppinchuk authored Dec 18, 2023
2 parents 113ecf8 + f3cd3fd commit 0bf8745
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 45 deletions.
34 changes: 33 additions & 1 deletion reV/supply_curve/aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from reV.handlers.exclusions import ExclusionLayers
from reV.supply_curve.exclusions import ExclusionMaskFromDict
from reV.supply_curve.extent import SupplyCurveExtent
from reV.supply_curve.tech_mapping import TechMapping
from reV.supply_curve.points import AggregationSupplyCurvePoint
from reV.utilities.exceptions import (EmptySupplyCurvePointError,
FileInputError, SupplyCurveInputError)
Expand Down Expand Up @@ -153,7 +154,7 @@ class BaseAggregation(ABC):

def __init__(self, excl_fpath, tm_dset, excl_dict=None,
area_filter_kernel='queen', min_area=None,
resolution=64, excl_area=None, gids=None,
resolution=64, excl_area=None, res_fpath=None, gids=None,
pre_extract_inclusions=False):
"""
Parameters
Expand Down Expand Up @@ -198,11 +199,14 @@ def __init__(self, excl_fpath, tm_dset, excl_dict=None,
self._resolution = resolution
self._area_filter_kernel = area_filter_kernel
self._min_area = min_area
self._res_fpath = res_fpath
self._gids = gids
self._pre_extract_inclusions = pre_extract_inclusions
self._excl_area = self._get_excl_area(excl_fpath, excl_area=excl_area)
self._shape = None

self._validate_tech_mapping()

if pre_extract_inclusions:
self._inclusion_mask = \
ExclusionMaskFromDict.extract_inclusion_mask(
Expand All @@ -213,6 +217,34 @@ def __init__(self, excl_fpath, tm_dset, excl_dict=None,
else:
self._inclusion_mask = None

def _validate_tech_mapping(self):
"""Check that tech mapping exists and create it if it doesn't"""

with ExclusionLayers(self._excl_fpath) as f:
dsets = f.h5.dsets

excl_fp_is_str = isinstance(self._excl_fpath, str)
tm_in_excl = self._tm_dset in dsets
if tm_in_excl:
logger.info('Found techmap "{}".'.format(self._tm_dset))
elif not tm_in_excl and not excl_fp_is_str:
msg = ('Could not find techmap dataset "{}" and cannot run '
'techmap with arbitrary multiple exclusion filepaths '
'to write to: {}'.format(self._tm_dset, self._excl_fpath))
logger.error(msg)
raise RuntimeError(msg)
else:
logger.info('Could not find techmap "{}". Running techmap module.'
.format(self._tm_dset))
try:
TechMapping.run(self._excl_fpath, self._res_fpath,
dset=self._tm_dset)
except Exception as e:
msg = ('TechMapping process failed. Received the '
'following error:\n{}'.format(e))
logger.exception(msg)
raise RuntimeError(msg) from e

@property
def gids(self):
"""
Expand Down
50 changes: 10 additions & 40 deletions reV/supply_curve/sc_aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from reV.supply_curve.exclusions import FrictionMask
from reV.supply_curve.extent import SupplyCurveExtent
from reV.supply_curve.points import GenerationSupplyCurvePoint
from reV.supply_curve.tech_mapping import TechMapping
from reV.utilities.exceptions import (EmptySupplyCurvePointError,
OutputWarning, FileInputError,
InputWarning)
Expand Down Expand Up @@ -226,7 +225,7 @@ class SupplyCurveAggregation(BaseAggregation):

def __init__(self, excl_fpath, tm_dset, econ_fpath=None,
excl_dict=None, area_filter_kernel='queen', min_area=None,
resolution=64, excl_area=None, gids=None,
resolution=64, excl_area=None, res_fpath=None, gids=None,
pre_extract_inclusions=False, res_class_dset=None,
res_class_bins=None, cf_dset='cf_mean-means',
lcoe_dset='lcoe_fcr-means', h5_dsets=None, data_layers=None,
Expand Down Expand Up @@ -368,6 +367,11 @@ def __init__(self, excl_fpath, tm_dset, econ_fpath=None,
Area of a single exclusion mask pixel (in km\ :sup:`2`).
If ``None``, this value will be inferred from the profile
transform attribute in `excl_fpath`. By default, ``None``.
res_fpath : str, optional
Filepath to HDF5 resource file (e.g. WTK or NSRDB). This
input is required if techmap dset is to be created or if the
``gen_fpath`` input to the ``summarize`` or ``run`` methods
is ``None``. By default, ``None``.
gids : list, optional
List of supply curve point gids to get summary for. If you
would like to obtain all available ``reV`` supply curve
Expand Down Expand Up @@ -636,7 +640,7 @@ def __init__(self, excl_fpath, tm_dset, econ_fpath=None,
super().__init__(excl_fpath, tm_dset, excl_dict=excl_dict,
area_filter_kernel=area_filter_kernel,
min_area=min_area, resolution=resolution,
excl_area=excl_area, gids=gids,
excl_area=excl_area, res_fpath=res_fpath, gids=gids,
pre_extract_inclusions=pre_extract_inclusions)

self._econ_fpath = econ_fpath
Expand Down Expand Up @@ -1206,34 +1210,6 @@ def _summary_to_df(summary):

return summary

def _validate_tech_mapping(self, res_fpath):
"""Check that tech mapping exists and create it if it doesn't"""

with ExclusionLayers(self._excl_fpath) as f:
dsets = f.h5.dsets

excl_fp_is_str = isinstance(self._excl_fpath, str)
tm_in_excl = self._tm_dset in dsets
if tm_in_excl:
logger.info('Found techmap "{}".'.format(self._tm_dset))
elif not tm_in_excl and not excl_fp_is_str:
msg = ('Could not find techmap dataset "{}" and cannot run '
'techmap with arbitrary multiple exclusion filepaths '
'to write to: {}'.format(self._tm_dset, self._excl_fpath))
logger.error(msg)
raise RuntimeError(msg)
else:
logger.info('Could not find techmap "{}". Running techmap module.'
.format(self._tm_dset))
try:
TechMapping.run(self._excl_fpath, res_fpath,
dset=self._tm_dset)
except Exception as e:
msg = ('TechMapping process failed. Received the '
'following error:\n{}'.format(e))
logger.exception(msg)
raise RuntimeError(msg) from e

def summarize(self, gen_fpath, args=None, max_workers=None,
sites_per_worker=100):
"""
Expand Down Expand Up @@ -1299,8 +1275,8 @@ def summarize(self, gen_fpath, args=None, max_workers=None,

return summary

def run(self, out_fpath, gen_fpath=None, res_fpath=None, args=None,
max_workers=None, sites_per_worker=100):
def run(self, out_fpath, gen_fpath=None, args=None, max_workers=None,
sites_per_worker=100):
"""Run a supply curve aggregation.
Parameters
Expand All @@ -1319,10 +1295,6 @@ def run(self, out_fpath, gen_fpath=None, res_fpath=None, args=None,
`econ_fpath` input will have to be specified manually.
By default, ``None``.
res_fpath : str, optional
Filepath to HDF5 resource file (e.g. WTK or NSRDB). This
input is required if techmap dset is to be created or if
``gen_fpath is`` is ``None``. By default, ``None``.
args : tuple | list, optional
List of columns to include in summary output table. ``None``
defaults to all available args defined in the
Expand All @@ -1341,11 +1313,9 @@ def run(self, out_fpath, gen_fpath=None, res_fpath=None, args=None,
Path to output CSV file containing supply curve aggregation.
"""

self._validate_tech_mapping(res_fpath)

if gen_fpath is None:
out = Aggregation.run(
self._excl_fpath, res_fpath, self._tm_dset,
self._excl_fpath, self._res_fpath, self._tm_dset,
excl_dict=self._excl_dict,
resolution=self._resolution,
excl_area=self._excl_area,
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
NREL-gaps>=0.6.3
NREL-gaps>=0.6.4
NREL-NRWAL>=0.0.7
NREL-PySAM~=4.1.0
NREL-rex>=0.2.80
Expand Down
9 changes: 6 additions & 3 deletions tests/test_supply_curve_sc_aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,9 @@ def test_recalc_lcoe():
assert not np.allclose(summary_base['mean_lcoe'], summary['mean_lcoe'])


def test_cli_basic_agg(runner, clear_loggers):
@pytest.mark.parametrize('tm_dset', ("techmap_ri", "techmap_ri_new"))
@pytest.mark.parametrize('pre_extract', (True, False))
def test_cli_basic_agg(runner, clear_loggers, tm_dset, pre_extract):
with tempfile.TemporaryDirectory() as td:
excl_fp = os.path.join(td, 'excl.h5')
shutil.copy(EXCL, excl_fp)
Expand All @@ -421,10 +423,11 @@ def test_cli_basic_agg(runner, clear_loggers):
"excl_fpath": excl_fp,
"gen_fpath": None,
"econ_fpath": None,
"tm_dset": "techmap_ri",
"tm_dset": tm_dset,
"res_fpath": RES,
'excl_dict': EXCL_DICT,
'resolution': 32
'resolution': 32,
'pre_extract_inclusions': pre_extract
}
config_path = os.path.join(td, 'config.json')
with open(config_path, 'w') as f:
Expand Down

0 comments on commit 0bf8745

Please sign in to comment.