示例#1
0
    def prepare_profile(self, kind, profile_as=None):
        """Prepares profile for simulation.

        :param kind: one of *demand*, *'hydro'*, *'solar'* or *'wind'*.
        :param int/str/None profile_as: if given, copy profile from this scenario.
        """
        if profile_as is None:
            tp = TransformProfile(self._scenario_info, self.grid, self.ct)
            profile = tp.get_profile(kind)
            print(
                f"Writing scaled {kind} profile in {server_setup.LOCAL_DIR} on local machine"
            )
            file_name = "%s_%s.csv" % (self._scenario_info["id"], kind)
            profile.to_csv(os.path.join(server_setup.LOCAL_DIR, file_name))

            self._data_access.move_to(
                file_name, self.REL_TMP_DIR, change_name_to=f"{kind}.csv"
            )
        else:
            from_dir = posixpath.join(
                self.server_config.execute_dir(),
                f"scenario_{profile_as}",
            )
            to_dir = posixpath.join(
                self.server_config.execute_dir(), self.scenario_folder
            )
            _, _, stderr = self._data_access.copy(f"{from_dir}/{kind}.csv", to_dir)
            if len(stderr.readlines()) != 0:
                raise IOError(f"Failed to copy {kind}.csv on server")
示例#2
0
def test_demand_is_scaled(base_grid, raw_demand):
    base_demand = raw_demand[base_grid.id2zone.keys()]

    n_zone = param["n_zone_to_scale"]
    ct = ChangeTable(base_grid)
    ct.scale_demand(
        zone_id={
            z: f
            for z, f in zip(
                np.random.choice([i for i in base_grid.zone2id.values()],
                                 size=n_zone,
                                 replace=False),
                2 * np.random.random(size=n_zone),
            )
        })

    tg = TransformGrid(base_grid, ct.ct)
    transformed_grid = tg.get_grid()

    empty_scenario_info = {
    }  # scenario_info not needed since profile_input is mocked
    tp = TransformProfile(empty_scenario_info, transformed_grid, ct.ct)
    transformed_profile = tp.get_profile("demand")
    assert not base_demand.equals(transformed_profile)

    scaled_zone = list(ct.ct["demand"]["zone_id"].keys())
    unscaled_zone = set(base_grid.id2zone.keys()) - set(scaled_zone)
    factor = list(ct.ct["demand"]["zone_id"].values())
    assert transformed_profile[scaled_zone].equals(
        base_demand[scaled_zone].multiply(factor, axis=1))
    if unscaled_zone:
        assert transformed_profile[list(unscaled_zone)].equals(
            base_demand[list(unscaled_zone)])
示例#3
0
    def get_demand(self, original=True):
        """Returns demand profiles.

        :param bool original: should the original demand profile or the
            potentially modified one be returned.
        :return: (*pandas.DataFrame*) -- data frame of demand (hour, zone).
        """
        profile = TransformProfile(self._scenario_info, self.get_grid(), self.get_ct())
        demand = profile.get_profile("demand")

        if original:
            return demand
        else:
            dates = pd.date_range(
                start=self._scenario_info["start_date"],
                end=self._scenario_info["end_date"],
                freq=self._scenario_info["interval"],
            )
            infeasibilities = self._parse_infeasibilities()
            if infeasibilities is None:
                print("No infeasibilities. Return original profile.")
                return demand
            else:
                for key, value in infeasibilities.items():
                    start = dates[key]
                    end = (
                        dates[key]
                        + pd.Timedelta(self._scenario_info["interval"])
                        - pd.Timedelta("1H")
                    )
                    demand[start:end] *= 1.0 - value / 100.0
                return demand
示例#4
0
    def get_wind(self):
        """Returns wind profile

        :return: (*pandas.DataFrame*) -- data frame of wind energy output.
        """
        profile = TransformProfile(self._scenario_info, self.get_grid(), self.get_ct())
        return profile.get_profile("wind")
示例#5
0
    def get_solar(self):
        """Returns solar profile

        :return: (*pandas.DataFrame*) -- data frame of solar energy output.
        """
        profile = TransformProfile(self._scenario_info, self.get_grid(), self.get_ct())
        return profile.get_profile("solar")
示例#6
0
    def get_hydro(self):
        """Returns hydro profile

        :return: (*pandas.DataFrame*) -- data frame of hydro energy output.
        """
        profile = TransformProfile(self._scenario_info, self.get_grid(), self.get_ct())
        return profile.get_profile("hydro")
示例#7
0
    def get_profile(self, kind):
        """Returns demand, hydro, solar or wind  profile.

        :param str kind: either *'demand'*, *'hydro'*, *'solar'*, *'wind'*.
        :return: (*pandas.DataFrame*) -- profile.
        """
        profile = TransformProfile(self._scenario_info, self.get_grid(),
                                   self.get_ct())
        return profile.get_profile(kind)
