def test_agg_anyall(self, simple_linear_model): """Test the "any" and "all" aggregation functions""" model = simple_linear_model model.timestepper.delta = 1 model.timestepper.start = "2017-01-01" model.timestepper.end = "2017-01-03" scenarioA = Scenario(model, "Scenario A", size=2) scenarioB = Scenario(model, "Scenario B", size=5) num_comb = len(model.scenarios.get_combinations()) parameters = { 0: DummyIndexParameter(model, 0, name="p0"), 1: DummyIndexParameter(model, 1, name="p1"), 2: DummyIndexParameter(model, 2, name="p2"), } data = [(0, 0), (1, 0), (0, 1), (1, 1), (1, 1, 1), (0, 2)] data_parameters = [[parameters[i] for i in d] for d in data] expected = [(np.any(d), np.all(d)) for d in data] for n, params in enumerate(data_parameters): for m, agg_func in enumerate(["any", "all"]): p = AggregatedIndexParameter(model, params, agg_func=agg_func) e = np.ones([len(model.timestepper), num_comb]) * expected[n][m] r = AssertionRecorder(model, p, expected_data=e, name="assertion {}-{}".format(n, agg_func)) model.run()
def test_two_scenarios(simple_linear_model, ): """Basic test of Scenario functionality""" model = simple_linear_model # Convenience renaming scenario_input = Scenario(model, 'Inflow', size=2) model.nodes["Input"].max_flow = ConstantScenarioParameter( scenario_input, [5.0, 10.0]) scenario_outflow = Scenario(model, 'Outflow', size=2) model.nodes["Output"].max_flow = ConstantScenarioParameter( scenario_outflow, [3.0, 8.0]) model.nodes["Output"].cost = -2.0 # add numpy recorders to input and output nodes NumpyArrayNodeRecorder(model, model.nodes["Input"], "input") NumpyArrayNodeRecorder(model, model.nodes["Output"], "output") expected_node_results = { "Input": [3.0, 5.0, 3.0, 8.0], "Link": [3.0, 5.0, 3.0, 8.0], "Output": [3.0, 5.0, 3.0, 8.0], } assert_model(model, expected_node_results) model.run() # combine recorder outputs to a single dataframe df = model.to_dataframe() assert (df.shape == (365, 2 * 2 * 2)) assert_allclose(df["input", 0, 0].iloc[0], 3.0) assert_allclose(df["input", 0, 1].iloc[0], 5.0) assert_allclose(df["input", 1, 0].iloc[0], 3.0) assert_allclose(df["input", 1, 1].iloc[0], 8.0)
def test_parameter_array_indexed_scenario_monthly_factors(simple_linear_model): """ Test ArrayIndexedParameterScenarioMonthlyFactors """ model = simple_linear_model # Baseline timeseries data values = np.arange(len(model.timestepper), dtype=np.float64) # Add two scenarios scA = Scenario(model, 'Scenario A', size=2) scB = Scenario(model, 'Scenario B', size=5) # Random factors for each Scenario B value per month factors = np.random.rand(scB.size, 12) p = ArrayIndexedScenarioMonthlyFactorsParameter(model, scB, values, factors) model.setup() # Iterate in time for v, ts in zip(values, model.timestepper): imth = ts.datetime.month - 1 # Now ensure the appropriate value is returned for the Scenario B indices. for i, (a, b) in enumerate(itertools.product(range(scA.size), range(scB.size))): f = factors[b, imth] si = ScenarioIndex(i, np.array([a, b], dtype=np.int32)) np.testing.assert_allclose(p.value(ts, si), v*f)
def test_parameter_array_indexed_scenario_monthly_factors_json(model): model.path = os.path.join(TEST_DIR, "models") scA = Scenario(model, 'Scenario A', size=2) scB = Scenario(model, 'Scenario B', size=3) p1 = ArrayIndexedScenarioMonthlyFactorsParameter.load(model, { "scenario": "Scenario A", "values": list(range(32)), "factors": [list(range(1, 13)),list(range(13, 25))], }) p2 = ArrayIndexedScenarioMonthlyFactorsParameter.load(model, { "scenario": "Scenario B", "values": { "url": "timeseries1.csv", "index_col": "Timestamp", "column": "Data", }, "factors": { "url": "monthly_profiles.csv", "index_col": "scenario", }, }) node1 = Input(model, "node1", max_flow=p1) node2 = Input(model, "node2", max_flow=p2) nodeN = Output(model, "nodeN", max_flow=None, cost=-1) node1.connect(nodeN) node2.connect(nodeN) model.timestepper.start = "2015-01-01" model.timestepper.end = "2015-01-31" model.run()
def test_parameter_df_upsampling_multiple_columns(model): """ Test that the `DataFrameParameter` works with multiple columns that map to a `Scenario` """ scA = Scenario(model, 'A', size=20) scB = Scenario(model, 'B', size=2) # scenario indices (not used for this test) # Use a 7 day timestep for this test and run 2015 model.timestepper.delta = datetime.timedelta(7) model.timestepper.start = pd.to_datetime('2015-01-01') model.timestepper.end = pd.to_datetime('2015-12-31') # Daily time-step index = pd.date_range('2015-01-01', periods=365, freq='D') df = pd.DataFrame(np.random.rand(365, 20), index=index) p = DataFrameParameter(model, df, scenario=scA) p.setup() A = df.resample('7D', axis=0).mean() for v, ts in zip(A.values, model.timestepper): np.testing.assert_allclose([ p.value(ts, ScenarioIndex(i, np.array([i], dtype=np.int32))) for i in range(20) ], v) p = DataFrameParameter(model, df, scenario=scB) with pytest.raises(ValueError): p.setup()
def test_scenario_collection(): """ Basic test of Scenario and ScenarioCollection API """ model = Model() # There is 1 combination when there are no Scenarios model.scenarios.setup() assert(len(model.scenarios.combinations) == 1) assert(len(model.scenarios) == 0) scA = Scenario(model, 'Scenario A', size=3) model.scenarios.setup() assert(len(model.scenarios.combinations) == 3) assert(len(model.scenarios) == 1) scA = Scenario(model, 'Scenario B', size=2) model.scenarios.setup() assert(len(model.scenarios.combinations) == 6) assert(len(model.scenarios) == 2) assert_equal([comb.indices for comb in model.scenarios.combinations], [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]) names = model.scenarios.combination_names for n, (ia, ib) in zip(names, [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]): assert n == 'Scenario A.{:03d}-Scenario B.{:03d}'.format(ia, ib) index = model.scenarios.multiindex assert_equal(index.tolist(), [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]) assert_equal(index.names, ['Scenario A', 'Scenario B'])
def test_dirty_scenario(simple_linear_model): """Adding a scenario to a model makes it dirty""" model = simple_linear_model model.setup() assert(not model.dirty) scenario = Scenario(model, "test", size=42) assert(model.dirty)
def test_transfer(pywr_solver, size): """Test a simple transfer model. """ model = Model() Scenario(model, name='test', size=size) supply1 = Input(model, name='supply-1', max_flow=5.0) wtw1 = Link(model, name='wtw-1') demand1 = Output(model, name='demand-1', max_flow=10.0, cost=-10.0) supply1.connect(wtw1) wtw1.connect(demand1) supply2 = Input(model, name='supply-2', max_flow=15.0) wtw2 = Link(model, name='wtw-2') demand2 = Output(model, name='demand-2', max_flow=10.0, cost=-10.0) supply2.connect(wtw2) wtw2.connect(demand2) transfer21 = Link(model, name='transfer-12', max_flow=2.0, cost=1.0) wtw2.connect(transfer21) transfer21.connect(wtw1) model.setup() model.step() assert_allclose(supply1.flow, [5.0] * size) assert_allclose(demand1.flow, [7.0] * size) assert_allclose(supply2.flow, [12.0] * size) assert_allclose(demand2.flow, [10.0] * size) assert_allclose(transfer21.flow, [2.0] * size)
def test_aggregated_storage_scenarios(three_storage_model): """ Test `AggregatedScenario` correctly sums over scenarios. """ from pywr.core import Scenario from pywr.parameters import ConstantScenarioParameter m = three_storage_model sc = Scenario(m, 'A', size=5) agg_stg = m.nodes['Total Storage'] stgs = [m.nodes['Storage {}'.format(num)] for num in range(3)] # Setup scenario inpt1 = m.nodes['Input 1'].max_flow = ConstantScenarioParameter( sc, range(sc.size)) m.setup() m.step() # Finally check volume is summed correctly np.testing.assert_allclose(agg_stg.volume, np.sum(s.volume for s in stgs)) current_pc = np.sum(s.volume for s in stgs) / (np.sum(s.max_volume for s in stgs)) np.testing.assert_allclose(agg_stg.current_pc, current_pc) np.testing.assert_allclose(agg_stg.flow, np.sum(s.flow for s in stgs)) m.step() # Finally check volume is summed correctly np.testing.assert_allclose(agg_stg.volume, np.sum(s.volume for s in stgs)) current_pc = np.sum(s.volume for s in stgs) / (np.sum(s.max_volume for s in stgs)) np.testing.assert_allclose(agg_stg.current_pc, current_pc) np.testing.assert_allclose(agg_stg.flow, np.sum(s.flow for s in stgs))
def test_delay_node(key, delay, initial_flow): """Test that the `DelayNode` and the `FlowDelayParameter` internal to it correctly delay node for a range of inputs and across scenarios""" model = Model() model.timestepper.start = "2015/01/01" model.timestepper.end = "2015/01/31" scen = Scenario(model, name="scenario", size=2) flow_vals = np.arange(1, 63).reshape((31, 2), order="F") flow = ArrayIndexedScenarioParameter(model, scen, flow_vals) catchment = Catchment(model, name="input", flow=flow) kwargs = {key: delay} if initial_flow: kwargs["initial_flow"] = initial_flow delaynode = DelayNode(model, name="delaynode", **kwargs) output = Output(model, name="output") catchment.connect(delaynode) delaynode.connect(output) rec = NumpyArrayNodeRecorder(model, output) model.run() if initial_flow: expected = np.concatenate( [np.full((delay, 2), initial_flow), flow_vals[:-delay, :]]) else: expected = np.concatenate( [np.zeros((delay, 2)), flow_vals[:-delay, :]]) assert_array_almost_equal(rec.data, expected)
def test_mean_flow_recorder(solver): model = Model(solver=solver) model.timestepper.start = pandas.to_datetime("2016-01-01") model.timestepper.end = pandas.to_datetime("2016-01-04") inpt = Input(model, "input") otpt = Output(model, "output") inpt.connect(otpt) rec_flow = NumpyArrayNodeRecorder(model, inpt) rec_mean = MeanFlowRecorder(model, node=inpt, timesteps=3) scenario = Scenario(model, "dummy", size=2) inpt.max_flow = inpt.min_flow = FunctionParameter(model, inpt, lambda model, t, si: 2 + t.index) model.run() expected = [ 2.0, (2.0 + 3.0) / 2, (2.0 + 3.0 + 4.0) / 3, (3.0 + 4.0 + 5.0) / 3, # zeroth day forgotten ] for value, expected_value in zip(rec_mean.data[:, 0], expected): assert_allclose(value, expected_value)
def test_annual_count_index_parameter_recorder(simple_storage_model): """ Test AnnualCountIndexParameterRecord The test sets uses a simple reservoir model with different inputs that trigger a control curve failure after different numbers of years. """ from pywr.parameters import ConstantScenarioParameter, ConstantParameter from pywr.parameters.control_curves import ControlCurveIndexParameter model = simple_storage_model scenario = Scenario(model, 'A', size=2) # Simulate 5 years model.timestepper.start = '2015-01-01' model.timestepper.end = '2019-12-31' # Control curve parameter param = ControlCurveIndexParameter(model, model.nodes['Storage'], ConstantParameter(model, 0.25)) # Storage model has a capacity of 20, but starts at 10 Ml # Demand is roughly 2 Ml/d per year # First ensemble balances the demand # Second ensemble should fail during 3rd year demand = 2.0 / 365 model.nodes['Input'].max_flow = ConstantScenarioParameter(model, scenario, [demand, 0]) model.nodes['Output'].max_flow = demand # Create the recorder with a threshold of 1 rec = AnnualCountIndexParameterRecorder(model, param, 1) model.run() # We expect no failures in the first ensemble, but 3 out of 5 in the second assert_allclose(rec.values(), [0, 3])
def test_scenario_storage(): """Test the behaviour of Storage nodes with multiple scenarios The model defined has two inflow scenarios: 5 and 10. It is expected that the volume in the storage node should increase at different rates in the two scenarios. """ model = Model() i = Input(model, 'input', max_flow=999) s = Storage(model, 'storage', num_inputs=1, num_outputs=1, max_volume=1000, initial_volume=500) o = Output(model, 'output', max_flow=999) scenario_input = Scenario(model, 'Inflow', size=2) i.min_flow = ConstantScenarioParameter(model, scenario_input, [5.0, 10.0]) i.connect(s) s.connect(o) s_rec = NumpyArrayStorageRecorder(model, s) model.run() assert_allclose(i.flow, [5, 10]) assert_allclose(s_rec.data[0], [505, 510]) assert_allclose(s_rec.data[1], [510, 520])
def test_transfer2(pywr_solver, size): """Test a simple transfer model. """ model = Model() Scenario(model, name='test', size=size) demands = [9.47, 7.65, 9.04, 9.56, 9.44] supply = [4.74, 6.59, 12.04, 8.81, 11.75] for i, (s, d) in enumerate(zip(supply, demands)): s = Input(model, name=f'supply-{i}', max_flow=s) lnk = Link(model, name=f'wtw-{i}') d = Output(model, name=f'demand-{i}', max_flow=d, cost=-10.0) s.connect(lnk) lnk.connect(d) transfer04 = Link(model, name='transfer-04', max_flow=15.36, cost=1.0) model.nodes['wtw-0'].connect(transfer04) transfer04.connect(model.nodes['wtw-4']) model.setup() model.step() expected_supply = [4.74, 6.59, 9.04, 8.81, 9.44] for i, expected in enumerate(expected_supply): assert_allclose(model.nodes[f'supply-{i}'].flow, [expected] * size) assert_allclose(transfer04.flow, [0.0] * size, atol=1e-8)
def test_parameter_constant_scenario(simple_linear_model): """ Test ConstantScenarioParameter """ model = simple_linear_model # Add two scenarios scA = Scenario(model, 'Scenario A', size=2) scB = Scenario(model, 'Scenario B', size=5) p = ConstantScenarioParameter(model, scB, np.arange(scB.size, dtype=np.float64)) model.setup() ts = model.timestepper.current # Now ensure the appropriate value is returned for the Scenario B indices. for i, (a, b) in enumerate(itertools.product(range(scA.size), range(scB.size))): si = ScenarioIndex(i, np.array([a, b], dtype=np.int32)) np.testing.assert_allclose(p.value(ts, si), float(b))
def test_ocptt(simple_linear_model): model = simple_linear_model inpt = model.nodes["Input"] s1 = Scenario(model, "scenario 1", size=3) s2 = Scenario(model, "scenario 1", size=2) x = np.arange(len(model.timestepper)).reshape([len(model.timestepper), 1]) + 5 y = np.arange(s1.size).reshape([1, s1.size]) z = x * y ** 2 p = ArrayIndexedScenarioParameter(model, s1, z) inpt.max_flow = p model.setup() model.reset() model.step() values1 = [p.get_value(scenario_index) for scenario_index in model.scenarios.combinations] values2 = list(p.get_all_values()) assert_allclose(values1, [0, 0, 5, 5, 20, 20]) assert_allclose(values2, [0, 0, 5, 5, 20, 20])
def test_basic_use(self, simple_linear_model): """ Test the basic use of `ConstantParameter` using the Python API """ model = simple_linear_model # Add two scenarios scA = Scenario(model, 'Scenario A', size=2) scB = Scenario(model, 'Scenario B', size=5) p = ConstantParameter(model, np.pi, name='pi', comment='Mmmmm Pi!') assert not p.is_variable assert p.double_size == 1 assert p.integer_size == 0 model.setup() ts = model.timestepper.current # Now ensure the appropriate value is returned for all scenarios for i, (a, b) in enumerate(itertools.product(range(scA.size), range(scB.size))): si = ScenarioIndex(i, np.array([a, b], dtype=np.int32)) np.testing.assert_allclose(p.value(ts, si), np.pi)
def test_two_scenarios(simple_linear_model, ): """Basic test of Scenario functionality""" model = simple_linear_model # Convenience renaming scenario_input = Scenario(model, 'Inflow', size=2) model.nodes["Input"].max_flow = ConstantScenarioParameter( model, scenario_input, [5.0, 10.0]) scenario_outflow = Scenario(model, 'Outflow', size=2, ensemble_names=['High', 'Low']) model.nodes["Output"].max_flow = ConstantScenarioParameter( model, scenario_outflow, [3.0, 8.0]) model.nodes["Output"].cost = -2.0 # Check ensemble names are provided in the multi-index index = model.scenarios.multiindex assert index.levels[0].name == 'Inflow' assert index.levels[1].name == 'Outflow' assert np.all(index.levels[1] == ['High', 'Low']) # add numpy recorders to input and output nodes NumpyArrayNodeRecorder(model, model.nodes["Input"], "input") NumpyArrayNodeRecorder(model, model.nodes["Output"], "output") expected_node_results = { "Input": [3.0, 5.0, 3.0, 8.0], "Link": [3.0, 5.0, 3.0, 8.0], "Output": [3.0, 5.0, 3.0, 8.0], } assert_model(model, expected_node_results) model.run() # combine recorder outputs to a single dataframe df = model.to_dataframe() assert (df.shape == (365, 2 * 2 * 2)) assert_allclose(df["input", 0, 'High'].iloc[0], 3.0) assert_allclose(df["input", 0, 'Low'].iloc[0], 5.0) assert_allclose(df["input", 1, 'High'].iloc[0], 3.0) assert_allclose(df["input", 1, 'Low'].iloc[0], 8.0)
def test_threshold_parameter(simple_linear_model): model = simple_linear_model model.timestepper.delta = 150 scenario = Scenario(model, "Scenario", size=2) class DummyRecorder(Recorder): def __init__(self, model, value, *args, **kwargs): super(DummyRecorder, self).__init__(model, *args, **kwargs) self.val = value def setup(self): super(DummyRecorder, self).setup() num_comb = len(model.scenarios.combinations) self.data = np.empty([len(model.timestepper), num_comb], dtype=np.float64) def after(self): timestep = model.timestepper.current self.data[timestep.index, :] = self.val threshold = 10.0 values = [50.0, 60.0] rec1 = DummyRecorder(model, threshold - 5, name="rec1") # below rec2 = DummyRecorder(model, threshold, name="rec2") # equal rec3 = DummyRecorder(model, threshold + 5, name="rec3") # above expected = [ ("LT", (1, 0, 0)), ("GT", (0, 0, 1)), ("EQ", (0, 1, 0)), ("LE", (1, 1, 0)), ("GE", (0, 1, 1)), ] for predicate, (value_lt, value_eq, value_gt) in expected: for rec in (rec1, rec2, rec3): param = RecorderThresholdParameter(model, rec, threshold, values=values, predicate=predicate) e_val = values[getattr(rec.val, "__{}__".format( predicate.lower()))(threshold)] e = np.ones([ len(model.timestepper), len(model.scenarios.get_combinations()) ]) * e_val e[0, :] = values[1] # first timestep is always "on" r = AssertionRecorder(model, param, expected_data=e) r.name = "assert {} {} {}".format(rec.val, predicate, threshold) model.run()
def test_min(self, model): # Add two scenarios scA = Scenario(model, 'Scenario A', size=2) scB = Scenario(model, 'Scenario B', size=5) values = np.arange(366, dtype=np.float64) p1 = DailyProfileParameter(values) p2 = ConstantScenarioParameter(scB, np.arange(scB.size, dtype=np.float64)) p = AggregatedParameter([ p1, ], agg_func='min') p.add(p2) p.setup(model) for ts in model.timestepper: iday = ts.datetime.dayofyear - 1 for i in range(scB.size): si = ScenarioIndex(i, np.array([0, i], dtype=np.int32)) np.testing.assert_allclose(p.value(ts, si), min(values[iday], i))
def test_max(self, model): # Add two scenarios scA = Scenario(model, 'Scenario A', size=2) scB = Scenario(model, 'Scenario B', size=5) values = np.arange(366, dtype=np.float64) p1 = DailyProfileParameter(values) p2 = ConstantScenarioParameter(scB, np.arange(scB.size, dtype=np.float64)) p = AggregatedParameter([p1, p2], agg_func='max') p.setup(model) for ts in model.timestepper: month = ts.datetime.month day = ts.datetime.day iday = int((datetime.datetime(2016, month, day) - datetime.datetime(2016, 1, 1)).days) for i in range(scB.size): si = ScenarioIndex(i, np.array([0, i], dtype=np.int32)) np.testing.assert_allclose(p.value(ts, si), max(values[iday], i))
def test_agg(self, simple_linear_model, agg_func): model = simple_linear_model model.timestepper.delta = 15 scenarioA = Scenario(model, "Scenario A", size=2) scenarioB = Scenario(model, "Scenario B", size=5) values = np.arange(366, dtype=np.float64) p1 = DailyProfileParameter(model, values) p2 = ConstantScenarioParameter(model, scenarioB, np.arange(scenarioB.size, dtype=np.float64)) p = AggregatedParameter(model, [p1, p2], agg_func=agg_func) func = TestAggregatedParameter.funcs[agg_func] @assert_rec(model, p) def expected_func(timestep, scenario_index): x = p1.get_value(scenario_index) y = p2.get_value(scenario_index) return func(np.array([x,y])) model.run()
def test_scenario_user_combinations(simple_linear_model): model = simple_linear_model # create two scenarios s1 = Scenario(model=model, name="A", size=20) s2 = Scenario(model=model, name="B", size=3) model.scenarios.user_combinations = [[0, 1], [1, 1]] combinations = model.scenarios.get_combinations() assert(len(combinations) == 2) # ScenarioCollection.shape is simply the number of combinations assert model.scenarios.shape == (2, ) # Test wrong number of dimensions with pytest.raises(ValueError): model.scenarios.user_combinations = [0, 1, 1, 1] # Test out of range index with pytest.raises(ValueError): model.scenarios.user_combinations = [[19, 3], [2, 2]] with pytest.raises(ValueError): model.scenarios.user_combinations = [[-1, 2], [2, 2]]
def test_init(self, model): scenario = Scenario(model, 'A', 10) values = np.random.rand(10, 12) p = ScenarioMonthlyProfileParameter(scenario, values) p.setup(model) # Iterate in time for ts in model.timestepper: imth = ts.datetime.month - 1 for i in range(scenario.size): si = ScenarioIndex(i, np.array([i], dtype=np.int32)) np.testing.assert_allclose(p.value(ts, si), values[i, imth])
def test_user_scenarios(self, simple_linear_model, tmpdir): """ Test the TablesRecorder with user defined scenario subset """ from pywr.parameters import ConstantScenarioParameter model = simple_linear_model scA = Scenario(model, name='A', size=4) scB = Scenario(model, name='B', size=2) # Use first and last combinations model.scenarios.user_combinations = [[0, 0], [3, 1]] otpt = model.nodes['Output'] inpt = model.nodes['Input'] inpt.max_flow = ConstantScenarioParameter(model, scA, [10, 20, 30, 40]) otpt.max_flow = ConstantScenarioParameter(model, scB, [20, 40]) otpt.cost = -2.0 h5file = tmpdir.join('output.h5') import tables with tables.open_file(str(h5file), 'w') as h5f: rec = TablesRecorder(model, h5f) model.run() for node_name in model.nodes.keys(): ca = h5f.get_node('/', node_name) assert ca.shape == (365, 2) np.testing.assert_allclose(ca[0, ...], [10, 40]) # check combinations table exists combinations = h5f.get_node('/scenario_combinations') for i, comb in enumerate(model.scenarios.user_combinations): row = combinations[i] assert row['A'] == comb[0] assert row['B'] == comb[1]
def test_concatenated_dataframes(simple_storage_model): """ Test that Model.to_dataframe returns something sensible. """ model = simple_storage_model scA = Scenario(model, 'A', size=2) scB = Scenario(model, 'B', size=3) res = model.nodes['Storage'] rec1 = NumpyArrayStorageRecorder(model, res) otpt = model.nodes['Output'] rec2 = NumpyArrayNodeRecorder(model, otpt) # The following can't return a DataFrame; is included to check # it doesn't cause any issues rec3 = TotalDeficitNodeRecorder(model, otpt) model.run() df = model.to_dataframe() assert df.shape == (5, 2*2*3) assert df.columns.names == ['Recorder', 'A', 'B']
def test_cache_scenarios(simple_model): """ Test caching across scenarios. """ model = simple_model scen = Scenario(model, 'Scenario A', size=2) param = ConstantScenarioParameter(scen, [10, 20]) inpt = model.nodes["input"] inpt.max_flow = CachedParameter(param) model.run() assert_allclose(inpt.flow, [10.0, 20.0])
def test_agg(self, simple_linear_model, agg_func): model = simple_linear_model model.timestepper.delta = 1 model.timestepper.start = "2017-01-01" model.timestepper.end = "2017-01-03" scenarioA = Scenario(model, "Scenario A", size=2) scenarioB = Scenario(model, "Scenario B", size=5) p1 = DummyIndexParameter(model, 2) p2 = DummyIndexParameter(model, 3) p = AggregatedIndexParameter(model, [p1, p2], agg_func=agg_func) func = TestAggregatedIndexParameter.funcs[agg_func] @assert_rec(model, p) def expected_func(timestep, scenario_index): x = p1.get_index(scenario_index) y = p2.get_index(scenario_index) return func(np.array([x, y], np.int32)) model.run()
def cyclical_storage_model(simple_storage_model): """ Extends simple_storage_model to have a cyclical boundary condition """ from pywr.parameters import AnnualHarmonicSeriesParameter, ConstantScenarioParameter m = simple_storage_model s = Scenario(m, name='Scenario A', size=3) m.timestepper.end = '2017-12-31' m.timestepper.delta = 5 inpt = m.nodes['Input'] inpt.max_flow = AnnualHarmonicSeriesParameter(m, 5, [0.1, 0.0, 0.25], [0.0, 0.0, 0.0]) otpt = m.nodes['Output'] otpt.max_flow = ConstantScenarioParameter(m, s, [5, 6, 2]) return m
def test_scenario_slices(simple_linear_model): """Test slicing of scenarios""" model = simple_linear_model # create two scenarios s1 = Scenario(model=model, name="A", size=20) s2 = Scenario(model=model, name="B", size=3) combinations = model.scenarios.get_combinations() assert(len(combinations) == 20 * 3) s1.slice = slice(0, None, 2) combinations = model.scenarios.get_combinations() assert(len(combinations) == 10 * 3) # check multiindex respects scenario slices index = model.scenarios.multiindex assert(len(index.levels) == 2) assert(len(index.levels[0]) == 10) assert(len(index.levels[1]) == 3) assert(len(index.codes) == 2) assert(len(index.codes[0]) == 10 * 3) assert(len(index.codes[1]) == 10 * 3) assert(index.names == ["A", "B"]) s2.slice = slice(1, 3, 1) combinations = model.scenarios.get_combinations() assert(len(combinations) == 10 * 2) assert(combinations[0].global_id == 0) assert(tuple(combinations[0].indices) == (0, 1)) assert(combinations[-1].global_id == 19) assert(tuple(combinations[-1].indices) == (18, 2)) model.run() node = model.nodes["Input"] assert((len(combinations),) == node.flow.shape) s1.slice = None s2.slice = None combinations = model.scenarios.get_combinations() assert(len(combinations) == 20 * 3)