Skip to content

Commit

Permalink
Merge pull request #461 from NREL/pp/resource_as_list
Browse files Browse the repository at this point in the history
Allow bespoke to read list for resource input
  • Loading branch information
ppinchuk authored Sep 12, 2024
2 parents f4b0b40 + 81befce commit 7d4a339
Show file tree
Hide file tree
Showing 14 changed files with 56 additions and 88 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# GitHub syntax highlighting
pixi.lock linguist-language=YAML linguist-generated=true
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,8 @@ tags
# Scratch and temp work
.tmp/
.scratch/


# pixi environments
.pixi
*.egg-info
2 changes: 1 addition & 1 deletion examples/project_points/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ reV Project Points
`reV Gen <https://nrel.github.io/reV/_autosummary/reV.generation.generation.Gen.html#reV.generation.generation.Gen>`_
and `reV Econ <https://nrel.github.io/reV/_autosummary/reV.econ.econ.Econ.html#reV.econ.econ.Econ>`_
use `Project Points <https://nrel.github.io/reV/_autosummary/reV.config.project_points.ProjectPoints.html#reV.config.project_points.ProjectPoints>`_ to define which resource sites (`gids`) to run through
`PySAM <https://pysam.readthedocs.io/en/latest/>`_ and how.
`PySAM <https://nrel-pysam.readthedocs.io/en/latest/>`_ and how.