示例#8
0
    def get_profile(self, kind):
        """Returns demand, hydro, solar or wind  profile.

        :param str kind: either *'demand'*, *'hydro'*, *'solar'*, *'wind'*.
        :return: (*pandas.DataFrame*) -- profile.
        """
        if getattr(self, kind):
            profile = TransformProfile(
                {
                    "grid_model": self.grid_model,
                    "base_%s" % kind: getattr(self, kind),
                },
                self.get_grid(),
                self.get_ct(),
            )
            return profile.get_profile(kind)
        else:
            raise Exception("%s profile version not set" % kind)
示例#9
0
def _check_plants_are_scaled(ct, base_grid, profile_info, raw_profile, resource):
    plant_id_type = get_plant_with_resource(base_grid, resource)

    base_profile = (
        raw_profile[plant_id_type] * base_grid.plant.loc[plant_id_type, "Pmax"]
    )

    tg = TransformGrid(base_grid, ct)
    transformed_grid = tg.get_grid()

    tp = TransformProfile(profile_info, transformed_grid, ct)
    transformed_profile = tp.get_profile(resource)

    scaled_plant_id = []
    scaling_factor_plant = []
    if "zone_id" in ct[resource].keys():
        for z, f in ct[resource]["zone_id"].items():
            plant_id_zone = (
                base_grid.plant.groupby(["zone_id", "type"])
                .get_group((z, resource))
                .index.tolist()
            )
            scaled_plant_id += plant_id_zone
            scaling_factor_plant += [f] * len(plant_id_zone)
    if "plant_id" in ct[resource].keys():
        for i, f in ct[resource]["plant_id"].items():
            if i in scaled_plant_id:
                scaling_factor_plant[scaled_plant_id.index(i)] *= f
            else:
                scaled_plant_id.append(i)
                scaling_factor_plant.append(f)

    assert not base_profile.equals(transformed_profile)
    assert_almost_equal(
        transformed_profile[scaled_plant_id].values,
        base_profile[scaled_plant_id].multiply(scaling_factor_plant, axis=1).values,
    )

    unscaled_plant_id = set(plant_id_type) - set(scaled_plant_id)
    if unscaled_plant_id:
        assert transformed_profile[unscaled_plant_id].equals(
            base_profile[unscaled_plant_id]
        )
    return transformed_profile
示例#10
0
def test_flexible_demand_profiles_are_trimmed(base_grid,
                                              raw_demand_flexibility_up,
                                              raw_demand_flexibility_dn,
                                              monkeypatch):
    monkeypatch.setattr(Context, "get_data_access",
                        MockContext().get_data_access)
    data_access = Context.get_data_access()

    # Specify the fake demand flexibility profiles from MockInputData
    zone_keys = [f"zone.{z}" for z in base_grid.id2zone.keys()]
    base_demand_flexibility_up = raw_demand_flexibility_up[zone_keys]
    base_demand_flexibility_dn = raw_demand_flexibility_dn[zone_keys]

    # Create fake files in the expected directory path
    exp_path = f"raw/{base_grid.grid_model}"

    for csv_file in (
            "demand_flexibility_up_Test.csv",
            "demand_flexibility_dn_Test.csv",
    ):
        with data_access.write(exp_path + "/" + csv_file) as f:
            pd.DataFrame().to_csv(f)

    # Specify the change table
    ct = ChangeTable(base_grid)
    ct.add_demand_flexibility({
        "demand_flexibility_up": "Test",
        "demand_flexibility_dn": "Test",
        "demand_flexibility_duration": 6,
    })

    # Transform the grid object accordingly
    tg = TransformGrid(base_grid, ct.ct)
    transformed_grid = tg.get_grid()

    # Test that the demand flexibility profiles are pruned
    empty_scenario_info = {"grid_model": base_grid.grid_model}
    tp = TransformProfile(empty_scenario_info, transformed_grid, ct.ct)
    transformed_demand_flexibility_up = tp.get_profile("demand_flexibility_up")
    transformed_demand_flexibility_dn = tp.get_profile("demand_flexibility_dn")
    assert base_demand_flexibility_up.equals(transformed_demand_flexibility_up)
    assert base_demand_flexibility_dn.equals(transformed_demand_flexibility_dn)
示例#11
0
    def get_profile(self, kind):
        """Returns demand, hydro, solar or wind  profile.

        :param str kind: either *'demand'*, *'hydro'*, *'solar'*, *'wind'*.
        :return: (*pandas.DataFrame*) -- profile.
        :raises Exception: if :attr:`builder` has not been assigned yet through
            meth:`set_builder` or if :meth:`_Builder.set_base_profile` has not been
            called yet.
        """
        if getattr(self.builder, kind):
            profile = TransformProfile(
                {
                    "grid_model": getattr(self.builder, "grid_model"),
                    "base_%s" % kind: getattr(self.builder, kind),
                },
                self.get_grid(),
                self.get_ct(),
            )
            return profile.get_profile(kind)
        else:
            raise Exception("%s profile version not set" % kind)
