NREL-reV 0.8.7__py3-none-any.whl → 0.8.9__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.
Files changed (38) hide show
  1. {NREL_reV-0.8.7.dist-info → NREL_reV-0.8.9.dist-info}/METADATA +12 -10
  2. {NREL_reV-0.8.7.dist-info → NREL_reV-0.8.9.dist-info}/RECORD +38 -38
  3. {NREL_reV-0.8.7.dist-info → NREL_reV-0.8.9.dist-info}/WHEEL +1 -1
  4. reV/SAM/SAM.py +182 -133
  5. reV/SAM/econ.py +18 -14
  6. reV/SAM/generation.py +608 -419
  7. reV/SAM/windbos.py +93 -79
  8. reV/bespoke/bespoke.py +690 -445
  9. reV/bespoke/place_turbines.py +6 -6
  10. reV/config/project_points.py +220 -140
  11. reV/econ/econ.py +165 -113
  12. reV/econ/economies_of_scale.py +57 -34
  13. reV/generation/base.py +310 -183
  14. reV/generation/generation.py +298 -190
  15. reV/handlers/exclusions.py +16 -15
  16. reV/handlers/multi_year.py +12 -9
  17. reV/handlers/outputs.py +6 -5
  18. reV/hybrids/hybrid_methods.py +28 -30
  19. reV/hybrids/hybrids.py +304 -188
  20. reV/nrwal/nrwal.py +262 -168
  21. reV/qa_qc/cli_qa_qc.py +14 -10
  22. reV/qa_qc/qa_qc.py +217 -119
  23. reV/qa_qc/summary.py +228 -146
  24. reV/rep_profiles/rep_profiles.py +349 -230
  25. reV/supply_curve/aggregation.py +349 -188
  26. reV/supply_curve/competitive_wind_farms.py +90 -48
  27. reV/supply_curve/exclusions.py +138 -85
  28. reV/supply_curve/extent.py +75 -50
  29. reV/supply_curve/points.py +536 -309
  30. reV/supply_curve/sc_aggregation.py +366 -225
  31. reV/supply_curve/supply_curve.py +505 -308
  32. reV/supply_curve/tech_mapping.py +144 -82
  33. reV/utilities/__init__.py +199 -16
  34. reV/utilities/pytest_utils.py +8 -4
  35. reV/version.py +1 -1
  36. {NREL_reV-0.8.7.dist-info → NREL_reV-0.8.9.dist-info}/LICENSE +0 -0
  37. {NREL_reV-0.8.7.dist-info → NREL_reV-0.8.9.dist-info}/entry_points.txt +0 -0
  38. {NREL_reV-0.8.7.dist-info → NREL_reV-0.8.9.dist-info}/top_level.txt +0 -0
reV/econ/econ.py CHANGED
@@ -1,26 +1,24 @@
1
1
  # -*- coding: utf-8 -*-
2
- """
3
- reV econ module (lcoe-fcr, single owner, etc...)
4
- """
2
+ """reV econ module (lcoe-fcr, single owner, etc...)"""
5
3
  import logging
6
- import numpy as np
7
4
  import os
8
- import pandas as pd
9
5
  import pprint
10
6
  from warnings import warn
11
7
 
8
+ import numpy as np
9
+ import pandas as pd
10
+ from rex.multi_file_resource import MultiFileResource
11
+ from rex.resource import Resource
12
+ from rex.utilities.utilities import check_res_file
13
+
12
14
  from reV.config.project_points import PointsControl
13
15
  from reV.generation.base import BaseGen
14
16
  from reV.handlers.outputs import Outputs
15
17
  from reV.SAM.econ import LCOE as SAM_LCOE
16
18
  from reV.SAM.econ import SingleOwner
17
19
  from reV.SAM.windbos import WindBos
18
- from reV.utilities.exceptions import (ExecutionError, OffshoreWindInputWarning)
19
- from reV.utilities import ModuleName
20
-
21
- from rex.resource import Resource
22
- from rex.multi_file_resource import MultiFileResource
23
- from rex.utilities.utilities import check_res_file
20
+ from reV.utilities import ModuleName, ResourceMetaField
21
+ from reV.utilities.exceptions import ExecutionError, OffshoreWindInputWarning
24
22
 
