예제 #1
0
def test_model_initialize(test_mp, caplog):
    # Model.initialize runs on an empty Scenario
    s = make_dantzig(test_mp)
    b1 = s.par('b')
    assert len(b1) == 3

    # Modify a value for 'b'
    s.check_out()
    new_value = 301
    s.add_par('b', 'chicago', new_value, 'cases')
    s.commit('Overwrite b(chicago)')

    # Model.initialize runs on an already-initialized Scenario, without error
    DantzigModel.initialize(s, with_data=True)

    # Data has the same length...
    b2 = s.par('b')
    assert len(b2) == 3
    # ...but modified value(s) are not overwritten
    assert (b2.query("j == 'chicago'")['value'] == new_value).all()

    # Unrecognized Scenario(scheme=...) is initialized using the base method, a
    # no-op
    messages = [
        "No scheme for new Scenario model-name/scenario-name",
        "No initialization for None-scheme Scenario",
    ]
    with assert_logs(caplog, messages, at_level=logging.DEBUG):
        Scenario(test_mp, model='model-name', scenario='scenario-name',
                 version='new')

    with assert_logs(caplog, "No initialization for 'foo'-scheme Scenario",
                     at_level=logging.DEBUG):
        Scenario(test_mp, model='model-name', scenario='scenario-name',
                 version='new', scheme='foo')

    # Keyword arguments to Scenario(...) that are not recognized by
    # Model.initialize() raise an intelligible exception
    with pytest.raises(TypeError,
                       match="unexpected keyword argument 'bad_arg1'"):
        Scenario(test_mp, model='model-name', scenario='scenario-name',
                 version='new', scheme='unknown', bad_arg1=111)

    with pytest.raises(TypeError,
                       match="unexpected keyword argument 'bad_arg2'"):
        Scenario(test_mp, model='model-name', scenario='scenario-name',
                 version='new', scheme='dantzig', with_data=True,
                 bad_arg2=222)

    # Replace b[j] with a parameter of the same name, but different indices
    s.check_out()
    s.remove_par('b')
    s.init_par('b', idx_sets=['i'], idx_names=['i_dim'])

    # Logs an error message
    with assert_logs(caplog,
                     "Existing index sets of 'b' ['i'] do not match ['j']"):
        DantzigModel.initialize(s)
예제 #2
0
def test_model_initialize(test_mp, caplog):
    # Model.initialize runs on an empty Scenario
    s = make_dantzig(test_mp)
    b1 = s.par('b')
    assert len(b1) == 3

    # Modify a value for 'b'
    s.check_out()
    s.add_par('b', 'chicago', 600, 'cases')
    s.commit('Overwrite b(chicago)')

    # Model.initialize runs on an already-initialized Scenario, without error
    DantzigModel.initialize(s, with_data=True)

    # Data has the same length...
    b2 = s.par('b')
    assert len(b2) == 3
    # ...but modified value(s) are not overwritten
    assert (b2.query("j == 'chicago'")['value'] == 600).all()

    # Unrecognized Scenario(scheme=...) is initialized using the base method, a
    # no-op
    caplog.set_level(logging.DEBUG)
    Scenario(test_mp,
             model='model name',
             scenario='scenario name',
             version='new',
             scheme='unknown')
    assert caplog.records[-1].message == \
        "No initialization for 'unknown'-scheme Scenario"

    # Keyword arguments to Scenario(...) that are not recognized by
    # Model.initialize() raise an intelligible exception
    with pytest.raises(TypeError,
                       match="unexpected keyword argument 'bad_arg1'"):
        Scenario(test_mp,
                 model='model name',
                 scenario='scenario name',
                 version='new',
                 scheme='unknown',
                 bad_arg1=111)

    with pytest.raises(TypeError,
                       match="unexpected keyword argument 'bad_arg2'"):
        Scenario(test_mp,
                 model='model name',
                 scenario='scenario name',
                 version='new',
                 scheme='dantzig',
                 with_data=True,
                 bad_arg2=222)
예제 #3
0
    def scen_with_big_data(self, test_mp, num_params=10):
        from itertools import zip_longest

        # test_mp.add_unit('kg')
        scen = Scenario(test_mp, 'TestQuantity', 'big data', version='new')

        # Dimensions and their lengths (Fibonacci numbers)
        N_dims = 6
        dims = 'abcdefgh'[:N_dims + 1]
        sizes = [1, 5, 21, 21, 89, 377, 1597, 6765][:N_dims + 1]

        # commented: "377 / 73984365 elements = 0.00051% full"
        # from functools import reduce
        # from operator import mul
        # size = reduce(mul, sizes)
        # print('{} / {} elements = {:.5f}% full'
        #       .format(max(sizes), size, 100 * max(sizes) / size))

        # Names like f_0000 ... f_1596 along each dimension
        coords = []
        for d, N in zip(dims, sizes):
            coords.append([f'{d}_{i:04d}' for i in range(N)])
            # Add to Scenario
            scen.init_set(d)
            scen.add_set(d, coords[-1])

        def _make_values():
            """Make a DataFrame containing each label in *coords* ≥ 1 time."""
            values = list(zip_longest(*coords, np.random.rand(max(sizes))))
            result = pd.DataFrame(values, columns=list(dims) + ['value']) \
                       .ffill()
            result['unit'] = 'kg'
            return result

        # Fill the Scenario with quantities named q_01 ... q_09
        names = []
        for i in range(num_params):
            name = f'q_{i:02d}'
            scen.init_par(name, list(dims))
            scen.add_par(name, _make_values())
            names.append(name)

        yield scen
