NREL-reV 0.13.1__py3-none-any.whl → 0.14.1__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.
@@ -11,7 +11,7 @@ import numpy as np
11
11
  import pandas as pd
12
12
  from rex.multi_time_resource import MultiTimeResource
13
13
  from rex.resource import BaseResource, Resource
14
- from rex.utilities.utilities import jsonify_dict
14
+ from rex.utilities.utilities import jsonify_dict, check_res_file
15
15
 
16
16
  from reV.econ.economies_of_scale import EconomiesOfScale
17
17
  from reV.econ.utilities import lcoe_fcr
@@ -1169,9 +1169,11 @@ class AggregationSupplyCurvePoint(SupplyCurvePoint):
1169
1169
  Resource h5 handler object.
1170
1170
  """
1171
1171
  if self._h5 is None and "*" in self._h5_fpath:
1172
- self._h5 = MultiTimeResource(self._h5_fpath)
1172
+ __, hsds = check_res_file(self._h5_fpath)
1173
+ self._h5 = MultiTimeResource(self._h5_fpath, hsds=hsds)
1173
1174
  elif self._h5 is None:
1174
- self._h5 = Resource(self._h5_fpath)
1175
+ __, hsds = check_res_file(self._h5_fpath)
1176
+ self._h5 = Resource(self._h5_fpath, hsds=hsds)
1175
1177
 
1176
1178
  return self._h5
1177
1179
 
@@ -1643,7 +1645,8 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
1643
1645
  reV generation Resource object
1644
1646
  """
1645
1647
  if self._gen is None:
1646
- self._gen = Resource(self._gen_fpath, str_decode=False)
1648
+ __, hsds = check_res_file(self._gen_fpath)
1649
+ self._gen = Resource(self._gen_fpath, str_decode=False, hsds=hsds)
1647
1650
 
1648
1651
  return self._gen
1649
1652
 
@@ -2249,6 +2252,13 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2249
2252
  else self.capacity_ac)
2250
2253
  return sc_point_cost / ac_cap
2251
2254
 
2255
+ def _compute_voc_per_ac_mwh(self, dset):
2256
+ """Compute variable operating cost per MWh """
2257
+ if dset not in self.gen.datasets:
2258
+ return None
2259
+
2260
+ return self.exclusion_weighted_mean(self.gen[dset]) * 1000 # to $/MWh
2261
+
2252
2262
  @property
2253
2263
  def mean_h5_dsets_data(self):
2254
2264
  """Get the mean supplemental h5 datasets data (optional)
@@ -2368,10 +2378,10 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2368
2378
  SupplyCurveField.SC_POINT_ANNUAL_ENERGY_MWH: (
2369
2379
  self.sc_point_annual_energy
2370
2380
  ),
2371
- SupplyCurveField.COST_SITE_OCC_USD_PER_AC_MW: (
2381
+ SupplyCurveField.COST_SITE_CC_USD_PER_AC_MW: (
2372
2382
  self._compute_cost_per_ac_mw("capital_cost")
2373
2383
  ),
2374
- SupplyCurveField.COST_BASE_OCC_USD_PER_AC_MW: (
2384
+ SupplyCurveField.COST_BASE_CC_USD_PER_AC_MW: (
2375
2385
  self._compute_cost_per_ac_mw("base_capital_cost")
2376
2386
  ),
2377
2387
  SupplyCurveField.COST_SITE_FOC_USD_PER_AC_MW: (
@@ -2380,11 +2390,11 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2380
2390
  SupplyCurveField.COST_BASE_FOC_USD_PER_AC_MW: (
2381
2391
  self._compute_cost_per_ac_mw("base_fixed_operating_cost")
2382
2392
  ),
2383
- SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MW: (
2384
- self._compute_cost_per_ac_mw("variable_operating_cost")
2393
+ SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MWH: (
2394
+ self._compute_voc_per_ac_mwh("variable_operating_cost")
2385
2395
  ),
2386
- SupplyCurveField.COST_BASE_VOC_USD_PER_AC_MW: (
2387
- self._compute_cost_per_ac_mw("base_variable_operating_cost")
2396
+ SupplyCurveField.COST_BASE_VOC_USD_PER_AC_MWH: (
2397
+ self._compute_voc_per_ac_mwh("base_variable_operating_cost")
2388
2398
  ),
2389
2399
  SupplyCurveField.FIXED_CHARGE_RATE: self.fixed_charge_rate,
2390
2400
  }
@@ -2414,19 +2424,46 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2414
2424
  return summary
2415
2425
 
2416
2426
  @staticmethod
2417
- def economies_of_scale(cap_cost_scale, summary):
2427
+ def economies_of_scale(summary, cap_cost_scale=None, fixed_cost_scale=None,
2428
+ var_cost_scale=None):
2418
2429
  """Apply economies of scale to this point summary