25
23
  logger = logging.getLogger(__name__)
26
24
 
@@ -29,22 +27,23 @@ class Econ(BaseGen):
29
27
  """Econ"""
30
28
 
31
29
  # Mapping of reV econ output strings to SAM econ modules
32
- OPTIONS = {'lcoe_fcr': SAM_LCOE,
33
- 'ppa_price': SingleOwner,
34
- 'project_return_aftertax_npv': SingleOwner,
35
- 'lcoe_real': SingleOwner,
36
- 'lcoe_nom': SingleOwner,
37
- 'flip_actual_irr': SingleOwner,
38
- 'gross_revenue': SingleOwner,
39
- 'total_installed_cost': WindBos,
40
- 'turbine_cost': WindBos,
41
- 'sales_tax_cost': WindBos,
42
- 'bos_cost': WindBos,
43
- 'fixed_charge_rate': SAM_LCOE,
44
- 'capital_cost': SAM_LCOE,
45
- 'fixed_operating_cost': SAM_LCOE,
46
- 'variable_operating_cost': SAM_LCOE,
47
- }
30
+ OPTIONS = {
31
+ "lcoe_fcr": SAM_LCOE,
32
+ "ppa_price": SingleOwner,
33
+ "project_return_aftertax_npv": SingleOwner,
34
+ "lcoe_real": SingleOwner,
35
+ "lcoe_nom": SingleOwner,
36
+ "flip_actual_irr": SingleOwner,
37
+ "gross_revenue": SingleOwner,
38
+ "total_installed_cost": WindBos,
39
+ "turbine_cost": WindBos,
40
+ "sales_tax_cost": WindBos,
41
+ "bos_cost": WindBos,
42
+ "fixed_charge_rate": SAM_LCOE,
43
+ "capital_cost": SAM_LCOE,
44
+ "fixed_operating_cost": SAM_LCOE,
45
+ "variable_operating_cost": SAM_LCOE,
46
+ }
48
47
  """Available ``reV`` econ `output_request` options"""
49
48
 
50
49
  # Mapping of reV econ outputs to scale factors and units.
@@ -54,7 +53,7 @@ class Econ(BaseGen):
54
53
  def __init__(self, project_points, sam_files, cf_file, site_data=None,
55
54
  output_request=('lcoe_fcr',), sites_per_worker=100,
56
55
  memory_utilization_limit=0.4, append=False):
57
- """reV econ analysis class.
56
+ """ReV econ analysis class.
58
57
 
59
58
  ``reV`` econ analysis runs SAM econ calculations, typically to
60
59
  compute LCOE (using :py:class:`PySAM.Lcoefcr.Lcoefcr`), though