At its most basic Project Points consists of the resource ``gid``s and the
``SAM`` configuration file associated it. This can be definited in a variety
Expand Down
25 changes: 3 additions & 22 deletions examples/project_points/reV_project_points.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"[reV Gen](https://nrel.github.io/reV/_autosummary/reV.generation.generation.Gen.html#reV.generation.generation.Gen)\n",
"and [reV Econ](https://nrel.github.io/reV/_autosummary/reV.econ.econ.Econ.html#reV.econ.econ.Econ)\n",
"use [Project Points](https://nrel.github.io/reV/_autosummary/reV.config.project_points.ProjectPoints.html#reV.config.project_points.ProjectPoints) to define which resource sites (`gids`) to run through\n",
"[PySAM](https://pysam.readthedocs.io/en/latest/) and how.\n",
"[PySAM](https://nrel-pysam.readthedocs.io/en/latest/) and how.\n",
"\n",
"At its most basic Project Points consists of the resource `gid`s and the\n",
"`SAM` configuration file associated it. This can be definited in a variety\n",
Expand All @@ -31,9 +31,6 @@
"ExecuteTime": {
"end_time": "2021-07-07T14:58:35.397005Z",
"start_time": "2021-07-07T14:58:32.416695Z"
},
"vscode": {
"languageId": "python"
}
},
"outputs": [
Expand Down Expand Up @@ -166,9 +163,6 @@
"ExecuteTime": {
"end_time": "2021-07-07T14:58:50.285840Z",
"start_time": "2021-07-07T14:58:50.264216Z"
},
"vscode": {
"languageId": "python"
}
},
"outputs": [
Expand Down Expand Up @@ -298,9 +292,6 @@
"ExecuteTime": {
"end_time": "2021-07-07T14:59:24.504132Z",
"start_time": "2021-07-07T14:59:24.487708Z"
},
"vscode": {
"languageId": "python"
}
},
"outputs": [
Expand Down Expand Up @@ -403,9 +394,6 @@
"ExecuteTime": {
"end_time": "2021-07-07T15:00:00.189414Z",
"start_time": "2021-07-07T15:00:00.142362Z"
},
"vscode": {
"languageId": "python"
}
},
"outputs": [
Expand Down Expand Up @@ -549,9 +537,6 @@
"ExecuteTime": {
"end_time": "2021-07-07T15:00:55.441563Z",
"start_time": "2021-07-07T15:00:55.407988Z"
},
"vscode": {
"languageId": "python"
}
},
"outputs": [
Expand Down Expand Up @@ -909,7 +894,7 @@
"from reV.config.project_points import ProjectPoints\n",
"\n",
"# Of form {region : region_column}\n",
"regions = {'Rhode Island': 'state'} \n",
"regions = {'Rhode Island': 'state'}\n",
"# or\n",
"regions = {'Providence': 'county', 'Kent': 'county'}\n",
"\n",
Expand Down Expand Up @@ -956,11 +941,7 @@
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"vscode": {
"languageId": "python"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
Expand Down
2 changes: 1 addition & 1 deletion examples/running_locally/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ can be run locally using resource .h5 files stored locally.
reV Gen
-------

reV Generation uses `PySAM <https://pysam.readthedocs.io/en/latest/>`_ to
reV Generation uses `PySAM <https://nrel-pysam.readthedocs.io/en/latest/>`_ to
compute technologically specific capcity factor means and profiles. reV Gen
uses ``SAM`` technology terms and input configuration files

Expand Down
2 changes: 1 addition & 1 deletion examples/running_locally/running_reV_locally.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"\n",
"[reV Gen](https://nrel.github.io/reV/_autosummary/reV.generation.generation.Gen.html#reV.generation.generation.Gen) and [reV Econ](https://nrel.github.io/reV/_autosummary/reV.econ.econ.Econ.html#reV.econ.econ.Econ) can be run locally using resource .h5 files stored locally or using the [HDF Groups](https://www.hdfgroup.org) Highly Scalable Distributed Service (HSDS) to access resource .h5 file stored in the cloud (currenly on Amazon Web Services -- AWS).\n",
"\n",
"reV use [PySAM](https://pysam.readthedocs.io/en/latest/) to\n",
"reV uses [PySAM](https://nrel-pysam.readthedocs.io/en/latest/) to\n",
"compute technologically specific capcity factor means and profiles (`Gen`) and mean levelized cost of energy (`Econ`). `reV`\n",
"uses ``SAM`` technology terms and input configuration files. \n",
"\n",
Expand Down
2 changes: 1 addition & 1 deletion examples/running_with_hsds/running_reV_with_HSDS.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"\n",
"[reV Gen](https://nrel.github.io/reV/_autosummary/reV.generation.generation.Gen.html#reV.generation.generation.Gen) and [reV Econ](https://nrel.github.io/reV/_autosummary/reV.econ.econ.Econ.html#reV.econ.econ.Econ) can be run locally using the [HDF Groups](https://www.hdfgroup.org) Highly Scalable Distributed Service (HSDS) to access resource .h5 file stored in the cloud (currenly on Amazon Web Services -- AWS).\n",
"\n",
"reV use [PySAM](https://pysam.readthedocs.io/en/latest/) to\n",
"reV uses [PySAM](https://nrel-pysam.readthedocs.io/en/latest/) to\n",
"compute technologically specific capcity factor means and profiles (`Gen`) and mean levelized cost of energy (`Econ`). `reV`\n",
"uses ``SAM`` technology terms and input configuration files.\n",
"\n",
Expand Down
2 changes: 1 addition & 1 deletion reV/SAM/generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1548,7 +1548,7 @@ class Geothermal(AbstractSamGenerationFromWeatherFile):
or 1 allowed.
- ``design_temp`` : EGS plant design temperature (in C). Only
affects EGS runs. This value may be adjusted internally by
``reV under the following conditions:
``reV`` under the following conditions:
- The design temperature is larger than the resource
temperature
Expand Down
68 changes: 21 additions & 47 deletions reV/bespoke/bespoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import psutil
from rex.joint_pd.joint_pd import JointPD
from rex.multi_year_resource import MultiYearWindResource
from rex.renewable_resource import WindResource
from rex.utilities.bc_parse_table import parse_bc_table
from rex.utilities.execution import SpawnProcessPool
from rex.utilities.loggers import create_dirs, log_mem
Expand Down Expand Up @@ -60,16 +59,21 @@ def __init__(self, res_fpath, sc_gid_to_hh, sc_gid_to_res_gid):
Parameters
----------
res_fpath : str
Path to resource h5 file.
res_fpath : str | list
Unix shell style path (potentially containing wildcard (*)
patterns) to a single or multi-file resource file set(s).
Can also be an explicit list of resource file paths, which
themselves can contain wildcards. This input must be
readable by
:py:class:`rex.multi_year_resource.MultiYearWindResource`.
sc_gid_to_hh : dict
Dictionary mapping SC GID values to hub-heights. Data for
each SC GID will be pulled for the corresponding hub-height
given in this dictionary.
sc_gid_to_res_gid : dict
Dictionary mapping SC GID values to an iterable oif resource
GID values. Resource GID values should correspond to GID
values in teh HDF5 file, so any GID map must be applied
values in the HDF5 file, so any GID map must be applied
before initializing :class`BespokeMultiPlantData`.
"""
self.res_fpath = res_fpath
Expand All @@ -95,12 +99,7 @@ def _pre_load_data(self):
}

start_time = time.time()
if "*" in self.res_fpath:
handler = MultiYearWindResource
else:
handler = WindResource

with handler(self.res_fpath) as res:
with MultiYearWindResource(self.res_fpath) as res:
self._wind_dirs = {
hh: res[f"winddirection_{hh}m", :, gids]
for hh, gids in self.hh_to_res_gids.items()
Expand Down Expand Up @@ -481,8 +480,7 @@ def __init__(
self._pre_loaded_data = pre_loaded_data
self._outputs = {}

Handler = self.get_wind_handler(res)
res = res if not isinstance(res, str) else Handler(res)
res = res if not isinstance(res, str) else MultiYearWindResource(res)

self._sc_point = AggSCPoint(
gid,
Expand Down Expand Up @@ -1142,29 +1140,6 @@ def get_lcoe_kwargs(self):
lcoe_kwargs["capital_cost"] = lcoe_kwargs["capital_cost"] + bos
return lcoe_kwargs

@staticmethod
def get_wind_handler(res):
"""Get a wind resource handler for a resource filepath.
Parameters
----------
res : str
Resource filepath to wtk .h5 file. Can include * wildcards
for multi year resource.
Returns
-------
handler : WindResource | MultiYearWindResource
Wind resource handler or multi year handler
"""
handler = res
if isinstance(res, str):
if "*" in res:
handler = MultiYearWindResource
else:
handler = WindResource
return handler

@classmethod
def check_dependencies(cls):
"""Check special dependencies for bespoke"""
Expand Down Expand Up @@ -1535,14 +1510,15 @@ def __init__(self, excl_fpath, res_fpath, tm_dset, objective_function,
uniquely defined (i.e.only appear once and in a single
input file).
res_fpath : str
Filepath to wind resource data in NREL WTK format. This
input can be path to a single resource HDF5 file or a path
including a wildcard input like ``/h5_dir/prefix*suffix`` to
run bespoke on multiple years of resource data. The former
must be readable by
:py:class:`rex.renewable_resource.WindResource` while the
latter must be readable by
or :py:class:`rex.multi_year_resource.MultiYearWindResource`
Unix shell style path to wind resource HDF5 file in NREL WTK
format. Can also be a path including a wildcard input like
``/h5_dir/prefix*suffix`` to run bespoke on multiple years
of resource data. Can also be an explicit list of resource
HDF5 file paths, which themselves can contain wildcards. If
multiple files are specified in this way, they must have the
same coordinates but can have different time indices (i.e.
different years). This input must be readable by
:py:class:`rex.multi_year_resource.MultiYearWindResource`
(i.e. the resource data conform to the
`rex data format <https://tinyurl.com/3fy7v5kx>`_). This
means the data file(s) must contain a 1D ``time_index``
Expand Down Expand Up @@ -2141,8 +2117,7 @@ def _check_files(self):
)

# just check that this file exists, cannot check res_fpath if *glob
Handler = BespokeSinglePlant.get_wind_handler(self._res_fpath)
with Handler(self._res_fpath) as f:
with MultiYearWindResource(self._res_fpath) as f:
assert any(f.dsets)

def _pre_load_data(self, pre_load_data):
Expand Down Expand Up @@ -2502,14 +2477,13 @@ def run_serial(cls, excl_fpath, res_fpath, tm_dset,
exclusion_shape = sc.exclusions.shape

cls._check_inclusion_mask(inclusion_mask, gids, exclusion_shape)
Handler = BespokeSinglePlant.get_wind_handler(res_fpath)

# pre-extract handlers so they are not repeatedly initialized
file_kwargs = {
"excl_dict": excl_dict,
"area_filter_kernel": area_filter_kernel,
"min_area": min_area,
"h5_handler": Handler,
"h5_handler": MultiYearWindResource,
}

with AggFileHandler(excl_fpath, res_fpath, **file_kwargs) as fh:
Expand Down
18 changes: 12 additions & 6 deletions reV/generation/generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,10 @@ def __init__(
info on the allowed and/or required SAM config file inputs.
resource_file : str
Filepath to resource data. This input can be path to a
single resource HDF5 file, a path to a directory containing
data spread across multiple HDF5 files, or a path including
a wildcard input like ``/h5_dir/prefix*suffix``. In all
cases, the resource data must be readable by
single resource HDF5 file or a path including a wildcard
input like ``/h5_dir/prefix*suffix`` (i.e. if your datasets
for a single year are spread out over multiple files). In
all cases, the resource data must be readable by
:py:class:`rex.resource.Resource`
or :py:class:`rex.multi_file_resource.MultiFileResource`.
(i.e. the resource data conform to the
Expand All @@ -253,8 +253,14 @@ def __init__(
consideration, and its shape must be a multiple of 8760.
.. Note:: If executing ``reV`` from the command line, this
path can contain brackets ``{}`` that will be filled in by
the `analysis_years` input.
input string can contain brackets ``{}`` that will be
filled in by the `analysis_years` input. Alternatively,
this input can be a list of explicit files to process. In
this case, the length of the list must match the length of
the `analysis_years` input exactly, and the path are
assumed to align with the `analysis_years` (i.e. the first
path corresponds to the first analysis year, the second
path corresponds to the second analysis year, and so on).
.. Important:: If you are using custom resource data (i.e.
not NSRDB/WTK/Sup3rCC, etc.), ensure the following:
Expand Down
3 changes: 1 addition & 2 deletions reV/supply_curve/sc_aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from rex.resource import Resource
from rex.utilities.execution import SpawnProcessPool

from reV.generation.base import BaseGen
from reV.handlers.exclusions import ExclusionLayers
from reV.supply_curve.aggregation import (
AbstractAggFileHandler,
Expand Down Expand Up @@ -1410,7 +1409,7 @@ def run(
``multi-year``, ``collect``, or ``econ``. However, note
that duplicate executions of any of these commands within
the pipeline may invalidate this parsing, meaning the
`econ_fpath` input will have to be specified manually.
`gen_fpath` input will have to be specified manually.
By default, ``None``.
args : tuple | list, optional
Expand Down
2 changes: 1 addition & 1 deletion reV/supply_curve/tech_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def _get_excl_coords(cls, excl_fpath, gids, sc_row_indices, sc_col_indices,
excl_row_slices, excl_col_slices,
coord_labels=(LATITUDE, LONGITUDE)):
"""
Extract the exclusion coordinates for teh desired gids for TechMapping.
Extract the exclusion coordinates for the desired gids for TechMapping.
Parameters
----------
Expand Down
2 changes: 1 addition & 1 deletion reV/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
reV Version number
"""

__version__ = "0.9.3"
__version__ = "0.9.4"
9 changes: 5 additions & 4 deletions tests/test_bespoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -1514,12 +1514,13 @@ def test_cli(runner, clear_loggers):
fn_out = "{}_{}.h5".format(dirname, ModuleName.BESPOKE)
out_fpath = os.path.join(td, fn_out)

res_fp = os.path.join(td, "ri_100_wtk_{}.h5")
res_fp_1 = os.path.join(td, "ri_100_wtk_{}.h5")
res_fp_2 = os.path.join(td, "another_name_{}.h5")
excl_fp = os.path.join(td, "ri_exclusions.h5")
shutil.copy(EXCL, excl_fp)
shutil.copy(RES.format(2012), res_fp.format(2012))
shutil.copy(RES.format(2013), res_fp.format(2013))
res_fp = res_fp.format("*")
shutil.copy(RES.format(2012), res_fp_1.format(2012))
shutil.copy(RES.format(2013), res_fp_2.format(2013))
res_fp = [res_fp_1.format(2012), res_fp_2.format("*")]

TechMapping.run(excl_fp, RES.format(2012), dset=TM_DSET, max_workers=1)

Expand Down

0 comments on commit 7d4a339

Please sign in to comment.