NREL-reV 0.8.9__py3-none-any.whl → 0.9.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -113,7 +113,7 @@ class Gen(BaseGen):
113
113
  allowed and/or required SAM config file inputs. If economic
114
114
  parameters are supplied in the SAM config, then you can bundle a
115
115
  "follow-on" econ calculation by just adding the desired econ
116
- output keys to the `output_request`. You can request ``reV`` to '
116
+ output keys to the `output_request`. You can request ``reV`` to
117
117
  run the analysis for one or more "sites", which correspond to
118
118
  the meta indices in the resource data (also commonly called the
119
119
  ``gid's``).
@@ -128,7 +128,7 @@ class Gen(BaseGen):
128
128
  >>> import os
129
129
  >>> from reV import Gen, TESTDATADIR
130
130
  >>>
131
- >>> sam_tech = 'pvwattsv7'
131
+ >>> sam_tech = 'pvwattsv8'
132
132
  >>> sites = 0
133
133
  >>> fp_sam = os.path.join(TESTDATADIR, 'SAM/naris_pv_1axis_inv13.json')
134
134
  >>> fp_res = os.path.join(TESTDATADIR, 'nsrdb/ri_100_nsrdb_2013.h5')
@@ -145,15 +145,16 @@ class Gen(BaseGen):
145
145
  >>> gen.run()
146
146
  >>>
147
147
  >>> gen.out
148
- {'lcoe_fcr': array([131.39166, 131.31221, 127.54539, 125.49656]),
149
- 'cf_mean': array([0.17713654, 0.17724372, 0.1824783 , 0.1854574 ]),
150
- : array([[0., 0., 0., 0.],
151
- [0., 0., 0., 0.],
152
- [0., 0., 0., 0.],
153
- ...,
154
- [0., 0., 0., 0.],
155
- [0., 0., 0., 0.],
156
- [0., 0., 0., 0.]])}
148
+ {'fixed_charge_rate': array([0.096, 0.096, 0.096, 0.096],
149
+ 'base_capital_cost': array([39767200, 39767200, 39767200, 39767200],
150
+ 'base_variable_operating_cost': array([0, 0, 0, 0],
151
+ 'base_fixed_operating_cost': array([260000, 260000, 260000, 260000],
152
+ 'capital_cost': array([39767200, 39767200, 39767200, 39767200],
153
+ 'fixed_operating_cost': array([260000, 260000, 260000, 260000],
154
+ 'variable_operating_cost': array([0, 0, 0, 0],
155
+ 'capital_cost_multiplier': array([1, 1, 1, 1],
156
+ 'cf_mean': array([0.17859147, 0.17869979, 0.1834818 , 0.18646291],
157
+ 'lcoe_fcr': array([130.32126, 130.24226, 126.84782, 124.81981]}
157
158
 
158
159
  Parameters
159
160
  ----------
@@ -170,7 +171,7 @@ class Gen(BaseGen):
170
171
  multiple sites can be specified to evaluate reV at multiple
171
172
  specific locations. A string pointing to a project points
172
173
  CSV file may also be specified. Typically, the CSV contains
173
- two columns:
174
+ the following columns:
174
175
 
175
176
  - ``gid``: Integer specifying the generation GID of each
176
177
  site.
@@ -180,16 +181,25 @@ class Gen(BaseGen):
180
181
  ``None`` (or left out completely) if you specify only
181
182
  a single SAM configuration file as the `sam_files`
182
183
  input.
183
-
184
- The CSV file may also contain site-specific inputs by
184
+ - ``capital_cost_multiplier``: This is an *optional*
185
+ multiplier input that, if included, will be used to
186
+ regionally scale the ``capital_cost`` input in the SAM
187
+ config. If you include this column in your CSV, you
188
+ *do not* need to specify ``capital_cost``, unless you
189
+ would like that value to vary regionally and
190
+ independently of the multiplier (i.e. the multiplier
191
+ will still be applied on top of the ``capital_cost``
192
+ input).
193
+
194
+ The CSV file may also contain other site-specific inputs by
185
195
  including a column named after a config keyword (e.g. a
186
- column called ``capital_cost`` may be included to specify a
187
- site-specific capital cost value for each location). Columns
188
- that do not correspond to a config key may also be included,
189
- but they will be ignored. A DataFrame following the same
190
- guidelines as the CSV input (or a dictionary that can be
191
- used to initialize such a DataFrame) may be used for this
192
- input as well.
196
+ column called ``wind_turbine_rotor_diameter`` may be
197
+ included to specify a site-specific turbine diameter for
198
+ each location). Columns that do not correspond to a config
199
+ key may also be included, but they will be ignored. A
200
+ DataFrame following the same guidelines as the CSV input
201
+ (or a dictionary that can be used to initialize such a
202
+ DataFrame) may be used for this input as well.
193
203
 
194
204
  .. Note:: By default, the generation GID of each site is
195
205
  assumed to match the resource GID to be evaluated for that
@@ -454,7 +464,7 @@ class Gen(BaseGen):
454
464
  Meta data df for sites in project points. Column names are meta
455
465
  data variables, rows are different sites. The row index
456
466
  does not indicate the site number if the project points are
457
- non-sequential or do not start from 0, so a `SupplyCurveField.GID`
467
+ non-sequential or do not start from 0, so a `SiteDataField.GID`
458
468
  column is added.
459
469
  """
460
470
  if self._meta is None:
@@ -712,6 +722,8 @@ class Gen(BaseGen):
712
722
  for k in site_output.keys():
713
723
  # iterate through variable names in each site's output dict
714
724
  if k in cls.OUT_ATTRS:
725
+ if out[site][k] is None:
726
+ continue
715
727
  # get dtype and scale for output variable name
716
728
  dtype = cls.OUT_ATTRS[k].get("dtype", "float32")
717
729
  scale_factor = cls.OUT_ATTRS[k].get("scale_factor", 1)
@@ -947,12 +959,20 @@ class Gen(BaseGen):
947
959
  Output variables requested from SAM.
948
960
  """
949
961
 
950
- output_request = self._output_request_type_check(req)
962
+ output_request = super()._parse_output_request(req)
951
963
 
952
964
  # ensure that cf_mean is requested from output
953
965
  if "cf_mean" not in output_request:
954
966
  output_request.append("cf_mean")
955
967
 
968
+ if _is_solar_run_with_ac_outputs(self.tech):
969
+ if "dc_ac_ratio" not in output_request:
970
+ output_request.append("dc_ac_ratio")
971
+ for dset in ["cf_mean", "cf_profile"]:
972
+ ac_dset = f"{dset}_ac"
973
+ if dset in output_request and ac_dset not in output_request:
974
+ output_request.append(ac_dset)
975
+
956
976
  for request in output_request:
957
977
  if request not in self.OUT_ATTRS:
958
978
  msg = (
@@ -1097,3 +1117,10 @@ class Gen(BaseGen):
1097
1117
  raise e
1098
1118
 
1099
1119
  return self._out_fpath
1120
+
1121
+
1122
+ def _is_solar_run_with_ac_outputs(tech):
1123
+ """True if tech is pvwattsv8+"""
1124
+ if "pvwatts" not in tech.casefold():
1125
+ return False
1126
+ return tech.casefold() not in {f"pvwattsv{i}" for i in range(8)}
@@ -4,7 +4,7 @@
4
4
  "dtype": "float32",
5
5
  "scale_factor": 1,
6
6
  "type": "scalar",
7
- "units": "dollars"
7
+ "units": "usd"
8
8
  },
9
9
  "fixed_charge_rate": {
10
10
  "chunks": null,
@@ -18,13 +18,48 @@
18
18
  "dtype": "float32",
19
19
  "scale_factor": 1,
20
20
  "type": "scalar",
21
- "units": "dollars"
21
+ "units": "usd"
22
22
  },
23
23
  "variable_operating_cost": {
24
24
  "chunks": null,
25
25
  "dtype": "float32",
26
26
  "scale_factor": 1,
27
27
  "type": "scalar",
28
- "units": "dol/kWh"
28
+ "units": "usd/kWh"
29
+ },
30
+ "base_capital_cost": {
31
+ "chunks": null,
32
+ "dtype": "float32",
33
+ "scale_factor": 1,
34
+ "type": "scalar",
35
+ "units": "usd"
36
+ },
37
+ "base_fixed_operating_cost": {
38
+ "chunks": null,
39
+ "dtype": "float32",
40
+ "scale_factor": 1,
41
+ "type": "scalar",
42
+ "units": "usd"
43
+ },
44
+ "base_variable_operating_cost": {
45
+ "chunks": null,
46
+ "dtype": "float32",
47
+ "scale_factor": 1,
48
+ "type": "scalar",
49
+ "units": "usd/kWh"
50
+ },
51
+ "capital_cost_multiplier": {
52
+ "chunks": null,
53
+ "dtype": "float32",
54
+ "scale_factor": 1,
55
+ "type": "scalar",
56
+ "units": "unitless"
57
+ },
58
+ "system_capacity": {
59
+ "chunks": null,
60
+ "dtype": "float32",
61
+ "scale_factor": 1,
62
+ "type": "scalar",
63
+ "units": "kW"
29
64
  }
30
65
  }
reV/handlers/__init__.py CHANGED
@@ -3,5 +3,4 @@
3
3
  Sub-package of data handlers
4
4
  """
5
5
  from .exclusions import ExclusionLayers
6
- from .multi_year import MultiYear
7
6
  from .outputs import Outputs
@@ -18,6 +18,7 @@ from rex.utilities.utilities import (
18
18
  parse_year,
19
19
  )
20
20
 
21
+ from reV.generation.base import LCOE_REQUIRED_OUTPUTS
21
22
  from reV.config.output_request import SAMOutputRequest
22
23
  from reV.handlers.outputs import Outputs
23
24
  from reV.utilities import ModuleName, log_versions
@@ -60,8 +61,12 @@ class MultiYearGroup:
60
61
  source files. This takes priority over `source_dir` and
61
62
  `source_prefix` but is not used if `source_files` are
62
63
  specified explicitly. By default, ``None``.
63
- dsets : list | tuple, optional
64
- List of datasets to collect. By default, ``('cf_mean',)``.
64
+ dsets : str | list | tuple, optional
65
+ List of datasets to collect. This can be set to
66
+ ``"PIPELINE"`` if running from the command line as part of a
67
+ reV pipeline. In this case, all the datasets from the
68
+ previous pipeline step will be collected.
69
+ By default, ``('cf_mean',)``.
65
70
  pass_through_dsets : list | tuple, optional
66
71
  Optional list of datasets that are identical in the
67
72
  multi-year files (e.g. input datasets that don't vary from
@@ -76,10 +81,35 @@ class MultiYearGroup:
76
81
  self._source_prefix = source_prefix
77
82
  self._source_pattern = source_pattern
78
83
  self._pass_through_dsets = None
79
- if pass_through_dsets is not None:
80
- self._pass_through_dsets = SAMOutputRequest(pass_through_dsets)
84
+ self._dsets = None
81
85
 
82
- self._dsets = self._parse_dsets(dsets)
86
+ self._parse_pass_through_dsets(dsets, pass_through_dsets or [])
87
+ self._parse_dsets(dsets)
88
+
89
+ def _parse_pass_through_dsets(self, dsets, pass_through_dsets):
90
+ """Parse a multi-year pass-through dataset collection request.
91
+
92
+ Parameters
93
+ ----------
94
+ dsets : str | list
95
+ One or more datasets to collect, or "PIPELINE"
96
+ pass_through_dsets : list
97
+ List of pass through datasets.
98
+ """
99
+ if isinstance(dsets, str) and dsets == 'PIPELINE':
100
+ files = parse_previous_status(self._dirout, ModuleName.MULTI_YEAR)
101
+ with Resource(files[0]) as res:
102
+ dsets = res.datasets
103
+
104
+ if "lcoe_fcr" in dsets:
105
+ for dset in LCOE_REQUIRED_OUTPUTS:
106
+ if dset not in pass_through_dsets:
107
+ pass_through_dsets.append(dset)
108
+ if "dc_ac_ratio" in dsets:
109
+ if "dc_ac_ratio" not in pass_through_dsets:
110
+ pass_through_dsets.append("dc_ac_ratio")
111
+
112
+ self._pass_through_dsets = SAMOutputRequest(pass_through_dsets)
83
113
 
84
114
  def _parse_dsets(self, dsets):
85
115
  """Parse a multi-year dataset collection request. Can handle PIPELINE
@@ -90,11 +120,6 @@ class MultiYearGroup:
90
120
  ----------
91
121
  dsets : str | list
92
122
  One or more datasets to collect, or "PIPELINE"
93
-
94
- Returns
95
- -------
96
- dsets : SAMOutputRequest
97
- Dataset list object.
98
123
  """
99
124
  if isinstance(dsets, str) and dsets == 'PIPELINE':
100
125
  files = parse_previous_status(self._dirout, ModuleName.MULTI_YEAR)
@@ -104,9 +129,7 @@ class MultiYearGroup:
104
129
  and d != 'meta'
105
130
  and d not in self.pass_through_dsets]
106
131
 
107
- dsets = SAMOutputRequest(dsets)
108
-
109
- return dsets
132
+ self._dsets = SAMOutputRequest(dsets)
110
133
 
111
134
  @property
112
135
  def name(self):
@@ -815,10 +838,15 @@ def my_collect_groups(out_fpath, groups, clobber=True):
815
838
  MultiYear.collect_means(out_fpath, group['source_files'],
816
839
  dset, group=group['group'])
817
840
 
818
- if group.get('pass_through_dsets', None) is not None:
819
- for dset in group['pass_through_dsets']:
820
- MultiYear.pass_through(out_fpath, group['source_files'],
821
- dset, group=group['group'])
841
+ pass_through_dsets = group.get('pass_through_dsets') or []
842
+ if "lcoe_fcr" in group['dsets']:
843
+ for dset in LCOE_REQUIRED_OUTPUTS:
844
+ if dset not in pass_through_dsets:
845
+ pass_through_dsets.append(dset)
846
+
847
+ for dset in pass_through_dsets:
848
+ MultiYear.pass_through(out_fpath, group['source_files'],
849
+ dset, group=group['group'])
822
850
 
823
851
  runtime = (time.time() - t0) / 60
824
852
  logger.info('- {} collection completed in: {:.2f} min.'
@@ -9,6 +9,7 @@ import os
9
9
  import pandas as pd
10
10
  from warnings import warn
11
11
 
12
+ from reV.utilities import SupplyCurveField
12
13
  from reV.utilities.exceptions import (HandlerWarning, HandlerKeyError,
13
14
  HandlerRuntimeError)
14
15
 
@@ -153,12 +154,17 @@ class TransmissionFeatures:
153
154
  raise
154
155
 
155
156
  trans_table = \
156
- trans_table.rename(columns={'trans_line_gid': 'trans_gid',
157
- 'trans_gids': 'trans_line_gids'})
158
-
159
- if 'dist_mi' in trans_table and 'dist_km' not in trans_table:
160
- trans_table = trans_table.rename(columns={'dist_mi': 'dist_km'})
161
- trans_table['dist_km'] *= 1.60934
157
+ trans_table.rename(
158
+ columns={'trans_line_gid': SupplyCurveField.TRANS_GID,
159
+ 'trans_gids': 'trans_line_gids'})
160
+
161
+ contains_dist_in_miles = "dist_mi" in trans_table
162
+ missing_km_dist = SupplyCurveField.DIST_SPUR_KM not in trans_table
163
+ if contains_dist_in_miles and missing_km_dist:
164
+ trans_table = trans_table.rename(
165
+ columns={"dist_mi": SupplyCurveField.DIST_SPUR_KM}
166
+ )
167
+ trans_table[SupplyCurveField.DIST_SPUR_KM] *= 1.60934
162
168
 
163
169
  return trans_table
164
170
 
@@ -184,23 +190,28 @@ class TransmissionFeatures:
184
190
  features = {}
185
191
 
186
192
  cap_frac = self._avail_cap_frac
187
- trans_features = trans_table.groupby('trans_gid').first()
193
+ trans_features = trans_table.groupby(SupplyCurveField.TRANS_GID)
194
+ trans_features = trans_features.first()
188
195
 
189
196
  for gid, feature in trans_features.iterrows():
190
- name = feature['category'].lower()
197
+ name = feature[SupplyCurveField.TRANS_TYPE].lower()
191
198
  feature_dict = {'type': name}
192
199
 
193
200
  if name == 'transline':
194
- feature_dict['avail_cap'] = feature['ac_cap'] * cap_frac
201
+ feature_dict[SupplyCurveField.TRANS_CAPACITY] = (
202
+ feature['ac_cap'] * cap_frac
203
+ )
195
204
 
196
205
  elif name == 'substation':
197
206
  feature_dict['lines'] = json.loads(feature['trans_line_gids'])
198
207
 
199
208
  elif name == 'loadcen':
200
- feature_dict['avail_cap'] = feature['ac_cap'] * cap_frac
209
+ feature_dict[SupplyCurveField.TRANS_CAPACITY] = (
210
+ feature['ac_cap'] * cap_frac
211
+ )
201
212
 
202
213
  elif name == 'pcaloadcen':
203
- feature_dict['avail_cap'] = None
214
+ feature_dict[SupplyCurveField.TRANS_CAPACITY] = None
204
215
 
205
216
  else:
206
217
  msg = ('Cannot not recognize feature type "{}" '
@@ -297,7 +308,8 @@ class TransmissionFeatures:
297
308
  Substation available capacity
298
309
  """
299
310
  try:
300
- line_caps = [self[l_gid]['avail_cap'] for l_gid in line_gids]
311
+ line_caps = [self[l_gid][SupplyCurveField.TRANS_CAPACITY]
312
+ for l_gid in line_gids]
301
313
  except HandlerKeyError as e:
302
314
  msg = ('Could not find capacities for substation gid {} and '
303
315
  'connected lines: {}'.format(gid, line_gids))
@@ -331,8 +343,8 @@ class TransmissionFeatures:
331
343
 
332
344
  feature = self[gid]
333
345
 
334
- if 'avail_cap' in feature:
335
- avail_cap = feature['avail_cap']
346
+ if SupplyCurveField.TRANS_CAPACITY in feature:
347
+ avail_cap = feature[SupplyCurveField.TRANS_CAPACITY]
336
348
 
337
349
  elif 'lines' in feature:
338
350
  avail_cap = self._substation_capacity(gid, feature['lines'])
@@ -387,7 +399,7 @@ class TransmissionFeatures:
387
399
  capacity : float
388
400
  Capacity needed in MW
389
401
  """
390
- avail_cap = self[gid]['avail_cap']
402
+ avail_cap = self[gid][SupplyCurveField.TRANS_CAPACITY]
391
403
 
392
404
  if avail_cap < capacity:
393
405
  msg = ("Cannot connect to {}: "
@@ -397,7 +409,7 @@ class TransmissionFeatures:
397
409
  logger.error(msg)
398
410
  raise RuntimeError(msg)
399
411
 
400
- self[gid]['avail_cap'] -= capacity
412
+ self[gid][SupplyCurveField.TRANS_CAPACITY] -= capacity
401
413
 
402
414
  def _fill_lines(self, line_gids, line_caps, capacity):
403
415
  """
@@ -471,7 +483,7 @@ class TransmissionFeatures:
471
483
  Substation connection is limited by maximum capacity of the
472
484
  attached lines
473
485
  """
474
- line_caps = np.array([self[gid]['avail_cap']
486
+ line_caps = np.array([self[gid][SupplyCurveField.TRANS_CAPACITY]
475
487
  for gid in line_gids])
476
488
  if self._line_limited:
477
489
  gid = line_gids[np.argmax(line_caps)]
@@ -603,8 +615,8 @@ class TransmissionFeatures:
603
615
  raise
604
616
 
605
617
  feature_cap = pd.Series(feature_cap)
606
- feature_cap.name = 'avail_cap'
607
- feature_cap.index.name = 'trans_gid'
618
+ feature_cap.name = SupplyCurveField.TRANS_CAPACITY
619
+ feature_cap.index.name = SupplyCurveField.TRANS_GID
608
620
  feature_cap = feature_cap.to_frame().reset_index()
609
621
 
610
622
  return feature_cap
@@ -635,16 +647,20 @@ class TransmissionCosts(TransmissionFeatures):
635
647
 
636
648
  features = {}
637
649
 
638
- if 'avail_cap' not in trans_table:
650
+ if SupplyCurveField.TRANS_CAPACITY not in trans_table:
639
651
  kwargs = {'avail_cap_frac': self._avail_cap_frac}
640
652
  fc = TransmissionFeatures.feature_capacity(trans_table,
641
653
  **kwargs)
642
- trans_table = trans_table.merge(fc, on='trans_gid')
654
+ trans_table = trans_table.merge(fc, on=SupplyCurveField.TRANS_GID)
643
655
 
644
- trans_features = trans_table.groupby('trans_gid').first()
656
+ trans_features = trans_table.groupby(SupplyCurveField.TRANS_GID)
657
+ trans_features = trans_features.first()
645
658
  for gid, feature in trans_features.iterrows():
646
- name = feature['category'].lower()
647
- feature_dict = {'type': name, 'avail_cap': feature['avail_cap']}
659
+ name = feature[SupplyCurveField.TRANS_TYPE].lower()
660
+ feature_dict = {'type': name,
661
+ SupplyCurveField.TRANS_CAPACITY: (
662
+ feature[SupplyCurveField.TRANS_CAPACITY]
663
+ )}
648
664
  features[gid] = feature_dict
649
665
 
650
666
  return features
@@ -665,7 +681,7 @@ class TransmissionCosts(TransmissionFeatures):
665
681
  default = 100%
666
682
  """
667
683
 
668
- return self[gid]['avail_cap']
684
+ return self[gid][SupplyCurveField.TRANS_CAPACITY]
669
685
 
670
686
  @classmethod
671
687
  def feature_costs(cls, trans_table, capacity=None, line_tie_in_cost=14000,
@@ -722,8 +738,9 @@ class TransmissionCosts(TransmissionFeatures):
722
738
  costs = []
723
739
  for _, row in trans_table.iterrows():
724
740
  tm = row.get('transmission_multiplier', 1)
725
- costs.append(feature.cost(row['trans_gid'],
726
- row['dist_km'], capacity=capacity,
741
+ costs.append(feature.cost(row[SupplyCurveField.TRANS_GID],
742
+ row[SupplyCurveField.DIST_SPUR_KM],
743
+ capacity=capacity,
727
744
  transmission_multiplier=tm))
728
745
  except Exception:
729
746
  logger.exception("Error computing costs for all connections in {}"
@@ -31,9 +31,9 @@ def aggregate_solar_capacity(h):
31
31
  capacity ratio and the solar capacity is copied into this new
32
32
  column.
33
33
  """
34
- if f'hybrid_solar_{SupplyCurveField.CAPACITY}' in h.hybrid_meta:
34
+ if f'hybrid_solar_{SupplyCurveField.CAPACITY_AC_MW}' in h.hybrid_meta:
35
35
  return None
36
- return h.hybrid_meta[f'solar_{SupplyCurveField.CAPACITY}']
36
+ return h.hybrid_meta[f'solar_{SupplyCurveField.CAPACITY_AC_MW}']
37
37
 
38
38
 
39
39
  def aggregate_wind_capacity(h):
@@ -60,9 +60,9 @@ def aggregate_wind_capacity(h):
60
60
  exist, it is assumed that there is no limit on the solar to wind
61
61
  capacity ratio and the wind capacity is copied into this new column.
62
62
  """
63
- if f'hybrid_wind_{SupplyCurveField.CAPACITY}' in h.hybrid_meta:
63
+ if f'hybrid_wind_{SupplyCurveField.CAPACITY_AC_MW}' in h.hybrid_meta:
64
64
  return None
65
- return h.hybrid_meta[f'wind_{SupplyCurveField.CAPACITY}']
65
+ return h.hybrid_meta[f'wind_{SupplyCurveField.CAPACITY_AC_MW}']
66
66
 
67
67
 
68
68
  def aggregate_capacity(h):
@@ -81,8 +81,8 @@ def aggregate_capacity(h):
81
81
  A series of data containing the aggregated capacity, or `None`
82
82
  if the capacity columns are missing.
83
83
  """
84
- sc = f'hybrid_solar_{SupplyCurveField.CAPACITY}'
85
- wc = f'hybrid_wind_{SupplyCurveField.CAPACITY}'
84
+ sc = f'hybrid_solar_{SupplyCurveField.CAPACITY_AC_MW}'
85
+ wc = f'hybrid_wind_{SupplyCurveField.CAPACITY_AC_MW}'
86
86
  missing_solar_cap = sc not in h.hybrid_meta.columns
87
87
  missing_wind_cap = wc not in h.hybrid_meta.columns
88
88
  if missing_solar_cap or missing_wind_cap:
@@ -109,10 +109,10 @@ def aggregate_capacity_factor(h):
109
109
  if the capacity and/or mean_cf columns are missing.
110
110
  """
111
111
 
112
- sc = f'hybrid_solar_{SupplyCurveField.CAPACITY}'
113
- wc = f'hybrid_wind_{SupplyCurveField.CAPACITY}'
114
- scf = f'solar_{SupplyCurveField.MEAN_CF}'
115
- wcf = f'wind_{SupplyCurveField.MEAN_CF}'
112
+ sc = f'hybrid_solar_{SupplyCurveField.CAPACITY_AC_MW}'
113
+ wc = f'hybrid_wind_{SupplyCurveField.CAPACITY_AC_MW}'
114
+ scf = f'solar_{SupplyCurveField.MEAN_CF_AC}'
115
+ wcf = f'wind_{SupplyCurveField.MEAN_CF_AC}'
116
116
  missing_solar_cap = sc not in h.hybrid_meta.columns
117
117
  missing_wind_cap = wc not in h.hybrid_meta.columns
118
118
  missing_solar_mean_cf = scf not in h.hybrid_meta.columns
@@ -130,8 +130,10 @@ def aggregate_capacity_factor(h):
130
130
 
131
131
 
132
132
  HYBRID_METHODS = {
133
- f'hybrid_solar_{SupplyCurveField.CAPACITY}': aggregate_solar_capacity,
134
- f'hybrid_wind_{SupplyCurveField.CAPACITY}': aggregate_wind_capacity,
135
- f'hybrid_{SupplyCurveField.CAPACITY}': aggregate_capacity,
136
- f'hybrid_{SupplyCurveField.MEAN_CF}': aggregate_capacity_factor
133
+ f'hybrid_solar_{SupplyCurveField.CAPACITY_AC_MW}': (
134
+ aggregate_solar_capacity
135
+ ),
136
+ f'hybrid_wind_{SupplyCurveField.CAPACITY_AC_MW}': aggregate_wind_capacity,
137
+ f'hybrid_{SupplyCurveField.CAPACITY_AC_MW}': aggregate_capacity,
138
+ f'hybrid_{SupplyCurveField.MEAN_CF_AC}': aggregate_capacity_factor
137
139
  }
reV/hybrids/hybrids.py CHANGED
@@ -38,11 +38,11 @@ NON_DUPLICATE_COLS = {
38
38
  SupplyCurveField.SC_POINT_GID, SupplyCurveField.SC_ROW_IND,
39
39
  SupplyCurveField.SC_COL_IND
40
40
  }
41
- DROPPED_COLUMNS = [SupplyCurveField.GID]
42
- DEFAULT_FILL_VALUES = {f'solar_{SupplyCurveField.CAPACITY}': 0,
43
- f'wind_{SupplyCurveField.CAPACITY}': 0,
44
- f'solar_{SupplyCurveField.MEAN_CF}': 0,
45
- f'wind_{SupplyCurveField.MEAN_CF}': 0}
41
+ HYBRIDS_GID_COL = "gid"
42
+ DEFAULT_FILL_VALUES = {f'solar_{SupplyCurveField.CAPACITY_AC_MW}': 0,
43
+ f'wind_{SupplyCurveField.CAPACITY_AC_MW}': 0,
44
+ f'solar_{SupplyCurveField.MEAN_CF_AC}': 0,
45
+ f'wind_{SupplyCurveField.MEAN_CF_AC}': 0}
46
46
  OUTPUT_PROFILE_NAMES = ['hybrid_profile',
47
47
  'hybrid_solar_profile',
48
48
  'hybrid_wind_profile']
@@ -702,7 +702,7 @@ class MetaHybridizer:
702
702
  self._propagate_duplicate_cols(duplicate_cols)
703
703
  self._drop_cols(duplicate_cols)
704
704
  self._hybrid_meta.rename(self.__col_name_map, inplace=True, axis=1)
705
- self._hybrid_meta.index.name = SupplyCurveField.GID
705
+ self._hybrid_meta.index.name = HYBRIDS_GID_COL
706
706
 
707
707
  def _propagate_duplicate_cols(self, duplicate_cols):
708
708
  """Fill missing column values from outer merge."""
@@ -713,9 +713,9 @@ class MetaHybridizer:
713
713
  self._hybrid_meta.loc[null_idx, no_suffix] = non_null_vals
714
714
 
715
715
  def _drop_cols(self, duplicate_cols):
716
- """Drop any remaning duplicate and 'DROPPED_COLUMNS' columns."""
716
+ """Drop any remaining duplicate and 'HYBRIDS_GID_COL' columns."""
717
717
  self._hybrid_meta.drop(
718
- duplicate_cols + DROPPED_COLUMNS,
718
+ duplicate_cols + [HYBRIDS_GID_COL],
719
719
  axis=1,
720
720
  inplace=True,
721
721
  errors="ignore",
@@ -1196,8 +1196,8 @@ class Hybridization:
1196
1196
  def __rep_profile_hybridization_params(self):
1197
1197
  """Zip the rep profile hybridization parameters."""
1198
1198
 
1199
- cap_col_names = [f"hybrid_solar_{SupplyCurveField.CAPACITY}",
1200
- f"hybrid_wind_{SupplyCurveField.CAPACITY}"]
1199
+ cap_col_names = [f"hybrid_solar_{SupplyCurveField.CAPACITY_AC_MW}",
1200
+ f"hybrid_wind_{SupplyCurveField.CAPACITY_AC_MW}"]
1201
1201
  idx_maps = [
1202
1202
  self.meta_hybridizer.solar_profile_indices_map,
1203
1203
  self.meta_hybridizer.wind_profile_indices_map,
reV/nrwal/nrwal.py CHANGED
@@ -37,7 +37,7 @@ class RevNrwal:
37
37
 
38
38
  def __init__(self, gen_fpath, site_data, sam_files, nrwal_configs,
39
39
  output_request, save_raw=True,
40
- meta_gid_col=ResourceMetaField.GID,
40
+ meta_gid_col=str(ResourceMetaField.GID), # str() to fix docs
41
41
  site_meta_cols=None):
42
42
  """Framework to handle reV-NRWAL analysis.
43
43
 
reV/qa_qc/qa_qc.py CHANGED
@@ -105,7 +105,7 @@ class QaQc:
105
105
  if file.endswith(".csv"):
106
106
  summary_csv = os.path.join(self.out_dir, file)
107
107
  summary = pd.read_csv(summary_csv)
108
- has_right_cols = (SupplyCurveField.GID in summary
108
+ has_right_cols = ("gid" in summary
109
109
  and SupplyCurveField.LATITUDE in summary
110
110
  and SupplyCurveField.LONGITUDE in summary)
111
111
  if has_right_cols:
reV/qa_qc/summary.py CHANGED
@@ -597,11 +597,11 @@ class SummaryPlots(PlotBase):
597
597
  sc_df : pandas.DataFrame
598
598
  Supply curve data
599
599
  """
600
- values = [SupplyCurveField.CAPACITY, lcoe]
600
+ values = [SupplyCurveField.CAPACITY_AC_MW, lcoe]
601
601
  self._check_value(self.summary, values, scatter=False)
602
602
  sc_df = self.summary[values].sort_values(lcoe)
603
603
  sc_df['cumulative_capacity'] = (
604
- sc_df[SupplyCurveField.CAPACITY].cumsum()
604
+ sc_df[SupplyCurveField.CAPACITY_AC_MW].cumsum()
605
605
  )
606
606
 
607
607
  return sc_df
@@ -800,11 +800,11 @@ class SupplyCurvePlot(PlotBase):
800
800
  sc_df : pandas.DataFrame
801
801
  Supply curve data
802
802
  """
803
- values = [SupplyCurveField.CAPACITY, lcoe]
803
+ values = [SupplyCurveField.CAPACITY_AC_MW, lcoe]
804
804
  self._check_value(self.sc_table, values, scatter=False)
805
805
  sc_df = self.sc_table[values].sort_values(lcoe)
806
806
  sc_df['cumulative_capacity'] = (
807
- sc_df[SupplyCurveField.CAPACITY].cumsum()
807
+ sc_df[SupplyCurveField.CAPACITY_AC_MW].cumsum()
808
808
  )
809
809
 
810
810
  return sc_df
@@ -953,7 +953,7 @@ class RepProfiles(RepProfilesBase):
953
953
  def __init__(self, gen_fpath, rev_summary, reg_cols,
954
954
  cf_dset='cf_profile',
955
955
  rep_method='meanoid', err_method='rmse',
956
- weight=SupplyCurveField.GID_COUNTS,
956
+ weight=str(SupplyCurveField.GID_COUNTS), # str() to fix docs
957
957
  n_profiles=1, aggregate_profiles=False):
958
958
  """ReV rep profiles class.
959
959
 
@@ -111,7 +111,7 @@ class LayerMask:
111
111
  specifications to create a boolean mask that defines the
112
112
  extent to which the original mask should be applied.
113
113
  For example, suppose you specify the input the following
114
- way:
114
+ way::
115
115
 
116
116
  input_dict = {
117
117
  "viewsheds": {