@@ -176,17 +175,26 @@ class Econ(BaseGen):
176
175
  """
177
176
 
178
177
  # get a points control instance
179
- pc = self.get_pc(points=project_points, points_range=None,
180
- sam_configs=sam_files, cf_file=cf_file,
181
- sites_per_worker=sites_per_worker, append=append)
182
-
183
- super().__init__(pc, output_request, site_data=site_data,
184
- memory_utilization_limit=memory_utilization_limit)
178
+ pc = self.get_pc(
179
+ points=project_points,
180
+ points_range=None,
181
+ sam_configs=sam_files,
182
+ cf_file=cf_file,
183
+ sites_per_worker=sites_per_worker,
184
+ append=append,
185
+ )
186
+
187
+ super().__init__(
188
+ pc,
189
+ output_request,
190
+ site_data=site_data,
191
+ memory_utilization_limit=memory_utilization_limit,
192
+ )
185
193
 
186
194
  self._cf_file = cf_file
187
195
  self._append = append
188
- self._run_attrs['cf_file'] = cf_file
189
- self._run_attrs['sam_module'] = self._sam_module.MODULE
196
+ self._run_attrs["cf_file"] = cf_file
197
+ self._run_attrs["sam_module"] = self._sam_module.MODULE
190
198
 
191
199
  @property
192
200
  def cf_file(self):
@@ -212,19 +220,20 @@ class Econ(BaseGen):
212
220
  with Outputs(self.cf_file) as cfh:
213
221
  # only take meta that belongs to this project's site list
214
222
  self._meta = cfh.meta[
215
- cfh.meta['gid'].isin(self.points_control.sites)]
223
+ cfh.meta[ResourceMetaField.GID].isin(
224
+ self.points_control.sites)]
216
225
 
217
- if 'offshore' in self._meta:
218
- if self._meta['offshore'].sum() > 1:
219
- w = ('Found offshore sites in econ meta data. '
220
- 'This functionality has been deprecated. '
221
- 'Please run the reV offshore module to '
222
- 'calculate offshore wind lcoe.')
223
- warn(w, OffshoreWindInputWarning)
224
- logger.warning(w)
226
+ if ("offshore" in self._meta and self._meta["offshore"].sum() > 1):
227
+ w = ('Found offshore sites in econ meta data. '
228
+ 'This functionality has been deprecated. '
229
+ 'Please run the reV offshore module to '
230
+ 'calculate offshore wind lcoe.')
231
+ warn(w, OffshoreWindInputWarning)
232
+ logger.warning(w)
225
233
 
226
234
  elif self._meta is None and self.cf_file is None:
227
- self._meta = pd.DataFrame({'gid': self.points_control.sites})
235
+ self._meta = pd.DataFrame(
236
+ {ResourceMetaField.GID: self.points_control.sites})
228
237
 
229
238
  return self._meta
230
239
 
@@ -233,7 +242,7 @@ class Econ(BaseGen):
233
242
  """Get the generation resource time index data."""
234
243
  if self._time_index is None and self.cf_file is not None:
235
244
  with Outputs(self.cf_file) as cfh:
236
- if 'time_index' in cfh.datasets:
245
+ if "time_index" in cfh.datasets:
237
246
  self._time_index = cfh.time_index
238
247
 
239
248
  return self._time_index
@@ -264,11 +273,11 @@ class Econ(BaseGen):
264
273
  res_kwargs = {}
265
274
  else:
266
275
  res_cls = Resource
267
- res_kwargs = {'hsds': hsds}
276
+ res_kwargs = {"hsds": hsds}
268
277
 
269
278
  with res_cls(cf_file, **res_kwargs) as f:
270
- gid0 = f.meta['gid'].values[0]
271
- gid1 = f.meta['gid'].values[-1]
279
+ gid0 = f.meta[ResourceMetaField.GID].values[0]
280
+ gid1 = f.meta[ResourceMetaField.GID].values[-1]
272
281
 
273
282
  i0 = pp.index(gid0)
274
283
  i1 = pp.index(gid1) + 1
@@ -277,8 +286,15 @@ class Econ(BaseGen):
277
286
  return pc
278
287
 
279
288
  @classmethod
280
- def get_pc(cls, points, points_range, sam_configs, cf_file,
281
- sites_per_worker=None, append=False):
289
+ def get_pc(
290
+ cls,
291
+ points,
292
+ points_range,
293
+ sam_configs,
294
+ cf_file,
295
+ sites_per_worker=None,
296
+ append=False,
297
+ ):
282
298
  """
283
299
  Get a PointsControl instance.
284
300
 
@@ -311,13 +327,19 @@ class Econ(BaseGen):
311
327
  pc : reV.config.project_points.PointsControl
312
328
  PointsControl object instance.