예제 #4
0
def test_maybe_commit(caplog, test_mp):
    s = Scenario(test_mp, "maybe_commit", "maybe_commit", version="new")

    # A new Scenario is not committed, so this works
    assert utils.maybe_commit(s, True, message="foo") is True

    # *s* is already commited. No commit is performed, but the function call
    # succeeds and a message is logged
    caplog.set_level(logging.INFO, logger="ixmp")
    assert utils.maybe_commit(s, True, message="foo") is False
    assert caplog.messages[-1].startswith("maybe_commit() didn't commit: ")
예제 #5
0
def test_store_ts(request, caplog, test_mp):
    # Computer and target scenario
    c = Computer()

    # Target scenario
    model_name = __name__
    scenario_name = "test scenario"
    scen = Scenario(test_mp, model_name, scenario_name, version="new")
    scen.commit("Empty scenario")
    c.add("target", scen)

    # Add test data to the Computer: a pd.DataFrame
    input_1 = test_data[0].assign(variable="Foo")
    c.add("input 1", input_1)

    # A pyam.IamDataFrame
    input_2 = test_data[2050].assign(variable="Bar")
    c.add("input 2", pyam.IamDataFrame(input_2))

    # Expected results: same as input, but with the `model` and `scenario` columns
    # filled automatically.
    expected_1 = input_1.assign(model=model_name, scenario=scenario_name)
    expected_2 = input_2.assign(model=model_name, scenario=scenario_name)

    # Task to update the scenario with the data
    c.add("test 1", store_ts, "target", "input 1", "input 2")

    # Scenario starts empty of time series data
    assert 0 == len(scen.timeseries())

    # The computation runs successfully
    c.get("test 1")

    # All rows from both inputs are present
    assert len(input_1) + len(input_2) == len(scen.timeseries())

    # Input is stored exactly
    assert_frame_equal(expected_1, scen.timeseries(variable="Foo"))
    assert_frame_equal(expected_2, scen.timeseries(variable="Bar"))
예제 #6
0
    def test_error_message(self, test_data_path, test_mp):
        """GAMSModel.solve() displays a user-friendly message on error."""
        # Empty Scenario
        s = Scenario(test_mp, model="foo", scenario="bar", version="new")
        s.commit("Initial commit")

        # Expected paths for error message
        paths = map(
            lambda name: re.escape(str(test_data_path.joinpath(name))),
            ["_abort.lst", "default_in.gdx"],
        )

        with pytest.raises(
                ModelError,
                match="""GAMS errored with return code 2:
    There was a compilation error

For details, see the terminal output above, plus:
Listing   : {}
Input data: {}""".format(*paths),
        ):
            s.solve(model_file=test_data_path / "_abort.gms",
                    use_temp_dir=False)
예제 #7
0
def test_timeseries_remove_all_data(mp):
    args_all = ('Douglas Adams', 'test_remove_all')

    scen = Scenario(mp, *args_all, version='new', annotation='fo')
    scen.add_timeseries(DATA['timeseries'].pivot_table(values='value',
                                                       index=IDX_COLS))
    scen.commit('importing a testing timeseries')

    scen = Scenario(mp, *args_all)
    assert_timeseries(scen, DATA['timeseries'])

    exp = DATA['timeseries'].copy()
    exp['variable'] = 'Testing2'

    scen.check_out()
    scen.add_timeseries(exp)
    scen.remove_timeseries(DATA['timeseries'])
    scen.commit('testing for removing a full timeseries row')

    assert scen.timeseries(region='World', variable='Testing').empty
    assert_timeseries(scen, exp)
예제 #8
0
def test_timeseries_remove_single_entry(mp):
    args_single = ('Douglas Adams', 'test_remove_single')

    scen = Scenario(mp, *args_single, version='new', annotation='fo')
    scen.add_timeseries(DATA['timeseries'].pivot_table(values='value',
                                                       index=IDX_COLS))
    scen.commit('importing a testing timeseries')

    scen = Scenario(mp, *args_single)
    assert_timeseries(scen, DATA['timeseries'])

    scen.check_out()
    scen.remove_timeseries(DATA['timeseries'][DATA['timeseries'].year == 2010])
    scen.commit('testing for removing a single timeseries data point')

    exp = DATA['timeseries'][DATA['timeseries'].year == 2020]
    assert_timeseries(scen, exp)