2419
2430
 
2420
2431
  Parameters
2421
2432
  ----------
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
2433
  summary : dict
2429
2434
  Dictionary of summary outputs for this sc point.
2435
+ cap_cost_scale : str, optional
2436
+ Optional capital cost scaling equation to implement
2437
+ "economies of scale". Equations must be in python string
2438
+ format and must return a scalar value to multiply the
2439
+ capital cost by. Independent variables in the equation
2440
+ should match the names of the columns in the ``reV`` supply
2441
+ curve aggregation output table (see the documentation of
2442
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2443
+ for details on available outputs). If ``None``, no economies
2444
+ of scale are applied to the capital cost.
2445
+ fixed_cost_scale : str, optional
2446
+ Optional fixed operating cost scaling equation to implement
2447
+ "economies of scale". Equations must be in python string
2448
+ format and must return a scalar value to multiply the
2449
+ fixed operating cost by. Independent variables in the
2450
+ equation should match the names of the columns in the
2451
+ ``reV`` supply curve aggregation output table (see the
2452
+ documentation of
2453
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2454
+ for details on available outputs). If ``None``, no economies
2455
+ of scale are applied to the fixed operating cost.
2456
+ var_cost_scale : str, optional
2457
+ Optional variable operating cost scaling equation to
2458
+ implement "economies of scale". Equations must be in python
2459
+ string format and must return a scalar value to multiply the
2460
+ variable operating cost by. Independent variables in the
2461
+ equation should match the names of the columns in the
2462
+ ``reV`` supply curve aggregation output table (see the
2463
+ documentation of
2464
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2465
+ for details on available outputs). If ``None``, no economies
2466
+ of scale are applied to the variable operating cost.
2430
2467
 
2431
2468
  Returns
2432
2469
  -------
@@ -2434,15 +2471,35 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2434
2471
  Dictionary of summary outputs for this sc point.