313
329
  """
314
- pc = super().get_pc(points, points_range, sam_configs, ModuleName.ECON,
315
- sites_per_worker=sites_per_worker,
316
- res_file=cf_file)
330
+ pc = super().get_pc(
331
+ points,
332
+ points_range,
333
+ sam_configs,
334
+ ModuleName.ECON,
335
+ sites_per_worker=sites_per_worker,
336
+ res_file=cf_file,
337
+ )
317
338
 
318
339
  if append:
319
- pc = cls._econ_append_pc(pc.project_points, cf_file,
320
- sites_per_worker=sites_per_worker)
340
+ pc = cls._econ_append_pc(
341
+ pc.project_points, cf_file, sites_per_worker=sites_per_worker
342
+ )
321
343
 
322
344
  return pc
323
345
 
@@ -330,9 +352,10 @@ class Econ(BaseGen):
330
352
  pc : reV.config.project_points.PointsControl
331
353
  Iterable points control object from reV config module.
332
354
  Must have project_points with df property with all relevant
333
- site-specific inputs and a 'gid' column. By passing site-specific
334
- inputs in this dataframe, which was split using points_control,
335
- only the data relevant to the current sites is passed.
355
+ site-specific inputs and a `SupplyCurveField.GID` column.
356
+ By passing site-specific inputs in this dataframe, which
357
+ was split using points_control, only the data relevant to
358
+ the current sites is passed.
336
359
  econ_fun : method
337
360
  reV_run() method from one of the econ modules (SingleOwner,
338
361
  SAM_LCOE, WindBos).
@@ -354,15 +377,16 @@ class Econ(BaseGen):
354
377
 
355
378
  # Extract the site df from the project points df.
356
379
  site_df = pc.project_points.df
357
- site_df = site_df.set_index('gid', drop=True)
380
+ site_df = site_df.set_index(ResourceMetaField.GID, drop=True)
358
381
 
359
382
  # SAM execute econ analysis based on output request
360
383
  try:
361
- out = econ_fun(pc, site_df, output_request=output_request,
362
- **kwargs)
384
+ out = econ_fun(
385
+ pc, site_df, output_request=output_request, **kwargs
386
+ )
363
387
  except Exception as e:
364
388
  out = {}
365
- logger.exception('Worker failed for PC: {}'.format(pc))
389
+ logger.exception("Worker failed for PC: {}".format(pc))
366
390
  raise e
367
391
 
368
392
  return out
@@ -385,20 +409,23 @@ class Econ(BaseGen):
385
409
 
386
410
  for request in output_request:
387
411
  if request not in self.OUT_ATTRS:
388
- msg = ('User output request "{}" not recognized. '
389
- 'Will attempt to extract from PySAM.'.format(request))
412
+ msg = (
413
+ 'User output request "{}" not recognized. '
414
+ "Will attempt to extract from PySAM.".format(request)
415
+ )
390
416
  logger.debug(msg)
391
417
 
392
- modules = []
393
- for request in output_request:
394
- if request in self.OPTIONS:
395
- modules.append(self.OPTIONS[request])
418
+ modules = [self.OPTIONS[request] for request in output_request
419
+ if request in self.OPTIONS]
396
420
 
397
421
  if not any(modules):
398
- msg = ('None of the user output requests were recognized. '
399
- 'Cannot run reV econ. '
400
- 'At least one of the following must be requested: {}'
401
- .format(list(self.OPTIONS.keys())))
422
+ msg = (
423
+ "None of the user output requests were recognized. "
424
+ "Cannot run reV econ. "
425
+ "At least one of the following must be requested: {}".format(
426
+ list(self.OPTIONS.keys())
427
+ )
428
+ )
402
429
  logger.exception(msg)
403
430
  raise ExecutionError(msg)
404
431
 
@@ -413,9 +440,11 @@ class Econ(BaseGen):
413
440
  self._sam_module = SingleOwner
414
441
  self._fun = SingleOwner.reV_run
415
442
  else:
416
- msg = ('Econ outputs requested from different SAM modules not '
417
- 'currently supported. Output request variables require '
418
- 'SAM methods: {}'.format(modules))
443
+ msg = (
444
+ "Econ outputs requested from different SAM modules not "
445
+ "currently supported. Output request variables require "
446
+ "SAM methods: {}".format(modules)
447
+ )
419
448
  raise ValueError(msg)
420
449
 
421
450
  return list(set(output_request))
@@ -441,12 +470,14 @@ class Econ(BaseGen):
441
470
  """
442
471
 
443
472
  if dset in self.site_data:
444
- data_shape = (n_sites, )
473
+ data_shape = (n_sites,)
445
474
  data = self.site_data[dset].values[0]
446
475
 
447
476
  if isinstance(data, (list, tuple, np.ndarray, str)):
448
- msg = ('Cannot pass through non-scalar site_data '
449
- 'input key "{}" as an output_request!'.format(dset))
477
+ msg = (
478
+ "Cannot pass through non-scalar site_data "
479
+ 'input key "{}" as an output_request!'.format(dset)
480
+ )
450
481
  logger.error(msg)
