diff --git a/src/muse/data/example/default_new_input/agent_objectives.csv b/src/muse/data/example/default_new_input/agent_objectives.csv new file mode 100644 index 000000000..c14612aaa --- /dev/null +++ b/src/muse/data/example/default_new_input/agent_objectives.csv @@ -0,0 +1,3 @@ +agent,objective,objective_data,objective_sort +Agent1,LCOE,1,TRUE +Agent2,LCOE,1,TRUE diff --git a/src/muse/data/example/default_new_input/agent_pairs.csv b/src/muse/data/example/default_new_input/agent_pairs.csv new file mode 100644 index 000000000..72e306f93 --- /dev/null +++ b/src/muse/data/example/default_new_input/agent_pairs.csv @@ -0,0 +1,2 @@ +name,new_agent,retrofit_agent,quantity +A1,Agent1,Agent2,1 diff --git a/src/muse/data/example/default_new_input/agent_regions.csv b/src/muse/data/example/default_new_input/agent_regions.csv new file mode 100644 index 000000000..257b59615 --- /dev/null +++ b/src/muse/data/example/default_new_input/agent_regions.csv @@ -0,0 +1,2 @@ +agent_pair,region +A1,R1 diff --git a/src/muse/data/example/default_new_input/agents.csv b/src/muse/data/example/default_new_input/agents.csv new file mode 100644 index 000000000..2d1261bde --- /dev/null +++ b/src/muse/data/example/default_new_input/agents.csv @@ -0,0 +1,3 @@ +agent,description,type,maturity_threshold,annual_cost_limit,search_rule,decision_rule +Agent1,New agent for A1,new,-1,inf,all,single +Agent2,Retrofit agent for A1,retrofit,-1,inf,all,single diff --git a/src/muse/data/example/default_new_input/assets.csv b/src/muse/data/example/default_new_input/assets.csv new file mode 100644 index 000000000..c30df1a13 --- /dev/null +++ b/src/muse/data/example/default_new_input/assets.csv @@ -0,0 +1,8 @@ +process_name,region,agent,capacity,year +gassupply1,R1,Agent2,15,2020 +gassupply1,R1,Agent2,15,2025 +gassupply1,R1,Agent2,7.5,2030 +gasCCGT,R1,Agent2,1,2020 +gasCCGT,R1,Agent2,1,2025 +gasboiler,R1,Agent2,10,2020 +gasboiler,R1,Agent2,5,2025 diff --git a/src/muse/data/example/default_new_input/commodities.csv b/src/muse/data/example/default_new_input/commodities.csv new file mode 100644 index 000000000..cec5cbf65 --- /dev/null +++ b/src/muse/data/example/default_new_input/commodities.csv @@ -0,0 +1,6 @@ +commodity_name,description,type,unit +electricity,Electricity,energy,PJ +gas,Gas,energy,PJ +heat,Heat,energy,PJ +wind,Wind,energy,PJ +C02f,Carbon dioxide,energy,kt diff --git a/src/muse/data/example/default_new_input/commodity_costs.csv b/src/muse/data/example/default_new_input/commodity_costs.csv new file mode 100644 index 000000000..85309f435 --- /dev/null +++ b/src/muse/data/example/default_new_input/commodity_costs.csv @@ -0,0 +1,58 @@ +year,region,commodity_name,value +2010,R1,electricity,14.81481472 +2015,R1,electricity,17.89814806 +2020,R1,electricity,19.5 +2025,R1,electricity,21.93518528 +2030,R1,electricity,26.50925917 +2035,R1,electricity,26.51851861 +2040,R1,electricity,23.85185194 +2045,R1,electricity,23.97222222 +2050,R1,electricity,24.06481472 +2055,R1,electricity,25.3425925 +2060,R1,electricity,25.53703694 +2065,R1,electricity,25.32407417 +2070,R1,electricity,23.36111111 +2075,R1,electricity,22.27777778 +2080,R1,electricity,22.25925917 +2085,R1,electricity,22.17592583 +2090,R1,electricity,22.03703694 +2095,R1,electricity,21.94444444 +2100,R1,electricity,21.39814806 +2010,R1,gas,6.6759 +2015,R1,gas,6.914325 +2020,R1,gas,7.15275 +2025,R1,gas,8.10645 +2030,R1,gas,9.06015 +2035,R1,gas,9.2191 +2040,R1,gas,9.37805 +2045,R1,gas,9.193829337 +2050,R1,gas,9.009608674 +2055,R1,gas,8.832625604 +2060,R1,gas,8.655642534 +2065,R1,gas,8.485612708 +2070,R1,gas,8.315582883 +2075,R1,gas,8.152233126 +2080,R1,gas,7.988883368 +2085,R1,gas,7.831951236 +2090,R1,gas,7.675019103 +2095,R1,gas,7.524252461 +2100,R1,gas,7.373485819 +2010,R1,CO2f,0 +2015,R1,CO2f,0.052913851 +2020,R1,CO2f,0.08314119 +2025,R1,CO2f,0.120069795 +2030,R1,CO2f,0.156998399 +2035,R1,CO2f,0.214877567 +2040,R1,CO2f,0.272756734 +2045,R1,CO2f,0.35394801 +2050,R1,CO2f,0.435139285 +2055,R1,CO2f,0.542365578 +2060,R1,CO2f,0.649591871 +2065,R1,CO2f,0.780892624 +2070,R1,CO2f,0.912193378 +2075,R1,CO2f,1.078321687 +2080,R1,CO2f,1.244449995 +2085,R1,CO2f,1.4253503 +2090,R1,CO2f,1.606250604 +2095,R1,CO2f,1.73877515 +2100,R1,CO2f,1.871299697 diff --git a/src/muse/data/example/default_new_input/commodity_trade.csv b/src/muse/data/example/default_new_input/commodity_trade.csv new file mode 100644 index 000000000..eb23c4b6c --- /dev/null +++ b/src/muse/data/example/default_new_input/commodity_trade.csv @@ -0,0 +1 @@ +commodity,region,net_import,year diff --git a/src/muse/data/example/default_new_input/demand.csv b/src/muse/data/example/default_new_input/demand.csv new file mode 100644 index 000000000..13c64fe8c --- /dev/null +++ b/src/muse/data/example/default_new_input/demand.csv @@ -0,0 +1,3 @@ +year,commodity_name,region,demand +2020,heat,R1,10 +2050,heat,R1,30 diff --git a/src/muse/data/example/default_new_input/demand_slicing.csv b/src/muse/data/example/default_new_input/demand_slicing.csv new file mode 100644 index 000000000..10d4693c2 --- /dev/null +++ b/src/muse/data/example/default_new_input/demand_slicing.csv @@ -0,0 +1,7 @@ +commodity,region,timeslice,fraction,year +heat,R1,night,0.1, +heat,R1,morning,0.15, +heat,R1,afternoon,0.1, +heat,R1,early-peak,0.15, +heat,R1,late-peak,0.3, +heat,R1,evening,0.2, diff --git a/src/muse/data/example/default_new_input/process_availabilities.csv b/src/muse/data/example/default_new_input/process_availabilities.csv new file mode 100644 index 000000000..300a11407 --- /dev/null +++ b/src/muse/data/example/default_new_input/process_availabilities.csv @@ -0,0 +1,6 @@ +process_name,timeslice,lim_type,value,year,region +gassupply1,ALL,UP,0.9,, +gasCCGT,ALL,UP,0.9,, +windturbine,ALL,UP,0.4,, +gasboiler,ALL,UP,1,, +heatpump,ALL,UP,1,, diff --git a/src/muse/data/example/default_new_input/process_flows.csv b/src/muse/data/example/default_new_input/process_flows.csv new file mode 100644 index 000000000..e6e72c67d --- /dev/null +++ b/src/muse/data/example/default_new_input/process_flows.csv @@ -0,0 +1,12 @@ +process_name,commodity_name,flow,year,region +gassupply1,gas,1,, +gasCCGT,gas,-1.67,, +gasCCGT,electricity,1,, +gasCCGT,CO2f,91.67,, +windturbine,wind,-1,, +windturbine,electricity,1,, +gasboiler,gas,-1.16,, +gasboiler,heat,1,, +gasboiler,CO2f,64.71,, +heatpump,electricity,-0.4,, +heatpump,heat,1,, diff --git a/src/muse/data/example/default_new_input/process_parameters.csv b/src/muse/data/example/default_new_input/process_parameters.csv new file mode 100644 index 000000000..00bb38bb7 --- /dev/null +++ b/src/muse/data/example/default_new_input/process_parameters.csv @@ -0,0 +1,6 @@ +process,cap_par,cap_exp,fix_par,fix_exp,var_par,var_exp,max_capacity_addition,max_capacity_growth,total_capacity_limit,life,scaling_size,efficiency,discount_rate,year,region +gassupply1,0,1,0,1,2.55,1,5,1,60,35,0.00000189,86,0.1,, +gasCCGT,23.78234399,1,0,1,0,1,2,1,60,35,0.00000189,86,0.1,, +windturbine,36.30771182,1,0,1,0,1,2,1,60,25,0.00000189,86,0.1,, +gasboiler,3.8,1,0,1,0,1,10,0.02,60,10,0.00000189,86,0.1,, +heatpump,8.866667,1,0,1,0,1,10,0.02,60,10,0.00000189,86,0.1,, diff --git a/src/muse/data/example/default_new_input/process_regions.csv b/src/muse/data/example/default_new_input/process_regions.csv new file mode 100644 index 000000000..e7ca8286c --- /dev/null +++ b/src/muse/data/example/default_new_input/process_regions.csv @@ -0,0 +1,6 @@ +process,region +gassupply1,R1 +gasCCGT,R1 +windturbine,R1 +gasboiler,R1 +heatpump,R1 diff --git a/src/muse/data/example/default_new_input/processes.csv b/src/muse/data/example/default_new_input/processes.csv new file mode 100644 index 000000000..7c4b9f818 --- /dev/null +++ b/src/muse/data/example/default_new_input/processes.csv @@ -0,0 +1,6 @@ +name,type,fuel,end_use,level,sector +gassupply1,energy,gas,gas,fixed,gas +gasCCGT,energy,gas,electricity,fixed,power +windturbine,energy,wind,electricity,fixed,power +gasboiler,energy,gas,heat,fixed,residential +heatpump,energy,electricity,heat,fixed,residential diff --git a/src/muse/data/example/default_new_input/regions.csv b/src/muse/data/example/default_new_input/regions.csv new file mode 100644 index 000000000..1583e5334 --- /dev/null +++ b/src/muse/data/example/default_new_input/regions.csv @@ -0,0 +1,2 @@ +name,description +R1,Region 1 diff --git a/src/muse/data/example/default_new_input/sectors.csv b/src/muse/data/example/default_new_input/sectors.csv new file mode 100644 index 000000000..a841328b6 --- /dev/null +++ b/src/muse/data/example/default_new_input/sectors.csv @@ -0,0 +1,4 @@ +name,description +gas,Gas sector +power,Power sector +residential,Residential sector diff --git a/src/muse/data/example/default_new_input/time_slices.csv b/src/muse/data/example/default_new_input/time_slices.csv new file mode 100644 index 000000000..376022d96 --- /dev/null +++ b/src/muse/data/example/default_new_input/time_slices.csv @@ -0,0 +1,7 @@ +season,day,time_of_day,fraction +all,all,night,0.1667 +all,all,morning,0.1667 +all,all,afternoon,0.1667 +all,all,early-peak,0.1667 +all,all,late-peak,0.1667 +all,all,evening,0.1667 diff --git a/src/muse/examples.py b/src/muse/examples.py index a888763ff..ad01c1595 100644 --- a/src/muse/examples.py +++ b/src/muse/examples.py @@ -47,7 +47,12 @@ def example_data_dir() -> Path: def available_examples() -> list[str]: """List examples available in the examples folder.""" - return [d.stem for d in example_data_dir().iterdir() if d.is_dir()] + # temporary skip for default_new_input as this is not yet working + return [ + d.stem + for d in example_data_dir().iterdir() + if d.is_dir() and d.name != "default_new_input" + ] def model(name: str = "default") -> MCA: @@ -108,6 +113,8 @@ def copy_model( _copy_minimum_service(path) elif name.lower() == "trade": _copy_trade(path) + elif name.lower() == "default_new_input": + _copy_default_new_input(path) return path @@ -288,6 +295,12 @@ def _copy_default(path: Path): copyfile(example_data_dir() / "default" / "settings.toml", path / "settings.toml") +def _copy_default_new_input(path: Path): + from shutil import copytree + + copytree(example_data_dir() / "default_new_input", path) + + def _copy_default_timeslice(path: Path): from shutil import copyfile, copytree diff --git a/tests/test_readers.py b/tests/test_readers.py index 31e110f13..1543959df 100644 --- a/tests/test_readers.py +++ b/tests/test_readers.py @@ -5,7 +5,7 @@ import numpy as np import toml import xarray as xr -from pytest import fixture, mark, raises +from pytest import approx, fixture, mark, raises @fixture @@ -854,3 +854,148 @@ def test_check_utilization_and_minimum_service_factors_fail_missing_utilization( with raises(ValueError): check_utilization_and_minimum_service_factors(df, "file.csv") + + +@fixture +def default_new_input(tmp_path): + from muse.examples import copy_model + + copy_model("default_new_input", tmp_path) + return tmp_path + + +@mark.xfail +def test_read_new_global_commodities(default_new_input): + from muse.new_input.readers import read_inputs + + all_data = read_inputs(default_new_input) + data = all_data["global_commodities"] + + assert isinstance(data, xr.Dataset) + assert set(data.dims) == {"commodity"} + assert dict(data.dtypes) == dict( + type=np.dtype("str"), + unit=np.dtype("str"), + ) + + assert list(data.coords["commodity"].values) == [ + "electricity", + "gas", + "heat", + "wind", + "CO2f", + ] + assert list(data.data_vars["type"].values) == ["energy"] * 5 + assert list(data.data_vars["unit"].values) == ["PJ"] * 4 + ["kt"] + + +@mark.xfail +def test_read_demand(default_new_input): + from muse.new_input.readers import read_inputs + + all_data = read_inputs(default_new_input) + data = all_data["demand"] + + assert isinstance(data, xr.DataArray) + assert data.dtype == np.float64 + + assert set(data.dims) == {"year", "commodity", "region", "timeslice"} + assert list(data.coords["region"].values) == ["R1"] + assert list(data.coords["timeslice"].values) == list(range(1, 7)) + assert list(data.coords["year"].values) == [2020, 2050] + assert set(data.coords["commodity"].values) == { + "electricity", + "gas", + "heat", + "wind", + "CO2f", + } + + assert data.sel(year=2020, commodity="electricity", region="R1", timeslice=0) == 1 + + +@mark.xfail +def test_new_read_initial_market(default_new_input): + from muse.new_input.readers import read_inputs + + all_data = read_inputs(default_new_input) + data = all_data["initial_market"] + + assert isinstance(data, xr.Dataset) + assert set(data.dims) == {"region", "year", "commodity", "timeslice"} + assert dict(data.dtypes) == dict( + prices=np.float64, + exports=np.float64, + imports=np.float64, + static_trade=np.float64, + ) + assert list(data.coords["region"].values) == ["R1"] + assert list(data.coords["year"].values) == list(range(2010, 2105, 5)) + assert list(data.coords["commodity"].values) == [ + "electricity", + "gas", + "heat", + "CO2f", + "wind", + ] + month_values = ["all-year"] * 6 + day_values = ["all-week"] * 6 + hour_values = [ + "night", + "morning", + "afternoon", + "early-peak", + "late-peak", + "evening", + ] + + assert list(data.coords["timeslice"].values) == list( + zip(month_values, day_values, hour_values) + ) + assert list(data.coords["month"]) == month_values + assert list(data.coords["day"]) == day_values + assert list(data.coords["hour"]) == hour_values + + assert all(var.coords.equals(data.coords) for var in data.data_vars.values()) + + prices = data.data_vars["prices"] + assert approx( + prices.sel( + year=2010, + region="R1", + commodity="electricity", + timeslice=("all-year", "all-week", "night"), + ) + - 14.81481, + abs=1e-4, + ) + + exports = data.data_vars["exports"] + assert ( + exports.sel( + year=2010, + region="R1", + commodity="electricity", + timeslice=("all-year", "all-week", "night"), + ) + ) == 0 + + imports = data.data_vars["imports"] + assert ( + imports.sel( + year=2010, + region="R1", + commodity="electricity", + timeslice=("all-year", "all-week", "night"), + ) + ) == 0 + + static_trade = data.data_vars["static_trade"] + assert ( + static_trade.sel( + year=2010, + region="R1", + commodity="electricity", + timeslice=("all-year", "all-week", "night"), + ) + ) == 0