Source code for postreise.analyze.generation.costs

import numpy as np
import pandas as pd
from numpy.polynomial.polynomial import polyval
from powersimdata.input.check import _check_gencost, _check_time_series
from powersimdata.scenario.check import _check_scenario_is_in_analyze_state


[docs]def calculate_costs( scenario=None, pg=None, gencost=None, decommit=False, decommit_threshold=1 ): """Calculate individual generator costs at given powers. If decommit is True, costs will be zero below the decommit threshold (1 MW). Either ``scenario`` XOR (``pg`` AND ``gencost``) must be specified. :param powersimdata.scenario.scenario.Scenario scenario: scenario to analyze. :param pandas.DataFrame pg: Generation solution data frame. :param pandas.DataFrame gencost: cost curve polynomials. :param bool decommit: Whether to decommit generator at low power. :param int/float decommit_threshold: The power (MW) below which generators are assumed to be 'decommitted', and costs are zero (if ``decommit`` is True). :raises ValueError: if not (``scenario`` XOR (``pg`` AND ``gencost``)) is specified, or if ``pg`` is passed and has negative values. :return: (*pandas.DataFrame*) -- data frame of costs. Index is hours, columns are plant IDs, values are $/hour. """ # Check that we've appropriately specified `scenario` XOR (`pg` AND `gencost`) if not ((scenario is not None) ^ (pg is not None and gencost is not None)): raise ValueError("Either scenario XOR (pg AND gencost) must be specified") if scenario is not None: _check_scenario_is_in_analyze_state(scenario) pg = scenario.get_pg() gencost = scenario.get_grid().gencost["before"] else: _check_gencost(gencost) _check_time_series(pg, "PG") if (pg < -1e-3).any(axis=None): raise ValueError("PG must be non-negative") # get ordered polynomial coefficients in columns, discarding non-coefficient data num_coefficients = gencost["n"].iloc[0] coefficient_columns = [f"c{i}" for i in range(num_coefficients)] coefficients = gencost[coefficient_columns].to_numpy().T # elementwise, evaluate polynomial where x = value costs = polyval(pg.to_numpy(), coefficients, tensor=False) if decommit: # mask values where pg is 0 to 0 cost (assume uncommitted, no cost) costs = np.where(pg.to_numpy() < decommit_threshold, 0, costs) # Finally, convert to dataframe with shape that matches `pg` costs = pd.DataFrame(costs, columns=pg.columns, index=pg.index) return costs