示例#12
0
    def prepare_profile(self, kind, profile_as=None, slice=False):
        """Prepares profile for simulation.

        :param kind: one of *demand*, *'hydro'*, *'solar'*, *'wind'*,
            *'demand_flexibility_up'*, *'demand_flexibility_dn'*,
            *'demand_flexibility_cost_up'*, or *'demand_flexibility_cost_dn'*.
        :param int/str profile_as: if given, copy profile from this scenario.
        :param bool slice: whether to slice the profiles by the Scenario's time range.
        """
        file_name = f"{kind}.csv"
        dest_path = "/".join([self.REL_TMP_DIR, file_name])
        if profile_as is None:
            tp = TransformProfile(self._scenario_info, self.grid, self.ct, slice)
            profile = tp.get_profile(kind)
            print(f"Writing scaled {kind} profile to {dest_path}")
            with self._data_access.write(dest_path, save_local=False) as f:
                profile.to_csv(f)
        else:
            from_dir = self._data_access.tmp_folder(profile_as)
            src = "/".join([from_dir, file_name])
            self._data_access.fs.copy(src, dest_path)
示例#13
0
def export_transformed_profile(kind,
                               scenario_info,
                               grid,
                               ct,
                               filepath,
                               slice=True):
    """Apply transformation to the given kind of profile and save the result locally.

    :param str kind: which profile to export. This parameter is passed to
        :meth:`TransformProfile.get_profile`.
    :param dict scenario_info: a dict containing the profile version, with
        key in the form base_{kind}
    :param powersimdata.input.grid.Grid grid: a Grid object previously
        transformed.
    :param dict ct: change table.
    :param str filepath: path to save the result, including the filename
    :param bool slice: whether to slice the profiles by the Scenario's time range.
    """
    tp = TransformProfile(scenario_info, grid, ct, slice)
    profile = tp.get_profile(kind)
    print(f"Writing scaled {kind} profile to {filepath} on local machine")
    profile.to_csv(filepath)
示例#14
0
def test_demand_is_scaled(base_grid):
    input_data = InputData()
    demand_info = {
        "interconnect": "_".join(interconnect),
        "grid_model": "usa_tamu",
        "base_demand": param["demand"],
    }
    raw_demand = input_data.get_data(demand_info, "demand")
    base_demand = raw_demand[base_grid.id2zone.keys()]

    n_zone = param["n_zone_to_scale"]
    ct = ChangeTable(base_grid)
    ct.scale_demand(
        zone_id={
            z: f
            for z, f in zip(
                np.random.choice(
                    [i for i in base_grid.zone2id.values()], size=n_zone, replace=False
                ),
                2 * np.random.random(size=n_zone),
            )
        }
    )

    tg = TransformGrid(base_grid, ct.ct)
    transformed_grid = tg.get_grid()

    tp = TransformProfile(demand_info, transformed_grid, ct.ct)
    transformed_profile = tp.get_profile("demand")
    assert not base_demand.equals(transformed_profile)

    scaled_zone = list(ct.ct["demand"]["zone_id"].keys())
    unscaled_zone = set(base_grid.id2zone.keys()) - set(scaled_zone)
    factor = list(ct.ct["demand"]["zone_id"].values())
    assert transformed_profile[scaled_zone].equals(
        base_demand[scaled_zone].multiply(factor, axis=1)
    )
    if unscaled_zone:
        assert transformed_profile[unscaled_zone].equals(base_demand[unscaled_zone])
示例#15
0
def _check_new_plants_are_added(ct, base_grid, raw_profile, resource):
    n_plant = param["n_plant_to_add"]
    plant_id_type = (base_grid.plant.isin(
        profile_type[resource]).query("type == True").index)
    base_profile = (raw_profile[plant_id_type] *
                    base_grid.plant.loc[plant_id_type, "Pmax"])

    tg = TransformGrid(base_grid, ct)
    transformed_grid = tg.get_grid()

    empty_scenario_info = {
    }  # scenario_info not needed since profile_input is mocked
    tp = TransformProfile(empty_scenario_info, transformed_grid, ct)
    transformed_profile = tp.get_profile(resource)

    assert not transformed_profile.equals(base_profile)
    assert not len(base_profile.columns) == len(transformed_profile.columns)
    assert len(set(transformed_profile.columns) -
               set(base_profile.columns)) == n_plant
    assert set(transformed_profile.columns) - set(base_profile.columns) == set(
        transformed_grid.plant.index[-n_plant:])

    return transformed_profile.drop(base_profile.columns, axis=1)