예제 #9
0
def test_timeseries_remove_all_data(mp):
    args_all = ("Douglas Adams", "test_remove_all")

    scen = Scenario(mp, *args_all, version="new", annotation="fo")
    scen.add_timeseries(DATA["timeseries"].pivot_table(values="value",
                                                       index=IDX_COLS))
    scen.commit("importing a testing timeseries")

    scen = Scenario(mp, *args_all)
    assert_timeseries(scen, DATA["timeseries"])

    exp = DATA["timeseries"].copy()
    exp["variable"] = "Testing2"

    scen.check_out()
    scen.add_timeseries(exp)
    scen.remove_timeseries(DATA["timeseries"])
    scen.commit("testing for removing a full timeseries row")

    assert scen.timeseries(region="World", variable="Testing").empty
    assert_timeseries(scen, exp)
예제 #10
0
def test_timeseries_remove_single_entry(mp):
    args_single = ("Douglas Adams", "test_remove_single")

    scen = Scenario(mp, *args_single, version="new", annotation="fo")
    scen.add_timeseries(DATA["timeseries"].pivot_table(values="value",
                                                       index=IDX_COLS))
    scen.commit("importing a testing timeseries")

    scen = Scenario(mp, *args_single)
    assert_timeseries(scen, DATA["timeseries"])

    scen.check_out()
    scen.remove_timeseries(DATA["timeseries"][DATA["timeseries"].year == 2010])
    scen.commit("testing for removing a single timeseries data point")

    exp = DATA["timeseries"][DATA["timeseries"].year == 2020]
    assert_timeseries(scen, exp)
예제 #11
0
파일: test_perf.py 프로젝트: iiasa/ixmp
def add_par_setup(mp, length):  # pragma: no cover
    return (Scenario(mp, **models["dantzig"], version="new"), length), dict()
예제 #12
0
파일: data.py 프로젝트: iiasa/ixmp
def make_dantzig(mp: Platform,
                 solve: bool = False,
                 quiet: bool = False) -> Scenario:
    """Return :class:`ixmp.Scenario` of Dantzig's canning/transport problem.

    Parameters
    ----------
    mp : .Platform
        Platform on which to create the scenario.
    solve : bool, optional
        If :obj:`True`. then solve the scenario before returning. Default :obj:`False`.
    quiet : bool, optional
        If :obj:`True`, suppress console output when solving.

    Returns
    -------
    .Scenario

    See also
    --------
    .DantzigModel
    """
    # add custom units and region for timeseries data
    try:
        mp.add_unit("USD/km")
    except Exception:
        # Unit already exists. Pending bugfix from zikolach
        pass
    mp.add_region("DantzigLand", "country")

    # Initialize a new Scenario, and use the DantzigModel class' initialize()
    # method to populate it
    annot = "Dantzig's transportation problem for illustration and testing"
    scen = Scenario(
        mp,
        **models["dantzig"],  # type: ignore [arg-type]
        version="new",
        annotation=annot,
        scheme="dantzig",
        with_data=True,
    )

    # commit the scenario
    scen.commit("Import Dantzig's transport problem for testing.")

    # set this new scenario as the default version for the model/scenario name
    scen.set_as_default()

    if solve:
        # Solve the model using the GAMS code provided in the `tests` folder
        scen.solve(model="dantzig", case="transport_standard", quiet=quiet)

    # add timeseries data for testing `clone(keep_solution=False)`
    # and `remove_solution()`
    scen.check_out(timeseries_only=True)
    scen.add_timeseries(HIST_DF, meta=True)
    scen.add_timeseries(INP_DF)
    scen.commit("Import Dantzig's transport problem for testing.")

    return scen
예제 #13
0
파일: data.py 프로젝트: iiasa/ixmp
def add_test_data(scen: Scenario):
    # New sets
    t_foo = ["foo{}".format(i) for i in (1, 2, 3)]
    t_bar = ["bar{}".format(i) for i in (4, 5, 6)]
    t = t_foo + t_bar
    y = list(map(str, range(2000, 2051, 10)))

    # Add to scenario
    scen.init_set("t")
    scen.add_set("t", t)
    scen.init_set("y")
    scen.add_set("y", y)

    # Data
    ureg = pint.get_application_registry()
    x = Quantity(
        xr.DataArray(np.random.rand(len(t), len(y)),
                     coords=[("t", t), ("y", y)]),
        units=ureg.kg,
    )

    # As a pd.DataFrame with units
    x_df = x.to_series().rename("value").reset_index()
    x_df["unit"] = "kg"

    scen.init_par("x", ["t", "y"])
    scen.add_par("x", x_df)

    return t, t_foo, t_bar, x