Exemplo n.º 1
0
def test_check_resources_and_format_argument_type():
    arg = (
        1,
        {"coal": [1, 2, 3], "htdro": [4, 5, 6]},
        [1, 2, 3, 4],
        (1, 2, 3, 4),
        {1, 2, 3, 4},
        ("a", "b", "c", 4),
    )
    for a in arg:
        with pytest.raises(TypeError):
            _check_resources_and_format(a)
Exemplo n.º 2
0
def plot_curtailment_time_series(
    scenario,
    area,
    resources,
    area_type=None,
    time_range=None,
    time_zone="utc",
    time_freq="H",
    show_demand=True,
    percentage=True,
    t2c=None,
    t2l=None,
    title=None,
    label_fontsize=20,
    title_fontsize=22,
    tick_fontsize=15,
    legend_fontsize=18,
    save=False,
    filename=None,
    filepath=None,
):
    """Generate time series curtailment plot of each specified resource in a certain
    area of a scenario.

    :param powersimdata.scenario.scenario.Scenario scenario: scenario instance
    :param str area: one of *loadzone*, *state*, *state abbreviation*,
        *interconnect*, *'all'*
    :param str/list resources: one or a list of resources.
    :param str area_type: one of *'loadzone'*, *'state'*, *'state_abbr'*,
        *'interconnect'*
    :param tuple time_range: [start_timestamp, end_timestamp] where each time stamp
        is pandas.Timestamp/numpy.datetime64/datetime.datetime. If None, the entire
        time range is used for the given scenario.
    :param str time_zone: new time zone.
    :param str time_freq: frequency. Either *'D'* (day), *'W'* (week), *'M'* (month).
    :param bool show_demand: show demand line in the plot or not, default is True.
    :param bool percentage: plot the curtailment in terms of percentage or not,
        default is True.
    :param dict t2c: user specified color of resource type to overwrite type2color
        default dict. key: resource type, value: color code.
    :param dict t2l: user specified label of resource type to overwrite type2label
        default dict. key: resource type, value: label.
    :param str title: user specified title of the figure.
    :param float label_fontsize: user specified label fontsize, default is 20.
    :param float title_fontsize: user specified title fontsize, default is 22.
    :param float tick_fontsize: user specified ticks of axes fontsize, default is 15.
    :param float legend_fontsize: user specified legend fontsize, default is 18.
    :param bool save: save the generated figure or not, default is False.
    :param str filename: if save is True, user specified filename, use area if None.
    :param str filepath: if save is True, user specified filepath, use current
        directory if None.
    """
    _check_scenario_is_in_analyze_state(scenario)
    resources = _check_resources_and_format(
        resources, grid_model=scenario.info["grid_model"])

    mi = ModelImmutables(scenario.info["grid_model"])
    type2color = mi.plants["type2color"]
    type2label = mi.plants["type2label"]
    if t2c:
        type2color.update(t2c)
    if t2l:
        type2label.update(t2l)

    resource_pg = get_generation_time_series_by_resources(scenario,
                                                          area,
                                                          resources,
                                                          area_type=area_type)
    demand = get_demand_time_series(scenario, area, area_type=area_type)
    curtailment = get_curtailment_time_series(scenario,
                                              area,
                                              area_type=area_type)

    resource_pg = change_time_zone(resource_pg, time_zone)
    demand = change_time_zone(demand, time_zone)
    curtailment = change_time_zone(curtailment, time_zone)
    if not time_range:
        time_range = (
            pd.Timestamp(scenario.info["start_date"], tz="utc"),
            pd.Timestamp(scenario.info["end_date"], tz="utc"),
        )
    resource_pg = slice_time_series(resource_pg, time_range[0], time_range[1])
    demand = slice_time_series(demand, time_range[0], time_range[1])
    curtailment = slice_time_series(curtailment, time_range[0], time_range[1])
    if time_freq != "H":
        resource_pg = resample_time_series(resource_pg, time_freq)
        demand = resample_time_series(demand, time_freq)
        curtailment = resample_time_series(curtailment, time_freq)

    for r in resource_pg.columns:
        curtailment[r + "_curtailment" +
                    "_mean"] = curtailment[r + "_curtailment"].mean()
        curtailment[
            r +
            "_available"] = curtailment[r + "_curtailment"] + resource_pg[r]
        curtailment[r + "_curtailment" +
                    "_percentage"] = (curtailment[r + "_curtailment"] /
                                      curtailment[r + "_available"] * 100)
        curtailment[r + "_curtailment" + "_percentage" +
                    "_mean"] = curtailment[r + "_curtailment" +
                                           "_percentage"].mean()

    for r in resources:
        if r not in resource_pg.columns:
            raise ValueError(f"{r} is invalid in {area}!")
        fig = plt.figure(figsize=(20, 10))
        ax = fig.gca()

        title_text = f"{area} {r.capitalize()}" if not title else title
        plt.title(title_text, fontsize=title_fontsize)

        cr = r + "_curtailment"
        if percentage:
            key1, key2 = f"{cr}_percentage", f"{cr}_percentage_mean"
        else:
            key1, key2 = cr, f"{cr}_mean"
        curtailment[key1].plot(
            ax=ax,
            lw=4,
            alpha=0.7,
            color=type2color[cr],
            label=type2label[cr],
        )
        curtailment[key2].plot(
            ax=ax,
            ls="--",
            lw=4,
            alpha=0.7,
            color=type2color[cr],
            label=type2label[cr] + " Mean",
        )

        ax_twin = ax.twinx()
        curtailment[r + "_available"].plot(
            ax=ax_twin,
            lw=4,
            alpha=0.7,
            color=type2color[r],
            label=f"{type2label[r]} Energy Available",
        )

        if show_demand:
            demand.plot(ax=ax_twin,
                        lw=4,
                        alpha=0.7,
                        color="red",
                        label="Demand")

        # Erase year in xticklabels
        xt_with_year = list(ax_twin.__dict__["date_axis_info"][0])
        xt_with_year[-1] = b"%b"
        ax_twin.__dict__["date_axis_info"][0] = tuple(xt_with_year)
        ax_twin.set_xlabel("")
        ax_twin.tick_params(which="both", labelsize=tick_fontsize)
        ax_twin.yaxis.get_offset_text().set_fontsize(tick_fontsize)
        ax_twin.set_ylabel("MWh", fontsize=label_fontsize)
        ax_twin.legend(loc="upper right", prop={"size": legend_fontsize})

        ax.tick_params(which="both", labelsize=tick_fontsize)
        ax.yaxis.get_offset_text().set_fontsize(tick_fontsize)
        ax.grid(color="black", axis="y")
        ax.set_xlabel("")
        if percentage:
            ax.set_ylabel("Curtailment [%]", fontsize=label_fontsize)
        else:
            ax.set_ylabel("Curtailment", fontsize=label_fontsize)
        ax.legend(loc="upper left", prop={"size": legend_fontsize})

        if save:
            if not filename:
                filename = f"{area.lower()}_{r}_curtailment"
            if not filepath:
                filepath = os.path.join(os.getcwd(), filename)
            plt.savefig(f"{filepath}.pdf", bbox_inches="tight", pad_inches=0)