451
482
  raise ExecutionError(msg)
452
483
 
@@ -455,8 +486,7 @@ class Econ(BaseGen):
455
486
 
456
487
  return data_shape
457
488
 
458
- def run(self, out_fpath=None, max_workers=1, timeout=1800,
459
- pool_size=None):
489
+ def run(self, out_fpath=None, max_workers=1, timeout=1800, pool_size=None):
460
490
  """Execute a parallel reV econ run with smart data flushing.
461
491
 
462
492
  Parameters
@@ -494,52 +524,74 @@ class Econ(BaseGen):
494
524
  else:
495
525
  self._init_fpath(out_fpath, ModuleName.ECON)
496
526
 
497
- self._init_h5(mode='a' if self._append else 'w')
527
+ self._init_h5(mode="a" if self._append else "w")
498
528
  self._init_out_arrays()
499
529
 
500
530
  diff = list(set(self.points_control.sites)
501
- - set(self.meta['gid'].values))
531
+ - set(self.meta[ResourceMetaField.GID].values))
502
532
  if diff:
503
- raise Exception('The following analysis sites were requested '
504
- 'through project points for econ but are not '
505
- 'found in the CF file ("{}"): {}'
506
- .format(self.cf_file, diff))
533
+ raise Exception(
534
+ "The following analysis sites were requested "
535
+ "through project points for econ but are not "
536
+ 'found in the CF file ("{}"): {}'.format(self.cf_file, diff)
537
+ )
507
538
 
508
539
  # make a kwarg dict
509
- kwargs = {'output_request': self.output_request,
510
- 'cf_file': self.cf_file,
511
- 'year': self.year}
512
-
513
- logger.info('Running econ with smart data flushing '
514
- 'for: {}'.format(self.points_control))
515
- logger.debug('The following project points were specified: "{}"'
516
- .format(self.project_points))
517
- logger.debug('The following SAM configs are available to this run:\n{}'
518
- .format(pprint.pformat(self.sam_configs, indent=4)))
519
- logger.debug('The SAM output variables have been requested:\n{}'
520
- .format(self.output_request))
540
+ kwargs = {
541
+ "output_request": self.output_request,
542
+ "cf_file": self.cf_file,
543
+ "year": self.year,
544
+ }
545
+
546
+ logger.info(
547
+ "Running econ with smart data flushing " "for: {}".format(
548
+ self.points_control
549
+ )
550
+ )
551
+ logger.debug(
552
+ 'The following project points were specified: "{}"'.format(
553
+ self.project_points
554
+ )
555
+ )
556
+ logger.debug(
557
+ "The following SAM configs are available to this run:\n{}".format(
558
+ pprint.pformat(self.sam_configs, indent=4)
559
+ )
560
+ )
561
+ logger.debug(
562
+ "The SAM output variables have been requested:\n{}".format(
563
+ self.output_request
564
+ )
565
+ )
521
566
 
522
567
  try:
523
- kwargs['econ_fun'] = self._fun
568
+ kwargs["econ_fun"] = self._fun
524
569
  if max_workers == 1:
525
- logger.debug('Running serial econ for: {}'
526
- .format(self.points_control))
570
+ logger.debug(
571
+ "Running serial econ for: {}".format(self.points_control)
572
+ )
527
573
  for i, pc_sub in enumerate(self.points_control):
528
574
  self.out = self._run_single_worker(pc_sub, **kwargs)
529
- logger.info('Finished reV econ serial compute for: {} '
530
- '(iteration {} out of {})'
531
- .format(pc_sub, i + 1,
532
- len(self.points_control)))
575
+ logger.info(
576
+ "Finished reV econ serial compute for: {} "
577
+ "(iteration {} out of {})".format(
578
+ pc_sub, i + 1, len(self.points_control)
579
+ )
580
+ )
533
581
  self.flush()
534
582
  else:
535
- logger.debug('Running parallel econ for: {}'
536
- .format(self.points_control))
537
- self._parallel_run(max_workers=max_workers,
538
- pool_size=pool_size, timeout=timeout,
539
- **kwargs)
583
+ logger.debug(
584
+ "Running parallel econ for: {}".format(self.points_control)
585
+ )
586
+ self._parallel_run(
587
+ max_workers=max_workers,
588
+ pool_size=pool_size,
589
+ timeout=timeout,
590
+ **kwargs,
591
+ )
540
592
 
541
593
  except Exception as e:
542
- logger.exception('SmartParallelJob.execute() failed for econ.')
594
+ logger.exception("SmartParallelJob.execute() failed for econ.")
543
595
  raise e
544
596
 
545
597
  return self._out_fpath
@@ -3,14 +3,18 @@
3
3
  reV module for calculating economies of scale where larger power plants will
4
4
  have reduced capital cost.
5
5
  """
