From 72f53bab257d8c8ad9f273126dcb9f66ba24b11a Mon Sep 17 00:00:00 2001 From: Johannes Kochems Date: Tue, 12 Oct 2021 10:29:37 +0200 Subject: [PATCH 1/2] Include time series reindexing for target year --- pommesdata/data_prep/tools.py | 40 +++++++++++++++++++++++++++++-- pommesdata/data_preparation.ipynb | 24 ++++++++++++------- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/pommesdata/data_prep/tools.py b/pommesdata/data_prep/tools.py index a6eb098..1848141 100644 --- a/pommesdata/data_prep/tools.py +++ b/pommesdata/data_prep/tools.py @@ -13,7 +13,8 @@ - assign time-dependent NTC values, - convert data into the structure of oemof.solph, - load ENTSO-E data and transfer it to the format needed, -- extract capacities from the TYNDP 2018 scenario data set. +- extract capacities from the TYNDP 2018 scenario data set, +- reindex timeseries data for another year of choice. Licensing information and Disclaimer ------------------------------------ @@ -430,4 +431,39 @@ def extract_tyndp_capacities(countries, no_dict, scenario="2030_DG", 'variable': 'fuel', 'value': 'capacity'}) - return pp_eu_target_year \ No newline at end of file + return pp_eu_target_year + + +def reindex_time_series(df, year): + """Reindex a time series given for 2017 by another year + + Parameters + ---------- + df: pd.DataFrame + original DataFrame + + year: int + The year for reindexing + + Returns + ------- + df: pd.DataFrame + the manipulated DataFrame + """ + df.index = pd.DatetimeIndex(df.index) + df.index.freq = 'H' + date_diff = (df.index[0] + - pd.Timestamp("2017-01-01 00:00:00", + tz=df.index.tz)) + ts_start = (pd.Timestamp(str(year) + "-01-01 00:00:00", + tz=df.index.tz) + + date_diff) + # account for leap years + if ts_start.month == 12: + ts_start = ts_start + pd.Timedelta("1 days") + new_index = pd.date_range(start=ts_start, + periods=df.shape[0], + freq=df.index.freq) + df.index = new_index + + return df diff --git a/pommesdata/data_preparation.ipynb b/pommesdata/data_preparation.ipynb index a9d8617..a1c63d9 100644 --- a/pommesdata/data_preparation.ipynb +++ b/pommesdata/data_preparation.ipynb @@ -15,9 +15,9 @@ "* renewable generators (Sources / Transformers)\n", "* power demand (Sinks)\n", "\n", - "Two separate data sets are created:\n", - "* one containing the power plant status as of 2017 with an update for 2019 and\n", - "* one containing an estimated exogeneously determined power plant status for 2030.\n", + "A data sets for any year between 2017 and 2030 can be created.\n", + "* For future years, power plant commissionings and decommissionings are taken into account and RES are expanded by a given pathway.\n", + "* Note that so far, we have included **time series information only for 2017**. For any other year, 2017 time series are used and simply reindex. To have a comparable simulation year with 8760 hours, for leap years, the last day is simply neglected.\n", "\n", "> **Outline:** The correspondend elements, named components, used in the framework [oemof.solph](https://github.com/oemof/oemof-solph) determine the outline of the given notebook.\n", "> _NOTE: It is recommended to run the notebook sequentially since variables declared earlier may be needed later on, even in later sections._\n", @@ -1982,6 +1982,7 @@ "min_load_ts.index= pd.date_range(start='2017-01-01 00:00:00', end='2017-12-31 23:00:00', freq='H')\n", "\n", "min_load_ts = min_load_ts.round(4)\n", + "min_load_ts = tools.reindex_time_series(min_load_ts, year)\n", "min_load_ts.to_csv(\n", " main_path[\"outputs\"] + output_file[\"transformers_minload_ts\"] + \"_\" + str(year) + \".csv\"\n", ")\n", @@ -2533,6 +2534,8 @@ "\n", " NTC_actual[connector] = actual_capacity\n", " \n", + "NTC_actual = tools.reindex_time_series(NTC_actual, year)\n", + "\n", "NTC_actual.to_csv(\n", " main_path[\"outputs\"] + output_file[\"linking_transformers_ts\"] + \"_\" + str(year) + \".csv\"\n", ") \n", @@ -3152,9 +3155,9 @@ "GHG_df = GHG_df.mul(1e6)\n", "\n", "GHG_df.to_csv(\n", - " main_path[\"outputs\"] + output_file[\"emission_limits\"] + \"_\" + str(year) + \".csv\"\n", + " main_path[\"outputs\"] + output_file[\"emission_limits\"] + \".csv\"\n", ")\n", - "GHG_df.to_excel(writer, sheet_name='emission_limits' + \"_\" + str(year))" + "GHG_df.to_excel(writer, sheet_name='emission_limits')" ] }, { @@ -3534,6 +3537,7 @@ " year=2017\n", ")\n", "\n", + "market_values_ts = tools.reindex_time_series(market_values_ts, year)\n", "market_values_ts.to_csv(\n", " main_path[\"outputs\"] + output_file[\"costs_market_values\"] + \"_\" + str(year) + \".csv\"\n", ")" @@ -3960,6 +3964,9 @@ "sources_RES.to_csv(\n", " main_path[\"outputs\"] + output_file[\"sources_renewables\"] + \"_\" + str(year) + \".csv\"\n", ")\n", + "\n", + "sources_ts_res = tools.reindex_time_series(sources_ts_res, year)\n", + "\n", "sources_ts_res.to_csv(\n", " main_path[\"outputs\"] + output_file[\"sources_renewables_ts\"] + \"_\" + str(year) + \".csv\"\n", ")\n", @@ -4911,6 +4918,7 @@ "\n", "# interpolate NaN values (Czech and France)\n", "sinks_demand_el_ts = sinks_demand_el_ts.interpolate(method='linear')\n", + "sinks_demand_el_ts = tools.reindex_time_series(sinks_demand_el_ts, year)\n", "\n", "sinks_demand_el.to_csv(\n", " main_path[\"outputs\"] + output_file[\"sinks_demand_el\"] + \"_\" + str(year) + \".csv\"\n", @@ -5177,7 +5185,7 @@ "height": "calc(100% - 180px)", "left": "10px", "top": "150px", - "width": "396.533px" + "width": "677.533px" }, "toc_section_display": true, "toc_window_display": true @@ -5208,9 +5216,9 @@ "oldHeight": 923.85, "position": { "height": "945.85px", - "left": "1897px", + "left": "1887px", "right": "20px", - "top": "149px", + "top": "136px", "width": "583px" }, "types_to_exclude": [ From 6d4afdba98ba00754284000bd7029a62b8ac3e0b Mon Sep 17 00:00:00 2001 From: Johannes Kochems Date: Tue, 12 Oct 2021 10:52:40 +0200 Subject: [PATCH 2/2] Make costs files dependent on years (nuclear / coal phase outs) --- pommesdata/data_preparation.ipynb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pommesdata/data_preparation.ipynb b/pommesdata/data_preparation.ipynb index a1c63d9..9953c60 100644 --- a/pommesdata/data_preparation.ipynb +++ b/pommesdata/data_preparation.ipynb @@ -196,7 +196,7 @@ "metadata": {}, "outputs": [], "source": [ - "year = 2030 # between 2017 and 2030 \n", + "year = 2017 # between 2017 and 2030 \n", "shutdown_assumption = 2022 # between 2017 and 2030\n", "eeg_clusters_per_technology = 20\n", "res_capacity_projection = \"Prognos\" # \"EEG_2021\"\n", @@ -4849,7 +4849,7 @@ "\n", "costs_carbon = pd.DataFrame(index=sources_commodity.index, columns=range(2015,2050), data=5.8)\n", "costs_carbon.to_csv(\n", - " main_path[\"outputs\"] + output_file[\"costs_carbon\"] + \".csv\"\n", + " main_path[\"outputs\"] + output_file[\"costs_carbon\"] + \"_\" + str(year) + \".csv\"\n", ")" ] }, @@ -5071,7 +5071,7 @@ "costs_opex = costs_opex.round(2).astype(np.float32)\n", "\n", "costs_opex.to_csv(\n", - " main_path[\"outputs\"] + output_file[\"costs_operation\"] + \".csv\"\n", + " main_path[\"outputs\"] + output_file[\"costs_operation\"] + \"_\" + str(year) + \".csv\"\n", ")" ] }, @@ -5095,7 +5095,7 @@ " pd.DataFrame(index=ee_agg['from'].unique(), columns=range(2015,2051), data=0)])\n", "\n", "costs_ramping.to_csv(\n", - " main_path[\"outputs\"] + output_file[\"costs_ramping\"] + \".csv\"\n", + " main_path[\"outputs\"] + output_file[\"costs_ramping\"] + \"_\" + str(year) + \".csv\"\n", ")" ] }, @@ -5116,7 +5116,7 @@ "\n", "costs_fuel = costs_fuel.round(2).astype(np.float32)\n", "costs_fuel.to_csv(\n", - " main_path[\"outputs\"] + output_file[\"costs_fuel_middle\"] + \".csv\"\n", + " main_path[\"outputs\"] + output_file[\"costs_fuel_middle\"] + \"_\" + str(year) + \".csv\"\n", ")" ] }, @@ -5128,7 +5128,7 @@ "source": [ "opex_storages = pd.DataFrame(index=storages_el.index, columns=range(2015,2051), data=1)\n", "opex_storages.to_csv(\n", - " main_path[\"outputs\"] + output_file[\"costs_operation_storages\"] + \".csv\"\n", + " main_path[\"outputs\"] + output_file[\"costs_operation_storages\"] + \"_\" + str(year) + \".csv\"\n", ")" ] },