NREL-reV 0.13.0__py3-none-any.whl → 0.14.0__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.
@@ -0,0 +1,66 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ reV Tech Mapping CLI utility functions.
4
+ """
5
+ import logging
6
+
7
+ from gaps.cli import as_click_command, CLICommandFromClass
8
+
9
+ from reV.supply_curve.tech_mapping import TechMapping
10
+ from reV.utilities import ModuleName
11
+ from reV.utilities.exceptions import ConfigError
12
+ from reV.supply_curve.cli_sc_aggregation import _format_res_fpath
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ def _preprocessor(config):
18
+ """Preprocess tech mapping config user input.
19
+
20
+ Parameters
21
+ ----------
22
+ config : dict
23
+ User configuration file input as (nested) dict.
24
+
25
+ Returns
26
+ -------
27
+ dict
28
+ Updated config file.
29
+ """
30
+ _validate_excl_fpath(config)
31
+ config = _format_res_fpath(config)
32
+ _validate_dset(config)
33
+
34
+ return config
35
+
36
+
37
+ def _validate_excl_fpath(config):
38
+ paths = config["excl_fpath"]
39
+ if isinstance(paths, list):
40
+ raise ConfigError(
41
+ "Multiple exclusion file paths passed via excl_fpath. "
42
+ "Cannot run tech mapping with arbitrary multiple exclusion. "
43
+ "Specify a single exclusion file path to write to."
44
+ )
45
+
46
+
47
+ def _validate_dset(config):
48
+ if config.get("dset") is None:
49
+ raise ConfigError(
50
+ "dset must be specified to run tech mapping."
51
+ )
52
+
53
+
54
+ tm_command = CLICommandFromClass(TechMapping, method="run",
55
+ name=str(ModuleName.TECH_MAPPING),
56
+ add_collect=False, split_keys=None,
57
+ config_preprocessor=_preprocessor)
58
+ main = as_click_command(tm_command)
59
+
60
+
61
+ if __name__ == '__main__':
62
+ try:
63
+ main(obj={})
64
+ except Exception:
65
+ logger.exception('Error running reV Tech Mapping CLI.')
66
+ raise
@@ -2249,6 +2249,13 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2249
2249
  else self.capacity_ac)
2250
2250
  return sc_point_cost / ac_cap
2251
2251
 
2252
+ def _compute_voc_per_ac_mwh(self, dset):
2253
+ """Compute variable operating cost per MWh """
2254
+ if dset not in self.gen.datasets:
2255
+ return None
2256
+
2257
+ return self.exclusion_weighted_mean(self.gen[dset]) * 1000 # to $/MWh
2258
+
2252
2259
  @property
2253
2260
  def mean_h5_dsets_data(self):
2254
2261
  """Get the mean supplemental h5 datasets data (optional)
@@ -2368,10 +2375,10 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2368
2375
  SupplyCurveField.SC_POINT_ANNUAL_ENERGY_MWH: (
2369
2376
  self.sc_point_annual_energy
2370
2377
  ),
