From dd928672d705fd38f14616852127a6019e6be66b Mon Sep 17 00:00:00 2001 From: "Felix C. A. Auer" <10127354+FelixCAAuer@users.noreply.github.com> Date: Mon, 19 May 2025 16:52:13 +0200 Subject: [PATCH 1/8] Introduce Global_Scenarios Re-order changelog-LEGOExcels --- ExcelReader.py | 21 ++++ ExcelWriter.py | 10 ++ TableDefinitions.xml | 26 ++++ changelog-LEGOExcels.md | 217 ++++++++++++++++----------------- examples/Global_Scenarios.xlsx | Bin 0 -> 7293 bytes 5 files changed, 165 insertions(+), 109 deletions(-) create mode 100644 examples/Global_Scenarios.xlsx diff --git a/ExcelReader.py b/ExcelReader.py index 70f7e73..400d020 100644 --- a/ExcelReader.py +++ b/ExcelReader.py @@ -57,6 +57,27 @@ def __read_pivoted_file(excel_file_path: str, version_specifier: str, indices: l return df +def get_dGlobal_Scenarios(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: + """ + Read the dGlobal_Scenarios data from the Excel file. + :param excel_file_path: Path to the Excel file + :param keep_excluded_entries: Unused but kept for compatibility with other functions + :param do_not_convert_values: Unused but kept for compatibility with other functions + :return: dGlobal_Scenarios + """ + dGlobal_Scenarios = __read_non_pivoted_file(excel_file_path, "v0.1.0", ["scenarioID"], True, keep_excluded_entries) + + if do_not_convert_values: + printer.warning("'do_not_convert_values' is set for 'get_dGlobal_Scenarios', although no values are converted anyway - please check if this is intended.") + + # Check that there is only one sheet with the name 'Scenario' + check = dGlobal_Scenarios["scenario"].to_numpy() + if not (check[0] == check).all(): + raise ValueError(f"There are multiple or falsely named sheets for '{excel_file_path}'. There should only be one sheet with the name 'Scenario', please check the Excel file.") + + return dGlobal_Scenarios + + def get_dPower_Hindex(excel_file_path: str, keep_excluded_entries: bool = False, do_not_convert_values: bool = False) -> pd.DataFrame: """ Read the dPower_Hindex data from the Excel file. diff --git a/ExcelWriter.py b/ExcelWriter.py index 0d5e38f..495357b 100644 --- a/ExcelWriter.py +++ b/ExcelWriter.py @@ -193,6 +193,15 @@ def _write_Excel_from_definition(self, data: pd.DataFrame, folder_path: str, exc wb.save(path) printer.information(f"Saved Excel file to '{path}' after {time.time() - start_time:.2f} seconds") + def write_dGlobal_Scenarios(self, dGlobal_Scenarios: pd.DataFrame, folder_path: str) -> None: + """ + Write the dGlobal_Scenarios DataFrame to an Excel file in LEGO format. + :param dGlobal_Scenarios: DataFrame containing the dGlobal_Scenarios data. + :param folder_path: Path to the folder where the Excel file will be saved. + :return: None + """ + self._write_Excel_from_definition(dGlobal_Scenarios, folder_path, "Global_Scenarios") + def write_dPower_Hindex(self, dPower_Hindex: pd.DataFrame, folder_path: str) -> None: """ Write the dPower_Hindex DataFrame to an Excel file in LEGO format. @@ -316,6 +325,7 @@ def write_dData_Packages(self, dData_Packages: pd.DataFrame, folder_path: str) - printer.separator() combinations = [ + ("Global_Scenarios", f"{args.caseStudyFolder}Global_Scenarios.xlsx", ExcelReader.get_dGlobal_Scenarios, ew.write_dGlobal_Scenarios), ("Power_Hindex", f"{args.caseStudyFolder}Power_Hindex.xlsx", ExcelReader.get_dPower_Hindex, ew.write_dPower_Hindex), ("Power_WeightsRP", f"{args.caseStudyFolder}Power_WeightsRP.xlsx", ExcelReader.get_dPower_WeightsRP, ew.write_dPower_WeightsRP), ("Power_WeightsK", f"{args.caseStudyFolder}Power_WeightsK.xlsx", ExcelReader.get_dPower_WeightsK, ew.write_dPower_WeightsK), diff --git a/TableDefinitions.xml b/TableDefinitions.xml index 800d4de..5497860 100644 --- a/TableDefinitions.xml +++ b/TableDefinitions.xml @@ -1,6 +1,18 @@ + + v0.1.0 + Global - Scenarios and Probabilities + 30.0 + + + + + + + + v0.1.2 Power - Relation among periods and representative periods @@ -598,6 +610,13 @@ 16.86 rightFloat1 + + Relative Weight + Relative weight of scenario (gets calculated relatively to all other scenarios) + [float] + 15.0 + rightFloat2 + rp Representative period @@ -605,6 +624,13 @@ 15.0 general + + Scenario ID + Scenario name + [scenario] + 41.0 + general + Source(s) List of used sources (detailing which values are from where) diff --git a/changelog-LEGOExcels.md b/changelog-LEGOExcels.md index d6c711f..8902bae 100644 --- a/changelog-LEGOExcels.md +++ b/changelog-LEGOExcels.md @@ -1,3 +1,9 @@ +# Global_Scenarios + +## v0.1.0 + +Very fist version. + # Power_Hindex ## v0.1.1 → v0.1.2 @@ -51,6 +57,58 @@ Fix description for column 'k' to be more general. Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in formatting and description texts. +# Power_BusInfo + +## v0.1.1 → v0.1.2 + +Fix comment for 'excl' column, adjust column widths and fix typo in pBusMaxV. + +## v0.1.0 → v0.1.1 + +Fix readable name for 'i' column to 'Node'. + +## v0.0.4r → v0.1.0 + +Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in +formatting and description texts. + +## v0.0.4 → v0.0.4r + +| Sheet | Range | Old Value | New Value | Description | +|-----------|-------|-------------|-------------|------------------------------| +| ScenarioA | | 'scenarioA' | 'ScenarioA' | Renamed Sheet At Position 1. | +| ScenarioB | | 'scenarioB' | 'ScenarioB' | Renamed Sheet At Position 2. | +| ScenarioA | A4 | 'Excl.' | 'excl' | Entered Value Changed. | +| ScenarioA | C2 | 'v0.0.4' | 'v0.0.4r' | Entered Value Changed. | +| ScenarioA | M3 | 'lat' | 'Latitude' | Entered Value Changed. | +| ScenarioA | N3 | 'lon' | 'Longitude' | Entered Value Changed. | +| ScenarioB | A4 | 'Excl.' | 'excl' | Entered Value Changed. | +| ScenarioB | C2 | 'v0.0.4' | 'v0.0.4r' | Entered Value Changed. | +| ScenarioB | M3 | 'lat' | 'Latitude' | Entered Value Changed. | +| ScenarioB | N3 | 'lon' | 'Longitude' | Entered Value Changed. | + +## v0.0.3r → v0.0.4 + +| Sheet | Range | Old Value | New Value | Description | +|-----------|-------|-------------|-------------|------------------------| +| scenarioA | C2 | 'v0.0.3r' | 'v0.0.4' | Entered Value Changed. | +| scenarioA | K4 | 'comYear' | 'YearCom' | Entered Value Changed. | +| scenarioA | L4 | 'decomYear' | 'YearDecom' | Entered Value Changed. | +| scenarioB | C2 | 'v0.0.3r' | 'v0.0.4' | Entered Value Changed. | +| scenarioB | K4 | 'comYear' | 'YearCom' | Entered Value Changed. | +| scenarioB | L4 | 'decomYear' | 'YearDecom' | Entered Value Changed. | + +## v0.0.2r → v0.0.3r + +| Sheet | Range | Old Value | New Value | Description | +|---------------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------| +| Power_BusInfo | A4 | '' | 'Excl.' | Entered Value Added. | +| Power_BusInfo | C2 | 'v0.0.2r' | 'v0.0.3r' | Entered Value Changed. | +| Power_BusInfo | O5 | 'Whether node is relevant for end result' | 'Whether node is relevant for end result (1) or not (0)' | Entered Value Changed. | +| Power_BusInfo | O7 | '[Yes, No]' | '[0, 1]' | Entered Value Changed. | +| Power_BusInfo | O8 (and others) | 'Yes' | '1' | Entered Value Changed. | +| Power_BusInfo | A4 | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [A=255, R=216, G=216, B=216], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | + # Power_Network ## v0.1.0 → v0.1.1 @@ -110,76 +168,6 @@ formatting and description texts. | Power_Network | L8 (and others) | 'No' | '0' | Entered Value Changed. | | Power_Network | A4 | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [A=255, R=216, G=216, B=216], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | -# Power_VRES - -## v0.0.4r → v0.1.0 - -Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in -formatting and description texts. - -## v0.0.4 → v0.0.4r - -| Sheet | Range | Old Value | New Value | Description | -|-----------|-------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------| -| ScenarioA | A4 | 'Excl.' | 'excl' | Entered Value Changed. | -| ScenarioA | C2 | 'v0.0.3r' | 'v0.0.4r' | Entered Value Changed. | -| ScenarioA | F2 | 'v0.0.4' | '' | Entered Value Deleted. | -| ScenarioA | P3 | 'YearCom' | 'Commision Year' | Entered Value Changed. | -| ScenarioA | Q3 | 'YearDecom' | 'Decommision Year' | Entered Value Changed. | -| ScenarioA | R3 | 'lat' | 'Latitude' | Entered Value Changed. | -| ScenarioA | S3 | 'lon' | 'Longitude' | Entered Value Changed. | -| ScenarioB | A4 | 'Excl.' | 'excl' | Entered Value Changed. | -| ScenarioB | C2 | 'v0.0.4' | 'v0.0.4r' | Entered Value Changed. | -| ScenarioB | P3 | 'YearCom' | 'Commision Year' | Entered Value Changed. | -| ScenarioB | Q3 | 'YearDecom' | 'Decommision Year' | Entered Value Changed. | -| ScenarioB | R3 | 'lat' | 'Latitude' | Entered Value Changed. | -| ScenarioB | S3 | 'lon' | 'Longitude' | Entered Value Changed. | -| ScenarioB | F2 | 'Background color: Color [Window], Foreground color: Color [A=255, R=51, G=102, B=255], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | - -## v0.0.3r → v0.0.4 - -| Sheet | Range | Old Value | New Value | Description | -|-----------|-------|-----------|-----------|------------------------| -| ScenarioA | F2 | '' | 'v0.0.4' | Entered Value Added. | -| ScenarioA | S3 | 'long' | 'lon' | Entered Value Changed. | -| ScenarioA | S4 | 'long' | 'lon' | Entered Value Changed. | -| ScenarioB | C2 | 'v0.0.3r' | 'v0.0.4' | Entered Value Changed. | -| ScenarioB | S3 | 'long' | 'lon' | Entered Value Changed. | -| ScenarioB | S4 | 'long' | 'lon' | Entered Value Changed. | - -## v0.0.2r → v0.0.3r - -| Sheet | Range | Old Value | New Value | Description | -|------------|-------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------| -| Power_VRES | A4 | '' | 'Excl.' | Entered Value Added. | -| Power_VRES | A9 | '' | 'x' | Entered Value Added. | -| Power_VRES | C2 | 'v0.0.2r' | 'v0.0.3r' | Entered Value Changed. | -| Power_VRES | C10 | 'Solar' | 'PV Schafflerhofstraße' | Entered Value Changed. | -| Power_VRES | C11 | 'Solar2' | 'PV OMV-Schoenkirchen' | Entered Value Changed. | -| Power_VRES | | | | Renamed some plants & added a new one, but that's not relevant for formatting! | -| Power_VRES | F4 | '' | 'ExisUnits' | Entered Value Added. | -| Power_VRES | G4 | '' | 'MaxProd' | Entered Value Added. | -| Power_VRES | H4 | '' | 'EnableInvest' | Entered Value Added. | -| Power_VRES | I4 | '' | 'MaxInvest' | Entered Value Added. | -| Power_VRES | J4 | '' | 'InvestCost' | Entered Value Added. | -| Power_VRES | K4 | '' | 'OMVarCost' | Entered Value Added. | -| Power_VRES | L4 | '' | 'FirmCapCoef' | Entered Value Added. | -| Power_VRES | M4 | '' | 'Qmax' | Entered Value Added. | -| Power_VRES | N4 | '' | 'Qmin' | Entered Value Added. | -| Power_VRES | O4 | '' | 'InertiaConst' | Entered Value Added. | -| Power_VRES | P4 | '' | 'YearCom' | Entered Value Added. | -| Power_VRES | Q4 | '' | 'YearDecom' | Entered Value Added. | -| Power_VRES | R4 | '' | 'lat' | Entered Value Added. | -| Power_VRES | S4 | '' | 'long' | Entered Value Added. | -| Power_VRES | A4 | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [A=255, R=216, G=216, B=216], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | - -# Power_VRESProfiles - -## v0.0.3 → v0.1.0 - -Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in -formatting and description texts. - # Power_ThermalGen ## v0.1.0 → v0.1.1 @@ -255,15 +243,7 @@ formatting and description texts. | Power_ThermalGen | A4 | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [A=255, R=216, G=216, B=216], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | | Power_ThermalGen | A4 | '' | 'Excl.' | Entered Value Added. | -# Power_BusInfo - -## v0.1.1 → v0.1.2 - -Fix comment for 'excl' column, adjust column widths and fix typo in pBusMaxV. - -## v0.1.0 → v0.1.1 - -Fix readable name for 'i' column to 'Node'. +# Power_VRES ## v0.0.4r → v0.1.0 @@ -272,44 +252,63 @@ formatting and description texts. ## v0.0.4 → v0.0.4r -| Sheet | Range | Old Value | New Value | Description | -|-----------|-------|-------------|-------------|------------------------------| -| ScenarioA | | 'scenarioA' | 'ScenarioA' | Renamed Sheet At Position 1. | -| ScenarioB | | 'scenarioB' | 'ScenarioB' | Renamed Sheet At Position 2. | -| ScenarioA | A4 | 'Excl.' | 'excl' | Entered Value Changed. | -| ScenarioA | C2 | 'v0.0.4' | 'v0.0.4r' | Entered Value Changed. | -| ScenarioA | M3 | 'lat' | 'Latitude' | Entered Value Changed. | -| ScenarioA | N3 | 'lon' | 'Longitude' | Entered Value Changed. | -| ScenarioB | A4 | 'Excl.' | 'excl' | Entered Value Changed. | -| ScenarioB | C2 | 'v0.0.4' | 'v0.0.4r' | Entered Value Changed. | -| ScenarioB | M3 | 'lat' | 'Latitude' | Entered Value Changed. | -| ScenarioB | N3 | 'lon' | 'Longitude' | Entered Value Changed. | +| Sheet | Range | Old Value | New Value | Description | +|-----------|-------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------| +| ScenarioA | A4 | 'Excl.' | 'excl' | Entered Value Changed. | +| ScenarioA | C2 | 'v0.0.3r' | 'v0.0.4r' | Entered Value Changed. | +| ScenarioA | F2 | 'v0.0.4' | '' | Entered Value Deleted. | +| ScenarioA | P3 | 'YearCom' | 'Commision Year' | Entered Value Changed. | +| ScenarioA | Q3 | 'YearDecom' | 'Decommision Year' | Entered Value Changed. | +| ScenarioA | R3 | 'lat' | 'Latitude' | Entered Value Changed. | +| ScenarioA | S3 | 'lon' | 'Longitude' | Entered Value Changed. | +| ScenarioB | A4 | 'Excl.' | 'excl' | Entered Value Changed. | +| ScenarioB | C2 | 'v0.0.4' | 'v0.0.4r' | Entered Value Changed. | +| ScenarioB | P3 | 'YearCom' | 'Commision Year' | Entered Value Changed. | +| ScenarioB | Q3 | 'YearDecom' | 'Decommision Year' | Entered Value Changed. | +| ScenarioB | R3 | 'lat' | 'Latitude' | Entered Value Changed. | +| ScenarioB | S3 | 'lon' | 'Longitude' | Entered Value Changed. | +| ScenarioB | F2 | 'Background color: Color [Window], Foreground color: Color [A=255, R=51, G=102, B=255], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | ## v0.0.3r → v0.0.4 -| Sheet | Range | Old Value | New Value | Description | -|-----------|-------|-------------|-------------|------------------------| -| scenarioA | C2 | 'v0.0.3r' | 'v0.0.4' | Entered Value Changed. | -| scenarioA | K4 | 'comYear' | 'YearCom' | Entered Value Changed. | -| scenarioA | L4 | 'decomYear' | 'YearDecom' | Entered Value Changed. | -| scenarioB | C2 | 'v0.0.3r' | 'v0.0.4' | Entered Value Changed. | -| scenarioB | K4 | 'comYear' | 'YearCom' | Entered Value Changed. | -| scenarioB | L4 | 'decomYear' | 'YearDecom' | Entered Value Changed. | +| Sheet | Range | Old Value | New Value | Description | +|-----------|-------|-----------|-----------|------------------------| +| ScenarioA | F2 | '' | 'v0.0.4' | Entered Value Added. | +| ScenarioA | S3 | 'long' | 'lon' | Entered Value Changed. | +| ScenarioA | S4 | 'long' | 'lon' | Entered Value Changed. | +| ScenarioB | C2 | 'v0.0.3r' | 'v0.0.4' | Entered Value Changed. | +| ScenarioB | S3 | 'long' | 'lon' | Entered Value Changed. | +| ScenarioB | S4 | 'long' | 'lon' | Entered Value Changed. | ## v0.0.2r → v0.0.3r -| Sheet | Range | Old Value | New Value | Description | -|---------------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------| -| Power_BusInfo | A4 | '' | 'Excl.' | Entered Value Added. | -| Power_BusInfo | C2 | 'v0.0.2r' | 'v0.0.3r' | Entered Value Changed. | -| Power_BusInfo | O5 | 'Whether node is relevant for end result' | 'Whether node is relevant for end result (1) or not (0)' | Entered Value Changed. | -| Power_BusInfo | O7 | '[Yes, No]' | '[0, 1]' | Entered Value Changed. | -| Power_BusInfo | O8 (and others) | 'Yes' | '1' | Entered Value Changed. | -| Power_BusInfo | A4 | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [A=255, R=216, G=216, B=216], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | +| Sheet | Range | Old Value | New Value | Description | +|------------|-------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------| +| Power_VRES | A4 | '' | 'Excl.' | Entered Value Added. | +| Power_VRES | A9 | '' | 'x' | Entered Value Added. | +| Power_VRES | C2 | 'v0.0.2r' | 'v0.0.3r' | Entered Value Changed. | +| Power_VRES | C10 | 'Solar' | 'PV Schafflerhofstraße' | Entered Value Changed. | +| Power_VRES | C11 | 'Solar2' | 'PV OMV-Schoenkirchen' | Entered Value Changed. | +| Power_VRES | | | | Renamed some plants & added a new one, but that's not relevant for formatting! | +| Power_VRES | F4 | '' | 'ExisUnits' | Entered Value Added. | +| Power_VRES | G4 | '' | 'MaxProd' | Entered Value Added. | +| Power_VRES | H4 | '' | 'EnableInvest' | Entered Value Added. | +| Power_VRES | I4 | '' | 'MaxInvest' | Entered Value Added. | +| Power_VRES | J4 | '' | 'InvestCost' | Entered Value Added. | +| Power_VRES | K4 | '' | 'OMVarCost' | Entered Value Added. | +| Power_VRES | L4 | '' | 'FirmCapCoef' | Entered Value Added. | +| Power_VRES | M4 | '' | 'Qmax' | Entered Value Added. | +| Power_VRES | N4 | '' | 'Qmin' | Entered Value Added. | +| Power_VRES | O4 | '' | 'InertiaConst' | Entered Value Added. | +| Power_VRES | P4 | '' | 'YearCom' | Entered Value Added. | +| Power_VRES | Q4 | '' | 'YearDecom' | Entered Value Added. | +| Power_VRES | R4 | '' | 'lat' | Entered Value Added. | +| Power_VRES | S4 | '' | 'long' | Entered Value Added. | +| Power_VRES | A4 | 'Background color: Color [Window], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | 'Background color: Color [A=255, R=216, G=216, B=216], Foreground color: Color [WindowText], Font: [Font: Name=Microsoft Sans Serif, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False], Format code: ' | Cell Formatting Changed | -# Power_BusInfo +# Power_VRESProfiles -## v0.0.2 → v0.1.0 +## v0.0.3 → v0.1.0 Switching to "scripted" method when writing Excel-File (instead of copying from template), thus slight changes in formatting and description texts. diff --git a/examples/Global_Scenarios.xlsx b/examples/Global_Scenarios.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..557e4e03eba04caac0a66bf7085ac2768ea1238d GIT binary patch literal 7293 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 P0ejNIGG{50pR4}^b!M#& literal 0 HcmV?d00001 From 868714ff0a71887906b943a0594d88a784478895 Mon Sep 17 00:00:00 2001 From: "Felix C. A. Auer" <10127354+FelixCAAuer@users.noreply.github.com> Date: Tue, 20 May 2025 16:27:34 +0200 Subject: [PATCH 2/8] Implement scenario filtering for CaseStudy --- CaseStudy.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/CaseStudy.py b/CaseStudy.py index 8162dde..6f09554 100644 --- a/CaseStudy.py +++ b/CaseStudy.py @@ -1,6 +1,6 @@ import copy import warnings -from typing import Optional +from typing import Optional, Self import numpy as np import pandas as pd @@ -515,3 +515,36 @@ def to_full_hourly_model(self, inplace: bool) -> Optional['CaseStudy']: return caseStudy else: return None + + def filter_scenario(self, scenario_name) -> Self: + """ + Filters each (relevant) dataframe in the case study to only include the scenario with the given name. + :param scenario_name: The name of the scenario to filter for. + :return: Copy of the case study with the filtered dataframes. + """ + caseStudy = self.copy() + + # dGlobal_Parameters is not filtered, as it is the same for all scenarios + # dPower_Parameters is not filtered, as it is the same for all scenarios + caseStudy.dPower_BusInfo = caseStudy.dPower_BusInfo.loc[scenario_name] + caseStudy.dPower_Network = caseStudy.dPower_Network.loc[scenario_name] + caseStudy.dPower_Demand = caseStudy.dPower_Demand.loc[scenario_name] + caseStudy.dPower_WeightsRP = caseStudy.dPower_WeightsRP.loc[scenario_name] + caseStudy.dPower_WeightsK = caseStudy.dPower_WeightsK.loc[scenario_name] + caseStudy.dPower_Hindex = caseStudy.dPower_Hindex.loc[scenario_name] + if hasattr(caseStudy, "dPower_ThermalGen"): + caseStudy.dPower_ThermalGen = caseStudy.dPower_ThermalGen.loc[scenario_name] + if hasattr(caseStudy, "dPower_RoR"): + caseStudy.dPower_RoR = caseStudy.dPower_RoR.loc[scenario_name] + if hasattr(caseStudy, "dPower_VRES"): + caseStudy.dPower_VRES = caseStudy.dPower_VRES.loc[scenario_name] + caseStudy.dPower_VRESProfiles = caseStudy.dPower_VRESProfiles.loc[scenario_name] + if hasattr(caseStudy, "dPower_Storage"): + caseStudy.dPower_Storage = caseStudy.dPower_Storage.loc[scenario_name] + if hasattr(caseStudy, "dPower_ImpExpHubs"): + caseStudy.dPower_ImpExpHubs = caseStudy.dPower_ImpExpHubs.loc[scenario_name] + caseStudy.dPower_ImpExpProfiles = caseStudy.dPower_ImpExpProfiles.loc[scenario_name] + if hasattr(caseStudy, "dPower_Inflows"): + caseStudy.dPower_Inflows = caseStudy.dPower_Inflows.loc[scenario_name] + + return caseStudy From bd1dbd86e2e740443a88ea5f3e8ac3f9cc76cf49 Mon Sep 17 00:00:00 2001 From: "Felix C. A. Auer" <10127354+FelixCAAuer@users.noreply.github.com> Date: Wed, 21 May 2025 11:09:09 +0200 Subject: [PATCH 3/8] Add dGlobal_Scenarios to CaseStudy and simplify filtering of dataframes Add temporary fixes for RoR & Inflows regarding scenarios --- CaseStudy.py | 63 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/CaseStudy.py b/CaseStudy.py index 6f09554..178c26f 100644 --- a/CaseStudy.py +++ b/CaseStudy.py @@ -12,6 +12,7 @@ class CaseStudy: def __init__(self, example_folder: str, do_not_merge_single_node_buses: bool = False, global_parameters_file: str = "Global_Parameters.xlsx", dGlobal_Parameters: pd.DataFrame = None, + global_scenarios_file: str = "Global_Scenarios.xlsx", dGlobal_Scenarios: pd.DataFrame = None, power_parameters_file: str = "Power_Parameters.xlsx", dPower_Parameters: pd.DataFrame = None, power_businfo_file: str = "Power_BusInfo.xlsx", dPower_BusInfo: pd.DataFrame = None, power_network_file: str = "Power_Network.xlsx", dPower_Network: pd.DataFrame = None, @@ -36,6 +37,12 @@ def __init__(self, example_folder: str, do_not_merge_single_node_buses: bool = F self.global_parameters_file = global_parameters_file self.dGlobal_Parameters = self.get_dGlobal_Parameters() + if dGlobal_Scenarios is not None: + self.dGlobal_Scenarios = dGlobal_Scenarios + else: + self.global_scenarios_file = global_scenarios_file + self.dGlobal_Scenarios = ExcelReader.get_dGlobal_Scenarios(self.example_folder + self.global_scenarios_file) + if dPower_Parameters is not None: self.dPower_Parameters = dPower_Parameters else: @@ -190,6 +197,8 @@ def get_dPower_RoR(self): dPower_RoR['InvestCostEUR'] = dPower_RoR['MaxProd'] * 1e-3 * (dPower_RoR['InvestCostPerMW'] * 1e-3 + dPower_RoR['InvestCostPerMWh'] * 1e-3 * dPower_RoR['Ene2PowRatio']) dPower_RoR['MaxProd'] *= 1e-3 + + dPower_RoR['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated return dPower_RoR def get_dPower_Storage(self): @@ -209,6 +218,8 @@ def get_dPower_Inflows(self): dPower_Inflows = dPower_Inflows.rename(columns={dPower_Inflows.columns[0]: "rp", dPower_Inflows.columns[1]: "g"}) dPower_Inflows = dPower_Inflows.melt(id_vars=['rp', 'g'], var_name='k', value_name='Inflow') dPower_Inflows = dPower_Inflows.set_index(['rp', 'g', 'k']) + + dPower_Inflows['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated return dPower_Inflows def get_dPower_ImpExpHubs(self): @@ -516,6 +527,24 @@ def to_full_hourly_model(self, inplace: bool) -> Optional['CaseStudy']: else: return None + def _filter_dataframe(self, df_name: str, scenario_name: str) -> None: + """ + Filters the dataframe with the given name to only include the scenario with the given name. + :param df_name: The name of the dataframe to filter. + :param scenario_name: The name of the scenario to filter for. + :return: None + """ + if not hasattr(self, df_name): + raise ValueError(f"Dataframe '{df_name}' not found in the case study. Please check the input data.") + df = getattr(self, df_name) + + filtered_df = df.loc[df['scenario'] == scenario_name] + + if len(df) >= 0 and len(filtered_df) == 0: + raise ValueError(f"Scenario '{scenario_name}' not found in '{df_name}'. Please check the input data.") + + setattr(self, df_name, filtered_df) + def filter_scenario(self, scenario_name) -> Self: """ Filters each (relevant) dataframe in the case study to only include the scenario with the given name. @@ -526,25 +555,25 @@ def filter_scenario(self, scenario_name) -> Self: # dGlobal_Parameters is not filtered, as it is the same for all scenarios # dPower_Parameters is not filtered, as it is the same for all scenarios - caseStudy.dPower_BusInfo = caseStudy.dPower_BusInfo.loc[scenario_name] - caseStudy.dPower_Network = caseStudy.dPower_Network.loc[scenario_name] - caseStudy.dPower_Demand = caseStudy.dPower_Demand.loc[scenario_name] - caseStudy.dPower_WeightsRP = caseStudy.dPower_WeightsRP.loc[scenario_name] - caseStudy.dPower_WeightsK = caseStudy.dPower_WeightsK.loc[scenario_name] - caseStudy.dPower_Hindex = caseStudy.dPower_Hindex.loc[scenario_name] + caseStudy._filter_dataframe("dPower_BusInfo", scenario_name) + caseStudy._filter_dataframe("dPower_Network", scenario_name) + caseStudy._filter_dataframe("dPower_Demand", scenario_name) + caseStudy._filter_dataframe("dPower_WeightsRP", scenario_name) + caseStudy._filter_dataframe("dPower_WeightsK", scenario_name) + caseStudy._filter_dataframe("dPower_Hindex", scenario_name) + if hasattr(caseStudy, "dPower_ThermalGen"): - caseStudy.dPower_ThermalGen = caseStudy.dPower_ThermalGen.loc[scenario_name] - if hasattr(caseStudy, "dPower_RoR"): - caseStudy.dPower_RoR = caseStudy.dPower_RoR.loc[scenario_name] + caseStudy._filter_dataframe("dPower_ThermalGen", scenario_name) + if hasattr(caseStudy, "dPower_RoR") and len(caseStudy.dPower_RoR) > 0: + caseStudy._filter_dataframe("dPower_RoR", scenario_name) + caseStudy._filter_dataframe("dPower_Inflows", scenario_name) if hasattr(caseStudy, "dPower_VRES"): - caseStudy.dPower_VRES = caseStudy.dPower_VRES.loc[scenario_name] - caseStudy.dPower_VRESProfiles = caseStudy.dPower_VRESProfiles.loc[scenario_name] + caseStudy._filter_dataframe("dPower_VRES", scenario_name) + caseStudy._filter_dataframe("dPower_VRESProfiles", scenario_name) if hasattr(caseStudy, "dPower_Storage"): - caseStudy.dPower_Storage = caseStudy.dPower_Storage.loc[scenario_name] - if hasattr(caseStudy, "dPower_ImpExpHubs"): - caseStudy.dPower_ImpExpHubs = caseStudy.dPower_ImpExpHubs.loc[scenario_name] - caseStudy.dPower_ImpExpProfiles = caseStudy.dPower_ImpExpProfiles.loc[scenario_name] - if hasattr(caseStudy, "dPower_Inflows"): - caseStudy.dPower_Inflows = caseStudy.dPower_Inflows.loc[scenario_name] + caseStudy._filter_dataframe("dPower_Storage", scenario_name) + if hasattr(caseStudy, "dPower_ImpExpHubs") and caseStudy.dPower_ImpExpHubs is not None: + caseStudy._filter_dataframe("dPower_ImpExpHubs", scenario_name) + caseStudy._filter_dataframe("dPower_ImpExpProfiles", scenario_name) return caseStudy From aa61999f202664163e0716c125b3bdb8235b8081 Mon Sep 17 00:00:00 2001 From: "Felix C. A. Auer" <10127354+FelixCAAuer@users.noreply.github.com> Date: Wed, 21 May 2025 15:46:02 +0200 Subject: [PATCH 4/8] Add temporary fixes for Storage, ImpExpHubs and ImpExpProfiles --- CaseStudy.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/CaseStudy.py b/CaseStudy.py index 178c26f..96370ea 100644 --- a/CaseStudy.py +++ b/CaseStudy.py @@ -198,7 +198,9 @@ def get_dPower_RoR(self): dPower_RoR['InvestCostEUR'] = dPower_RoR['MaxProd'] * 1e-3 * (dPower_RoR['InvestCostPerMW'] * 1e-3 + dPower_RoR['InvestCostPerMWh'] * 1e-3 * dPower_RoR['Ene2PowRatio']) dPower_RoR['MaxProd'] *= 1e-3 - dPower_RoR['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated + # If column 'scenario' is not present, add it + if 'scenario' not in dPower_RoR.columns: + dPower_RoR['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated return dPower_RoR def get_dPower_Storage(self): @@ -210,6 +212,10 @@ def get_dPower_Storage(self): dPower_Storage['InvestCostEUR'] = dPower_Storage['MaxProd'] * 1e-3 * (dPower_Storage['InvestCostPerMW'] * 1e-3 + dPower_Storage['InvestCostPerMWh'] * 1e-3 * dPower_Storage['Ene2PowRatio']) dPower_Storage['MaxProd'] *= 1e-3 dPower_Storage['MaxCons'] *= 1e-3 + + # If column 'scenario' is not present, add it + if 'scenario' not in dPower_Storage.columns: + dPower_Storage['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated return dPower_Storage def get_dPower_Inflows(self): @@ -245,6 +251,10 @@ def get_dPower_ImpExpHubs(self): dPower_ImpExpHubs["Pmax Import"] *= 1e-3 dPower_ImpExpHubs["Pmax Export"] *= 1e-3 + # If column 'scenario' is not present, add it + if 'scenario' not in dPower_ImpExpHubs.columns: + dPower_ImpExpHubs['scenario'] = 'ScenarioA' # TODO: Fill this dynamically, once the Excel file is updated + return dPower_ImpExpHubs def get_dPower_ImpExpProfiles(self): @@ -293,6 +303,10 @@ def get_dPower_ImpExpProfiles(self): error_information *= 1e3 # Convert back to input format raise ValueError(f"At least one hub has ExpFix exports which exceed the sum of Pmax of all connections. Please check: \n{error_information}\n") + # If column 'scenario' is not present, add it + if 'scenario' not in dPower_ImpExpProfiles.columns: + dPower_ImpExpProfiles['scenario'] = "ScenarioA" # TODO: Fill this dynamically, once the Excel file is updated + return dPower_ImpExpProfiles @staticmethod From 4e4f28959d5a2e5576db0c98d64fc96fb84e10a4 Mon Sep 17 00:00:00 2001 From: "Felix C. A. Auer" <10127354+FelixCAAuer@users.noreply.github.com> Date: Wed, 21 May 2025 17:28:52 +0200 Subject: [PATCH 5/8] Fix read-in of Yes/No values in Global_Parameters --- CaseStudy.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CaseStudy.py b/CaseStudy.py index 96370ea..940bfa4 100644 --- a/CaseStudy.py +++ b/CaseStudy.py @@ -154,6 +154,8 @@ def get_dGlobal_Parameters(self): dGlobal_Parameters = dGlobal_Parameters.drop(dGlobal_Parameters.columns[0], axis=1) dGlobal_Parameters = dGlobal_Parameters.set_index('Sectors') + self.yesNo_to_bool(dGlobal_Parameters, ['pEnablePower', 'pEnableGas', 'pEnableHeat', 'pEnableH2', 'pEnableRMIP']) + # Transform to make it easier to access values dGlobal_Parameters = dGlobal_Parameters.drop(dGlobal_Parameters.columns[1:], axis=1) # Drop all columns but "Value" (rest is just for information in the Excel) dGlobal_Parameters = dict({(parameter_name, parameter_value["Value"]) for parameter_name, parameter_value in dGlobal_Parameters.iterrows()}) # Transform into dictionary From b3a1f9fa1242bf697045483a57730a90c15c5adf Mon Sep 17 00:00:00 2001 From: "Felix C. A. Auer" <10127354+FelixCAAuer@users.noreply.github.com> Date: Mon, 16 Jun 2025 17:19:40 +0200 Subject: [PATCH 6/8] Implement Copilot suggestions --- CaseStudy.py | 2 +- changelog-LEGOExcels.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CaseStudy.py b/CaseStudy.py index 34670b7..8b56ff5 100644 --- a/CaseStudy.py +++ b/CaseStudy.py @@ -556,7 +556,7 @@ def _filter_dataframe(self, df_name: str, scenario_name: str) -> None: filtered_df = df.loc[df['scenario'] == scenario_name] - if len(df) >= 0 and len(filtered_df) == 0: + if len(df) > 0 and len(filtered_df) == 0: raise ValueError(f"Scenario '{scenario_name}' not found in '{df_name}'. Please check the input data.") setattr(self, df_name, filtered_df) diff --git a/changelog-LEGOExcels.md b/changelog-LEGOExcels.md index 8902bae..bbdf67c 100644 --- a/changelog-LEGOExcels.md +++ b/changelog-LEGOExcels.md @@ -2,7 +2,7 @@ ## v0.1.0 -Very fist version. +Very first version. # Power_Hindex From 00a43e2f87acbdb49ecea1747c58d2236ef8e1ba Mon Sep 17 00:00:00 2001 From: "Felix C. A. Auer" <10127354+FelixCAAuer@users.noreply.github.com> Date: Mon, 16 Jun 2025 18:39:20 +0200 Subject: [PATCH 7/8] Add Global_Scenarios to ExcelReadWrite tests --- CaseStudy.py | 2 +- tests/test_ExcelReaderWriter.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CaseStudy.py b/CaseStudy.py index 8b56ff5..835a22e 100644 --- a/CaseStudy.py +++ b/CaseStudy.py @@ -41,7 +41,7 @@ def __init__(self, data_folder: str, do_not_merge_single_node_buses: bool = Fals self.dGlobal_Scenarios = dGlobal_Scenarios else: self.global_scenarios_file = global_scenarios_file - self.dGlobal_Scenarios = ExcelReader.get_dGlobal_Scenarios(self.example_folder + self.global_scenarios_file) + self.dGlobal_Scenarios = ExcelReader.get_dGlobal_Scenarios(self.data_folder + self.global_scenarios_file) if dPower_Parameters is not None: self.dPower_Parameters = dPower_Parameters diff --git a/tests/test_ExcelReaderWriter.py b/tests/test_ExcelReaderWriter.py index e2b4a17..ff95402 100644 --- a/tests/test_ExcelReaderWriter.py +++ b/tests/test_ExcelReaderWriter.py @@ -9,6 +9,7 @@ case_study_folder = "examples/" ew = ExcelWriter() combinations = [ + ("Global_Scenarios", f"{case_study_folder}Global_Scenarios.xlsx", ExcelReader.get_dGlobal_Scenarios, ew.write_dGlobal_Scenarios), ("Power_Hindex", f"{case_study_folder}Power_Hindex.xlsx", ExcelReader.get_dPower_Hindex, ew.write_dPower_Hindex), ("Power_WeightsRP", f"{case_study_folder}Power_WeightsRP.xlsx", ExcelReader.get_dPower_WeightsRP, ew.write_dPower_WeightsRP), ("Power_WeightsK", f"{case_study_folder}Power_WeightsK.xlsx", ExcelReader.get_dPower_WeightsK, ew.write_dPower_WeightsK), From 3203c96414bb7b67886eb642f980c27a3b162cfc Mon Sep 17 00:00:00 2001 From: "Felix C. A. Auer" <10127354+FelixCAAuer@users.noreply.github.com> Date: Mon, 16 Jun 2025 18:59:17 +0200 Subject: [PATCH 8/8] Add pyproject.toml to enable installing InOutModule --- .gitignore | 5 ++++- pyproject.toml | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore index 53c0264..b2d0943 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,7 @@ examples/output ~$*.xlsx # Development environment files -.idea/ \ No newline at end of file +.idea/ + +# Files from editable installs of pip +/InOutModule.egg-info/ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a72a436 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,11 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "InOutModule" +version = "0.0.0-dev" +readme = "README.md" + +[tool.setuptools] +py-modules = ['CaseStudy', 'ExcelReader', 'ExcelWriter', 'printer', 'PypsaReader', 'pypsa_helper', 'SQLiteWriter', 'TableDefinition'] \ No newline at end of file