Exemplo n.º 3
0
def summarize_hist_gen(
    hist_gen_raw: pd.DataFrame, all_resources: list, grid_model="usa_tamu"
) -> pd.DataFrame:
    """Get the total historical generation for each generator type and state
    combination, adding totals for interconnects and for all states.

    :param pandas.DataFrame hist_gen_raw: historical generation data frame. Columns
        are resources and indices are either state or load zone.
    :param list all_resources: list of resources.
    :param str grid_model: grid_model
    :return: (*pandas.DataFrame*) -- historical generation per resource.
    """
    _check_data_frame(hist_gen_raw, "PG")
    filtered_colnames = _check_resources_and_format(
        all_resources, grid_model=grid_model
    )
    mi = ModelImmutables(grid_model)

    result = hist_gen_raw.copy()

    # Interconnection
    eastern_areas = (
        set([mi.zones["abv2state"][s] for s in mi.zones["interconnect2abv"]["Eastern"]])
        | mi.zones["interconnect2loadzone"]["Eastern"]
    )
    eastern = result.loc[result.index.isin(eastern_areas)].sum()

    ercot_areas = mi.zones["interconnect2loadzone"]["Texas"]
    ercot = result.loc[result.index.isin(ercot_areas)].sum()

    western_areas = (
        set([mi.zones["abv2state"][s] for s in mi.zones["interconnect2abv"]["Western"]])
        | mi.zones["interconnect2loadzone"]["Western"]
    )
    western = result.loc[result.index.isin(western_areas)].sum()

    # State
    def _groupby_state(index: str) -> str:
        """Use state as a dict key if index is a smaller region (e.g. Texas East),
        otherwise use the given index.

        :param str index: either a state name or region within a state.
        :return: (*str*) -- the corresponding state name.
        """
        return (
            mi.zones["loadzone2state"][index]
            if index in mi.zones["loadzone2state"]
            else index
        )

    result = result.groupby(by=_groupby_state).aggregate(np.sum)

    # Summary
    all = result.sum()

    result.loc["Eastern interconnection"] = eastern
    result.loc["Western interconnection"] = western
    result.loc["Texas interconnection"] = ercot
    result.loc["All"] = all

    result = result.loc[:, filtered_colnames]
    result.rename(columns=mi.plants["type2label"], inplace=True)

    return result
Exemplo n.º 4
0
def test_check_resources_and_format():
    _check_resources_and_format(["dfo", "wind", "solar", "ng"])
    _check_resources_and_format("wind_offshore")
    _check_resources_and_format({"nuclear"})
Exemplo n.º 5
0
def test_check_resources_and_format_argument_value():
    arg = ((), {"solar", "nuclear", "ng", "battery"}, {"geo-thermal"})
    for a in arg:
        with pytest.raises(ValueError):
            _check_resources_and_format(a)
Exemplo n.º 6
0
def test_check_resources_and_format():
    _check_resources_and_format(["dfo", "wind", "solar", "ng"])
    _check_resources_and_format("wind_offshore", mi=ModelImmutables("europe_tub"))
    _check_resources_and_format({"nuclear"})
    _check_resources_and_format("geothermal", mi=ModelImmutables("europe_tub"))