6
- import logging
6
+
7
7
  import copy
8
+ import logging
8
9
  import re
9
- import numpy as np # pylint: disable=unused-import
10
+
11
+ # pylint: disable=unused-import
12
+ import numpy as np
10
13
  import pandas as pd
14
+ from rex.utilities.utilities import check_eval_str
11
15
 
12
16
  from reV.econ.utilities import lcoe_fcr
13
- from rex.utilities.utilities import check_eval_str
17
+ from reV.utilities import SupplyCurveField
14
18
 
15
19
  logger = logging.getLogger(__name__)
16
20
 
@@ -57,23 +61,26 @@ class EconomiesOfScale:
57
61
  check_eval_str(str(self._eqn))
58
62
 
59
63
  if isinstance(self._data, pd.DataFrame):
60
- self._data = {k: self._data[k].values.flatten()
61
- for k in self._data.columns}
64
+ self._data = {
65
+ k: self._data[k].values.flatten() for k in self._data.columns
66
+ }
62
67
 
63
68
  if not isinstance(self._data, dict):
64
- e = ('Cannot evaluate EconomiesOfScale with data input of type: {}'
65
- .format(type(self._data)))
69
+ e = (
70
+ "Cannot evaluate EconomiesOfScale with data input of type: "
71
+ "{}".format(type(self._data))
72
+ )
73
+
66
74
  logger.error(e)
67
75
  raise TypeError(e)
68
76
 
69
- missing = []
70
- for name in self.vars:
71
- if name not in self._data:
72
- missing.append(name)
77
+ missing = [name for name in self.vars if name not in self._data]
73
78
 
74
79
  if any(missing):
75
- e = ('Cannot evaluate EconomiesOfScale, missing data for variables'
76
- ': {} for equation: {}'.format(missing, self._eqn))
80
+ e = (
81
+ "Cannot evaluate EconomiesOfScale, missing data for variables"
82
+ ": {} for equation: {}".format(missing, self._eqn)
83
+ )
77
84
  logger.error(e)
78
85
  raise KeyError(e)
79
86
 
@@ -90,7 +97,7 @@ class EconomiesOfScale:
90
97
  @staticmethod
91
98
  def is_method(s):
92
99
  """Check if a string is a numpy/pandas or python builtin method"""
93
- return bool(s.startswith(('np.', 'pd.')) or s in dir(__builtins__))
100
+ return bool(s.startswith(("np.", "pd.")) or s in dir(__builtins__))
94
101
 
95
102
  @property
96
103
  def vars(self):
@@ -106,14 +113,13 @@ class EconomiesOfScale:
106
113
  """
107
114
  var_names = []
108
115
  if self._eqn is not None:
109
- delimiters = ('*', '/', '+', '-', ' ', '(', ')', '[', ']', ',')
110
- regex_pattern = '|'.join(map(re.escape, delimiters))
116
+ delimiters = ("*", "/", "+", "-", " ", "(", ")", "[", "]", ",")
117
+ regex_pattern = "|".join(map(re.escape, delimiters))
111
118
  var_names = []
112
119
  for sub in re.split(regex_pattern, str(self._eqn)):
113
- if sub:
114
- if not self.is_num(sub) and not self.is_method(sub):
115
- var_names.append(sub)
116
- var_names = sorted(list(set(var_names)))
120
+ if sub and not self.is_num(sub) and not self.is_method(sub):
121
+ var_names.append(sub)
122
+ var_names = sorted(set(var_names))
117
123
 
118
124
  return var_names
119
125
 
@@ -162,9 +168,10 @@ class EconomiesOfScale:
162
168
  break
163
169
 
164
170
  if out is None:
165
- e = ('Could not find requested key list ({}) in the input '
166
- 'dictionary keys: {}'
167
- .format(key_list, list(input_dict.keys())))
171
+ e = (
172
+ "Could not find requested key list ({}) in the input "
173
+ "dictionary keys: {}".format(key_list, list(input_dict.keys()))
174
+ )
168
175
  logger.error(e)
169
176
  raise KeyError(e)
170
177
 
@@ -192,7 +199,10 @@ class EconomiesOfScale:
192
199
  out : float | np.ndarray
193
200
  Unscaled (raw) capital_cost found in the data input arg.
194
201
  """