2435
2472
  """
2436
2473
 
2437
- eos = EconomiesOfScale(cap_cost_scale, summary)
2474
+ eos = EconomiesOfScale(data=summary, cap_eqn=cap_cost_scale,
2475
+ fixed_eqn=fixed_cost_scale,
2476
+ var_eqn=var_cost_scale)
2438
2477
  summary[SupplyCurveField.RAW_LCOE] = eos.raw_lcoe
2439
2478
  summary[SupplyCurveField.MEAN_LCOE] = eos.scaled_lcoe
2440
2479
  summary[SupplyCurveField.EOS_MULT] = eos.capital_cost_scalar
2441
- cost = summary[SupplyCurveField.COST_SITE_OCC_USD_PER_AC_MW]
2480
+ summary[SupplyCurveField.FIXED_EOS_MULT] = (
2481
+ eos.fixed_operating_cost_scalar)
2482
+ summary[SupplyCurveField.VAR_EOS_MULT] = (
2483
+ eos.variable_operating_cost_scalar)
2484
+
2485
+ cost = summary[SupplyCurveField.COST_SITE_CC_USD_PER_AC_MW]
2442
2486
  if cost is not None:
2443
- summary[SupplyCurveField.COST_SITE_OCC_USD_PER_AC_MW] = (
2487
+ summary[SupplyCurveField.COST_SITE_CC_USD_PER_AC_MW] = (
2444
2488
  cost * summary[SupplyCurveField.EOS_MULT]
2445
2489
  )
2490
+
2491
+ cost = summary[SupplyCurveField.COST_SITE_FOC_USD_PER_AC_MW]
2492
+ if cost is not None:
2493
+ summary[SupplyCurveField.COST_SITE_FOC_USD_PER_AC_MW] = (
2494
+ cost * summary[SupplyCurveField.FIXED_EOS_MULT]
2495
+ )
2496
+
2497
+ cost = summary[SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MWH]
2498
+ if cost is not None:
2499
+ summary[SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MWH] = (
2500
+ cost * summary[SupplyCurveField.VAR_EOS_MULT]
2501
+ )
2502
+
2446
2503
  return summary
2447
2504
 
2448
2505
  @classmethod
@@ -2469,6 +2526,8 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2469
2526
  args=None,
2470
2527
  data_layers=None,
2471
2528
  cap_cost_scale=None,
2529
+ fixed_cost_scale=None,
2530
+ var_cost_scale=None,
2472
2531
  recalc_lcoe=True,
2473
2532
  zone_mask=None,
2474
2533
  ):
@@ -2540,12 +2599,41 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2540
2599
  Aggregation data layers. Must be a dictionary keyed by data label
2541
2600
  name. Each value must be another dictionary with "dset", "method",
2542
2601
  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.
2602
+ cap_cost_scale : str, optional
2603
+ Optional capital cost scaling equation to implement
2604
+ "economies of scale". Equations must be in python string
2605
+ format and must return a scalar value to multiply the
2606
+ capital cost by. Independent variables in the equation
2607
+ should match the names of the columns in the ``reV`` supply
2608
+ curve aggregation output table (see the documentation of
2609
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2610
+ for details on available outputs). If ``None``, no economies
2611
+ of scale are applied to the capital cost.
2612
+ By default, ``None``.
2613
+ fixed_cost_scale : str, optional
2614
+ Optional fixed operating cost scaling equation to implement
2615
+ "economies of scale". Equations must be in python string
2616
+ format and must return a scalar value to multiply the
2617
+ fixed operating cost by. Independent variables in the
2618
+ equation should match the names of the columns in the
2619
+ ``reV`` supply curve aggregation output table (see the
2620
+ documentation of
2621
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2622
+ for details on available outputs). If ``None``, no economies
2623
+ of scale are applied to the fixed operating cost.
2624
+ By default, ``None``.
2625
+ var_cost_scale : str, optional
2626
+ Optional variable operating cost scaling equation to
2627
+ implement "economies of scale". Equations must be in python
2628
+ string format and must return a scalar value to multiply the
2629
+ variable operating cost by. Independent variables in the
2630
+ equation should match the names of the columns in the
2631
+ ``reV`` supply curve aggregation output table (see the
2632
+ documentation of
2633
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
2634
+ for details on available outputs). If ``None``, no economies
2635
+ of scale are applied to the variable operating cost.
2636
+ By default, ``None``.
2549
2637
  recalc_lcoe : bool
2550
2638
  Flag to re-calculate the LCOE from the multi-year mean capacity
2551
2639
  factor and annual energy production data. This requires several
@@ -2589,8 +2677,10 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2589
2677
  if data_layers is not None:
2590
2678
  summary = point.agg_data_layers(summary, data_layers)
2591
2679
 
2592
- if cap_cost_scale is not None:
2593
- summary = point.economies_of_scale(cap_cost_scale, summary)
2680
+ if any((cap_cost_scale, fixed_cost_scale, var_cost_scale)):
2681
+ summary = point.economies_of_scale(summary, cap_cost_scale,
2682
+ fixed_cost_scale,
2683
+ var_cost_scale)
2594
2684
 
2595
2685
  for arg, val in summary.items():
2596
2686
  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
@@ -543,15 +569,20 @@ class SupplyCurveAggregation(BaseAggregation):
543
569
  generation HDF5 output, or if `recalc_lcoe` is set to
544
570
  ``False``, the mean LCOE will be computed from the data
545
571
  stored under the `lcoe_dset` instead. By default, ``True``.
546
- zones_dset: str, optional
547
- Dataset name in `excl_fpath` containing the zones to be applied.
548
- If specified, supply curve aggregation will be performed separately
549
- for each discrete zone within each supply curve site. This option
550
- can be used for uses cases such as subdividing sites by parcel,
551
- such that each parcel within each site is output to a separate
552
- sc_gid. The input data layer should consist of unique integer
553
- values for each zone. Values of zero will be treated as excluded
554
- areas.
572
+ zones_dset : str, optional
573
+ Dataset name in `excl_fpath` containing the zones to be
574
+ applied. If specified, supply curve aggregation will be
575
+ performed separately for each discrete zone within each
576
+ supply curve site. This option can be used for uses cases
577
+ such as subdividing sites by parcel, such that each parcel
578
+ within each site is output to a separate ``sc_gid``. The
579
+ input data layer should consist of unique integer values for
580
+ each zone. Values of zero will be treated as excluded areas.
581
+ This functionality works best of you have on the order of
582
+ ~100,000 zones or less. If you have significantly more zones
583
+ than that, the supply curve aggregation computation may take
584
+ too long to run; consider performing an alternative
585
+ analysis. By default, ``None``.
555
586
 
556
587
  Examples
557
588
  --------
@@ -711,6 +742,8 @@ class SupplyCurveAggregation(BaseAggregation):
711
742
  self._lcoe_dset = lcoe_dset
712
743
  self._h5_dsets = h5_dsets
713
744
  self._cap_cost_scale = cap_cost_scale
745
+ self._fixed_cost_scale = fixed_cost_scale
746
+ self._var_cost_scale = var_cost_scale
714
747
  self._power_density = power_density
715
748
  self._friction_fpath = friction_fpath
716
749
  self._friction_dset = friction_dset
@@ -958,6 +991,8 @@ class SupplyCurveAggregation(BaseAggregation):
958
991
  friction_dset=None,
959
992
  excl_area=None,
960
993
  cap_cost_scale=None,
994
+ fixed_cost_scale=None,
995
+ var_cost_scale=None,
961
996
  recalc_lcoe=True,
962
997
  zones_dset=None,
963
998
  ):
@@ -1041,12 +1076,41 @@ class SupplyCurveAggregation(BaseAggregation):
1041
1076
  excl_area : float | None, optional
1042
1077
  Area of an exclusion pixel in km2. None will try to infer the area
1043
1078
  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.
1079
+ cap_cost_scale : str, optional
1080
+ Optional capital cost scaling equation to implement
1081
+ "economies of scale". Equations must be in python string
1082
+ format and must return a scalar value to multiply the
1083
+ capital cost by. Independent variables in the equation
1084
+ should match the names of the columns in the ``reV`` supply
1085
+ curve aggregation output table (see the documentation of
1086
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
1087
+ for details on available outputs). If ``None``, no economies
1088
+ of scale are applied to the capital cost.
1089
+ By default, ``None``.
1090
+ fixed_cost_scale : str, optional
1091
+ Optional fixed operating cost scaling equation to implement
1092
+ "economies of scale". Equations must be in python string
1093
+ format and must return a scalar value to multiply the
1094
+ fixed operating cost by. Independent variables in the
1095
+ equation should match the names of the columns in the
1096
+ ``reV`` supply curve aggregation output table (see the
1097
+ documentation of
1098
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
1099
+ for details on available outputs). If ``None``, no economies
1100
+ of scale are applied to the fixed operating cost.
1101
+ By default, ``None``.
1102
+ var_cost_scale : str, optional
1103
+ Optional variable operating cost scaling equation to
1104
+ implement "economies of scale". Equations must be in python
1105
+ string format and must return a scalar value to multiply the
1106
+ variable operating cost by. Independent variables in the
1107
+ equation should match the names of the columns in the
1108
+ ``reV`` supply curve aggregation output table (see the
1109
+ documentation of
1110
+ :class:`~reV.supply_curve.sc_aggregation.SupplyCurveAggregation`
1111
+ for details on available outputs). If ``None``, no economies
1112
+ of scale are applied to the variable operating cost.
1113
+ By default, ``None``.
1050
1114
  recalc_lcoe : bool
1051
1115
  Flag to re-calculate the LCOE from the multi-year mean capacity
1052
1116
  factor and annual energy production data. This requires several
@@ -1143,6 +1207,8 @@ class SupplyCurveAggregation(BaseAggregation):
1143
1207
  close=False,
1144
1208
  friction_layer=fh.friction_layer,
1145
1209
  cap_cost_scale=cap_cost_scale,
1210
+ fixed_cost_scale=fixed_cost_scale,
1211
+ var_cost_scale=var_cost_scale,
1146
1212
  recalc_lcoe=recalc_lcoe,
1147
1213
  zone_mask=zone_mask,
1148
1214
  )
@@ -1262,6 +1328,8 @@ class SupplyCurveAggregation(BaseAggregation):
1262
1328
  args=args,
1263
1329
  excl_area=self._excl_area,
1264
1330
  cap_cost_scale=self._cap_cost_scale,
1331
+ fixed_cost_scale=self._fixed_cost_scale,
1332
+ var_cost_scale=self._var_cost_scale,
1265
1333
  recalc_lcoe=self._recalc_lcoe,
1266
1334
  zones_dset=self._zones_dset,
1267
1335
  )
@@ -1401,6 +1469,8 @@ class SupplyCurveAggregation(BaseAggregation):
1401
1469
  args=args,
1402
1470
  excl_area=self._excl_area,
1403
1471
  cap_cost_scale=self._cap_cost_scale,
1472
+ fixed_cost_scale=self._fixed_cost_scale,
1473
+ var_cost_scale=self._var_cost_scale,
1404
1474
  recalc_lcoe=self._recalc_lcoe,
1405
1475
  zones_dset=self._zones_dset,
1406
1476
  )