2371
- SupplyCurveField.COST_SITE_OCC_USD_PER_AC_MW: (
2378
+ SupplyCurveField.COST_SITE_CC_USD_PER_AC_MW: (
2372
2379
  self._compute_cost_per_ac_mw("capital_cost")
2373
2380
  ),
2374
- SupplyCurveField.COST_BASE_OCC_USD_PER_AC_MW: (
2381
+ SupplyCurveField.COST_BASE_CC_USD_PER_AC_MW: (
2375
2382
  self._compute_cost_per_ac_mw("base_capital_cost")
2376
2383
  ),
2377
2384
  SupplyCurveField.COST_SITE_FOC_USD_PER_AC_MW: (
@@ -2380,11 +2387,11 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2380
2387
  SupplyCurveField.COST_BASE_FOC_USD_PER_AC_MW: (
2381
2388
  self._compute_cost_per_ac_mw("base_fixed_operating_cost")
2382
2389
  ),
2383
- SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MW: (
2384
- self._compute_cost_per_ac_mw("variable_operating_cost")
2390
+ SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MWH: (
2391
+ self._compute_voc_per_ac_mwh("variable_operating_cost")
2385
2392
  ),
2386
- SupplyCurveField.COST_BASE_VOC_USD_PER_AC_MW: (
2387
- self._compute_cost_per_ac_mw("base_variable_operating_cost")
2393
+ SupplyCurveField.COST_BASE_VOC_USD_PER_AC_MWH: (
2394
+ self._compute_voc_per_ac_mwh("base_variable_operating_cost")
2388
2395
  ),
2389
2396
  SupplyCurveField.FIXED_CHARGE_RATE: self.fixed_charge_rate,
2390
2397
  }
@@ -2414,19 +2421,46 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2414
2421
  return summary
2415
2422
 
2416
2423
  @staticmethod
2417
- def economies_of_scale(cap_cost_scale, summary):
2424
+ def economies_of_scale(summary, cap_cost_scale=None, fixed_cost_scale=None,
2425
+ var_cost_scale=None):
2418
2426
  """Apply economies of scale to this point summary
2419
2427
 
2420
2428
  Parameters
2421
2429
  ----------
2422
- cap_cost_scale : str
2423
- LCOE scaling equation to implement "economies of scale".
2424
- Equation must be in python string format and return a scalar
2425
- value to multiply the capital cost by. Independent variables in
2426
- the equation should match the names of the columns in the reV
2427
- supply curve aggregation table.
2428
2430
  summary : dict
2429
2431
  Dictionary of summary outputs for this sc point.
2432
+ cap_cost_scale : str, optional
2433
+ Optional capital cost scaling equation to implement
2434
+ "economies of scale". Equations must be in python string
2435
+ format and must return a scalar value to multiply the
2436
+ capital cost by. Independent variables in the equation
2437
+ should match the names of the columns in the ``reV`` supply
2438
+ curve aggregation output table (see the documentation of
2439
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2440
+ for details on available outputs). If ``None``, no economies
2441
+ of scale are applied to the capital cost.
2442
+ fixed_cost_scale : str, optional
2443
+ Optional fixed operating cost scaling equation to implement
2444
+ "economies of scale". Equations must be in python string
2445
+ format and must return a scalar value to multiply the
2446
+ fixed operating cost by. Independent variables in the
2447
+ equation should match the names of the columns in the
2448
+ ``reV`` supply curve aggregation output table (see the
2449
+ documentation of
2450
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2451
+ for details on available outputs). If ``None``, no economies
2452
+ of scale are applied to the fixed operating cost.
2453
+ var_cost_scale : str, optional
2454
+ Optional variable operating cost scaling equation to
2455
+ implement "economies of scale". Equations must be in python
2456
+ string format and must return a scalar value to multiply the
2457
+ variable operating cost by. Independent variables in the
2458
+ equation should match the names of the columns in the
2459
+ ``reV`` supply curve aggregation output table (see the
2460
+ documentation of
2461
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2462
+ for details on available outputs). If ``None``, no economies
2463
+ of scale are applied to the variable operating cost.
2430
2464
 
2431
2465
  Returns
2432
2466
  -------
@@ -2434,15 +2468,35 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2434
2468
  Dictionary of summary outputs for this sc point.
2435
2469
  """
2436
2470
 
2437
- eos = EconomiesOfScale(cap_cost_scale, summary)
2471
+ eos = EconomiesOfScale(data=summary, cap_eqn=cap_cost_scale,
2472
+ fixed_eqn=fixed_cost_scale,
2473
+ var_eqn=var_cost_scale)
2438
2474
  summary[SupplyCurveField.RAW_LCOE] = eos.raw_lcoe
2439
2475
  summary[SupplyCurveField.MEAN_LCOE] = eos.scaled_lcoe
2440
2476
  summary[SupplyCurveField.EOS_MULT] = eos.capital_cost_scalar
2441
- cost = summary[SupplyCurveField.COST_SITE_OCC_USD_PER_AC_MW]
2477
+ summary[SupplyCurveField.FIXED_EOS_MULT] = (
2478
+ eos.fixed_operating_cost_scalar)
2479
+ summary[SupplyCurveField.VAR_EOS_MULT] = (
2480
+ eos.variable_operating_cost_scalar)
2481
+
2482
+ cost = summary[SupplyCurveField.COST_SITE_CC_USD_PER_AC_MW]
2442
2483
  if cost is not None:
2443
- summary[SupplyCurveField.COST_SITE_OCC_USD_PER_AC_MW] = (
2484
+ summary[SupplyCurveField.COST_SITE_CC_USD_PER_AC_MW] = (
2444
2485
  cost * summary[SupplyCurveField.EOS_MULT]
2445
2486
  )
2487
+
2488
+ cost = summary[SupplyCurveField.COST_SITE_FOC_USD_PER_AC_MW]
2489
+ if cost is not None:
2490
+ summary[SupplyCurveField.COST_SITE_FOC_USD_PER_AC_MW] = (
2491
+ cost * summary[SupplyCurveField.FIXED_EOS_MULT]
2492
+ )
2493
+
2494
+ cost = summary[SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MWH]
2495
+ if cost is not None:
2496
+ summary[SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MWH] = (
2497
+ cost * summary[SupplyCurveField.VAR_EOS_MULT]
2498
+ )
2499
+
2446
2500
  return summary
2447
2501
 
2448
2502
  @classmethod
@@ -2469,6 +2523,8 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2469
2523
  args=None,
2470
2524
  data_layers=None,
2471
2525
  cap_cost_scale=None,
2526
+ fixed_cost_scale=None,
2527
+ var_cost_scale=None,
2472
2528
  recalc_lcoe=True,
2473
2529
  zone_mask=None,
2474
2530
  ):
@@ -2540,12 +2596,41 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2540
2596
  Aggregation data layers. Must be a dictionary keyed by data label
2541
2597
  name. Each value must be another dictionary with "dset", "method",
2542
2598
  and "fpath", by default None
2543
- cap_cost_scale : str | None
2544
- Optional LCOE scaling equation to implement "economies of scale".
2545
- Equations must be in python string format and return a scalar
2546
- value to multiply the capital cost by. Independent variables in
2547
- the equation should match the names of the columns in the reV
2548
- supply curve aggregation table.
2599
+ cap_cost_scale : str, optional
2600
+ Optional capital cost scaling equation to implement
2601
+ "economies of scale". Equations must be in python string
2602
+ format and must return a scalar value to multiply the
2603
+ capital cost by. Independent variables in the equation
2604
+ should match the names of the columns in the ``reV`` supply
2605
+ curve aggregation output table (see the documentation of
2606
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2607
+ for details on available outputs). If ``None``, no economies
2608
+ of scale are applied to the capital cost.
2609
+ By default, ``None``.
2610
+ fixed_cost_scale : str, optional
2611
+ Optional fixed operating cost scaling equation to implement
2612
+ "economies of scale". Equations must be in python string
2613
+ format and must return a scalar value to multiply the
2614
+ fixed operating cost by. Independent variables in the
2615
+ equation should match the names of the columns in the
2616
+ ``reV`` supply curve aggregation output table (see the
2617
+ documentation of
2618
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2619
+ for details on available outputs). If ``None``, no economies
2620
+ of scale are applied to the fixed operating cost.
2621
+ By default, ``None``.
2622
+ var_cost_scale : str, optional
2623
+ Optional variable operating cost scaling equation to
2624
+ implement "economies of scale". Equations must be in python
2625
+ string format and must return a scalar value to multiply the
2626
+ variable operating cost by. Independent variables in the
2627
+ equation should match the names of the columns in the
2628
+ ``reV`` supply curve aggregation output table (see the
2629
+ documentation of
2630
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2631
+ for details on available outputs). If ``None``, no economies
2632
+ of scale are applied to the variable operating cost.
2633
+ By default, ``None``.
2549
2634
  recalc_lcoe : bool
2550
2635
  Flag to re-calculate the LCOE from the multi-year mean capacity
2551
2636
  factor and annual energy production data. This requires several
@@ -2589,8 +2674,10 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2589
2674
  if data_layers is not None:
2590
2675
  summary = point.agg_data_layers(summary, data_layers)
2591
2676
 
2592
- if cap_cost_scale is not None:
2593
- summary = point.economies_of_scale(cap_cost_scale, summary)
2677
+ if any((cap_cost_scale, fixed_cost_scale, var_cost_scale)):
2678
+ summary = point.economies_of_scale(summary, cap_cost_scale,
2679
+ fixed_cost_scale,
2680
+ var_cost_scale)
2594
2681
 
2595
2682
  for arg, val in summary.items():
2596
2683
  if val is None:
@@ -252,7 +252,8 @@ class SupplyCurveAggregation(BaseAggregation):
252
252
  res_class_bins=None, cf_dset='cf_mean-means',
253
253
  lcoe_dset='lcoe_fcr-means', h5_dsets=None, data_layers=None,
254
254
  power_density=None, friction_fpath=None, friction_dset=None,
255
- cap_cost_scale=None, recalc_lcoe=True, zones_dset=None):
255
+ cap_cost_scale=None, fixed_cost_scale=None,
256
+ var_cost_scale=None, recalc_lcoe=True, zones_dset=None):
256
257
  r"""ReV supply curve points aggregation framework.
257
258
 
258
259
  ``reV`` supply curve aggregation combines a high-resolution
@@ -518,15 +519,40 @@ class SupplyCurveAggregation(BaseAggregation):
518
519
  ``None``, no friction data is aggregated.
519
520
  By default, ``None``.
520
521
  cap_cost_scale : str, optional
521
- Optional LCOE scaling equation to implement "economies of
522
- scale". Equations must be in python string format and must
523
- return a scalar value to multiply the capital cost by.
524
- Independent variables in the equation should match the names
525
- of the columns in the ``reV`` supply curve aggregation
526
- output table (see the documentation of
522
+ Optional capital cost scaling equation to implement
523
+ "economies of scale". Equations must be in python string
524
+ format and must return a scalar value to multiply the
525
+ capital cost by. Independent variables in the equation
526
+ should match the names of the columns in the ``reV`` supply
527
+ curve aggregation output table (see the documentation of
527
528
  :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
528
529
  for details on available outputs). If ``None``, no economies
529
- of scale are applied. By default, ``None``.
530
+ of scale are applied to the capital cost.
531
+ By default, ``None``.
532
+ fixed_cost_scale : str, optional
533
+ Optional fixed operating cost scaling equation to implement
534
+ "economies of scale". Equations must be in python string
535
+ format and must return a scalar value to multiply the
536
+ fixed operating cost by. Independent variables in the
537
+ equation should match the names of the columns in the
538
+ ``reV`` supply curve aggregation output table (see the
539
+ documentation of
540
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
541
+ for details on available outputs). If ``None``, no economies
542
+ of scale are applied to the fixed operating cost.
543
+ By default, ``None``.
544
+ var_cost_scale : str, optional
545
+ Optional variable operating cost scaling equation to
546
+ implement "economies of scale". Equations must be in python
547
+ string format and must return a scalar value to multiply the
548
+ variable operating cost by. Independent variables in the
549
+ equation should match the names of the columns in the
550
+ ``reV`` supply curve aggregation output table (see the
551
+ documentation of
552
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
553
+ for details on available outputs). If ``None``, no economies
554
+ of scale are applied to the variable operating cost.
555
+ By default, ``None``.
530
556
  recalc_lcoe : bool, optional
531
557
  Flag to re-calculate the LCOE from the multi-year mean
532
558
  capacity factor and annual energy production data. This
@@ -711,6 +737,8 @@ class SupplyCurveAggregation(BaseAggregation):
711
737
  self._lcoe_dset = lcoe_dset
712
738
  self._h5_dsets = h5_dsets
713
739
  self._cap_cost_scale = cap_cost_scale
740
+ self._fixed_cost_scale = fixed_cost_scale
741
+ self._var_cost_scale = var_cost_scale
714
742
  self._power_density = power_density
715
743
  self._friction_fpath = friction_fpath
716
744
  self._friction_dset = friction_dset
@@ -958,6 +986,8 @@ class SupplyCurveAggregation(BaseAggregation):
958
986
  friction_dset=None,
959
987
  excl_area=None,
960
988
  cap_cost_scale=None,
989
+ fixed_cost_scale=None,
990
+ var_cost_scale=None,
961
991
  recalc_lcoe=True,
962
992
  zones_dset=None,
963
993
  ):
@@ -1041,12 +1071,41 @@ class SupplyCurveAggregation(BaseAggregation):
1041
1071
  excl_area : float | None, optional
1042
1072
  Area of an exclusion pixel in km2. None will try to infer the area
1043
1073
  from the profile transform attribute in excl_fpath, by default None
1044
- cap_cost_scale : str | None
1045
- Optional LCOE scaling equation to implement "economies of scale".
1046
- Equations must be in python string format and return a scalar
1047
- value to multiply the capital cost by. Independent variables in
1048
- the equation should match the names of the columns in the reV
1049
- supply curve aggregation table.
1074
+ cap_cost_scale : str, optional
1075
+ Optional capital cost scaling equation to implement
1076
+ "economies of scale". Equations must be in python string
1077
+ format and must return a scalar value to multiply the
1078
+ capital cost by. Independent variables in the equation
1079
+ should match the names of the columns in the ``reV`` supply
1080
+ curve aggregation output table (see the documentation of
1081
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
1082
+ for details on available outputs). If ``None``, no economies
1083
+ of scale are applied to the capital cost.
1084
+ By default, ``None``.
1085
+ fixed_cost_scale : str, optional
1086
+ Optional fixed operating cost scaling equation to implement
1087
+ "economies of scale". Equations must be in python string
1088
+ format and must return a scalar value to multiply the
1089
+ fixed operating cost by. Independent variables in the
1090
+ equation should match the names of the columns in the
1091
+ ``reV`` supply curve aggregation output table (see the
1092
+ documentation of
1093
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
1094
+ for details on available outputs). If ``None``, no economies
1095
+ of scale are applied to the fixed operating cost.
1096
+ By default, ``None``.
1097
+ var_cost_scale : str, optional
1098
+ Optional variable operating cost scaling equation to
1099
+ implement "economies of scale". Equations must be in python
1100
+ string format and must return a scalar value to multiply the
1101
+ variable operating cost by. Independent variables in the
1102
+ equation should match the names of the columns in the
1103
+ ``reV`` supply curve aggregation output table (see the
1104
+ documentation of
1105
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
1106
+ for details on available outputs). If ``None``, no economies
1107
+ of scale are applied to the variable operating cost.
1108
+ By default, ``None``.
1050
1109
  recalc_lcoe : bool
1051
1110
  Flag to re-calculate the LCOE from the multi-year mean capacity
1052
1111
  factor and annual energy production data. This requires several
@@ -1143,6 +1202,8 @@ class SupplyCurveAggregation(BaseAggregation):
1143
1202
  close=False,
1144
1203
  friction_layer=fh.friction_layer,
1145
1204
  cap_cost_scale=cap_cost_scale,
1205
+ fixed_cost_scale=fixed_cost_scale,
1206
+ var_cost_scale=var_cost_scale,
1146
1207
  recalc_lcoe=recalc_lcoe,
1147
1208
  zone_mask=zone_mask,
1148
1209
  )
@@ -1262,6 +1323,8 @@ class SupplyCurveAggregation(BaseAggregation):
1262
1323
  args=args,
1263
1324
  excl_area=self._excl_area,
1264
1325
  cap_cost_scale=self._cap_cost_scale,
1326
+ fixed_cost_scale=self._fixed_cost_scale,
1327
+ var_cost_scale=self._var_cost_scale,
1265
1328
  recalc_lcoe=self._recalc_lcoe,
1266
1329
  zones_dset=self._zones_dset,
1267
1330
  )
@@ -1401,6 +1464,8 @@ class SupplyCurveAggregation(BaseAggregation):
1401
1464
  args=args,
1402
1465
  excl_area=self._excl_area,
1403
1466
  cap_cost_scale=self._cap_cost_scale,
1467
+ fixed_cost_scale=self._fixed_cost_scale,
1468
+ var_cost_scale=self._var_cost_scale,
1404
1469
  recalc_lcoe=self._recalc_lcoe,
1405
1470
  zones_dset=self._zones_dset,
1406
1471
  )