195
- key_list = ['capital_cost', 'mean_capital_cost']
202
+ key_list = [
203
+ SupplyCurveField.CAPITAL_COST,
204
+ "mean_capital_cost",
205
+ ]
196
206
  return self._get_prioritized_keys(self._data, key_list)
197
207
 
198
208
  @property
@@ -219,7 +229,7 @@ class EconomiesOfScale:
219
229
  -------
220
230
  out : float | np.ndarray
221
231
  """
222
- key_list = ['system_capacity', 'mean_system_capacity']
232
+ key_list = ["system_capacity", "mean_system_capacity"]
223
233
  return self._get_prioritized_keys(self._data, key_list)
224
234
 
225
235
  @property
@@ -231,8 +241,12 @@ class EconomiesOfScale:
231
241
  out : float | np.ndarray
232
242
  Fixed charge rate from input data arg
233
243
  """
234
- key_list = ['fixed_charge_rate', 'mean_fixed_charge_rate',
235
- 'fcr', 'mean_fcr']
244
+ key_list = [
245
+ SupplyCurveField.FIXED_CHARGE_RATE,
246
+ "mean_fixed_charge_rate",
247
+ "fcr",
248
+ "mean_fcr",
249
+ ]
236
250
  return self._get_prioritized_keys(self._data, key_list)
237
251
 
238
252
  @property
@@ -244,8 +258,12 @@ class EconomiesOfScale:
244
258
  out : float | np.ndarray
245
259
  Fixed operating cost from input data arg
246
260
  """
247
- key_list = ['fixed_operating_cost', 'mean_fixed_operating_cost',
248
- 'foc', 'mean_foc']
261
+ key_list = [
262
+ SupplyCurveField.FIXED_OPERATING_COST,
263
+ "mean_fixed_operating_cost",
264
+ "foc",
265
+ "mean_foc",
266
+ ]
249
267
  return self._get_prioritized_keys(self._data, key_list)
250
268
 
251
269
  @property
@@ -257,8 +275,12 @@ class EconomiesOfScale:
257
275
  out : float | np.ndarray
258
276
  Variable operating cost from input data arg
259
277
  """
260
- key_list = ['variable_operating_cost', 'mean_variable_operating_cost',
261
- 'voc', 'mean_voc']
278
+ key_list = [
279
+ SupplyCurveField.VARIABLE_OPERATING_COST,
280
+ "mean_variable_operating_cost",
281
+ "voc",
282
+ "mean_voc",
283
+ ]
262
284
  return self._get_prioritized_keys(self._data, key_list)
263
285
 
264
286
  @property
@@ -284,7 +306,7 @@ class EconomiesOfScale:
284
306
  -------
285
307
  lcoe : float | np.ndarray
286
308
  """
287
- key_list = ['raw_lcoe', 'mean_lcoe']
309
+ key_list = [SupplyCurveField.RAW_LCOE, SupplyCurveField.MEAN_LCOE]
288
310
  return copy.deepcopy(self._get_prioritized_keys(self._data, key_list))
289
311
 
290
312
  @property
@@ -300,5 +322,6 @@ class EconomiesOfScale:
300
322
  LCOE calculated with the scaled capital cost based on the
301
323
  EconomiesOfScale input equation.
302
324
  """
303
- return lcoe_fcr(self.fcr, self.scaled_capital_cost, self.foc,
304
- self.aep, self.voc)
325
+ return lcoe_fcr(
326
+ self.fcr, self.scaled_capital_cost, self.foc, self.aep, self.voc
327
+ )