From e0210d2ee6f9d2a5ab2c1fce8c950843e930ade8 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Fri, 5 May 2023 12:02:08 +0200 Subject: [PATCH 1/2] Add test for carbon price" --- README.md | 2 +- src/osemosys2iamc/resultify.py | 23 ++++++++++++++++------- tests/test_resultify.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c9fb73d..421c4d0 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ Convert OSeMOSYS results to IAMC format It is currently necessary to install the OpenEntrance dependency as an editable installation. See [issue](https://github.com/openENTRANCE/openentrance/issues/202) - pip install git+https://github.com/osemosys/osemosys2iamc@main#egg=osemosys2iamc pip install -e git+https://github.com/openENTRANCE/openentrance.git@main#egg=openentrance + pip install git+https://github.com/osemosys/osemosys2iamc@main#egg=osemosys2iamc ## Run the package diff --git a/src/osemosys2iamc/resultify.py b/src/osemosys2iamc/resultify.py index ffc5e97..0df591a 100644 --- a/src/osemosys2iamc/resultify.py +++ b/src/osemosys2iamc/resultify.py @@ -13,8 +13,6 @@ """ import functools -from multiprocessing.sharedctypes import Value -from sqlite3 import DatabaseError import pandas as pd import pyam from openentrance import iso_mapping @@ -32,6 +30,7 @@ def read_file(filename) -> pd.DataFrame: return df + def filter_regex(df: pd.DataFrame, patterns: List[str], column: str) -> pd.DataFrame: """Generic filtering of rows based on columns that match a list of patterns @@ -41,6 +40,7 @@ def filter_regex(df: pd.DataFrame, patterns: List[str], column: str) -> pd.DataF masks = [df[column].str.match(p) for p in patterns] return pd.concat([df[mask] for mask in masks]) + def filter_fuels(df: pd.DataFrame, fuels: List[str]) -> pd.DataFrame: """Returns rows which match list of regex patterns in ``technologies`` @@ -53,6 +53,7 @@ def filter_fuels(df: pd.DataFrame, fuels: List[str]) -> pd.DataFrame: """ return filter_regex(df, fuels, 'FUEL') + def filter_technologies(df: pd.DataFrame, technologies: List[str]) -> pd.DataFrame: """Returns rows which match list of regex patterns in ``technologies`` @@ -65,16 +66,19 @@ def filter_technologies(df: pd.DataFrame, technologies: List[str]) -> pd.DataFra """ return filter_regex(df, technologies, 'TECHNOLOGY') + def filter_technology_fuel(df: pd.DataFrame, technologies: List, fuels: List) -> pd.DataFrame: """Return rows which match ``technologies`` and ``fuels`` """ df = filter_technologies(df, technologies) df = filter_fuels(df, fuels) - df = df.groupby(by=['REGION','YEAR'], as_index=False)["VALUE"].sum() + df = df.groupby(by=['REGION', 'YEAR'], as_index=False)["VALUE"].sum() return df[df.VALUE != 0] -def filter_emission_tech(df: pd.DataFrame, emission: List[str], technologies: Optional[List[str]]=None) -> pd.DataFrame: + +def filter_emission_tech(df: pd.DataFrame, emission: List[str], + technologies: Optional[List[str]] = None) -> pd.DataFrame: """Return annual emissions or captured emissions by one or several technologies. Parameters @@ -90,14 +94,19 @@ def filter_emission_tech(df: pd.DataFrame, emission: List[str], technologies: Op pandas.DataFrame """ - df['REGION'] = df['TECHNOLOGY'].str[:2] + # Try to extract region from technology + try: + df['REGION'] = df['TECHNOLOGY'].str[:2] + except KeyError: + # No Technology column + pass df = filter_regex(df, emission, 'EMISSION') if technologies: - # Create a list of masks, one for each row that matches the pattern listed in ``tech`` + # Create a list of masks, one for each row that matches the pattern listed in ``tech`` df = filter_technologies(df, technologies) - df = df.groupby(by=['REGION','YEAR'], as_index=False)["VALUE"].sum() + df = df.groupby(by=['REGION', 'YEAR'], as_index=False)["VALUE"].sum() return df[df.VALUE != 0] def filter_capacity(df: pd.DataFrame, technologies: List[str]) -> pd.DataFrame: diff --git a/tests/test_resultify.py b/tests/test_resultify.py index 34be3e9..44143bf 100644 --- a/tests/test_resultify.py +++ b/tests/test_resultify.py @@ -553,3 +553,34 @@ def test_price_bm(self): print(expected) pd.testing.assert_frame_equal(actual, expected) + +class TestCarbonPrice: + + def test_carbon_price(self): + """ + VALUE,constraint,REGION,EMISSION,YEAR + -0.011043939576413982,Constr E8_AnnualEmissionsLimit,REGION1,CO2,2036 + -0.013899709405226217,Constr E8_AnnualEmissionsLimit,REGION1,CO2,2037 + -0.014572746545426708,Constr E8_AnnualEmissionsLimit,REGION1,CO2,2038 + -0.011609757344217923,Constr E8_AnnualEmissionsLimit,REGION1,CO2,2039 + 0.0,Constr E8_AnnualEmissionsLimit,REGION1,UKWO,2060 + """ + + filepath = os.path.join("tests","fixtures","carbonprice.csv") + input_data = pd.read_csv(filepath) + emission = ['CO2'] + actual = filter_emission_tech(input_data, emission) + + data = [ + ['REGION1',2036,-0.011043939576413982], + ['REGION1',2037,-0.013899709405226217], + ['REGION1',2038,-0.014572746545426708], + ['REGION1',2039,-0.011609757344217923], + ] + + expected = pd.DataFrame(data=data, columns=["REGION", "YEAR", "VALUE"]) + + print(actual) + print(expected) + + pd.testing.assert_frame_equal(actual, expected) \ No newline at end of file From 6d535a9f77b3d27c3e08c4b8f6cd5d61f4e59e74 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Fri, 5 May 2023 13:52:10 +0200 Subject: [PATCH 2/2] Added fixture for carbonprice --- tests/fixtures/carbonprice.csv | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/fixtures/carbonprice.csv diff --git a/tests/fixtures/carbonprice.csv b/tests/fixtures/carbonprice.csv new file mode 100644 index 0000000..a54192f --- /dev/null +++ b/tests/fixtures/carbonprice.csv @@ -0,0 +1,6 @@ +VALUE,constraint,REGION,EMISSION,YEAR +-0.011043939576413982,Constr E8_AnnualEmissionsLimit,REGION1,CO2,2036 +-0.013899709405226217,Constr E8_AnnualEmissionsLimit,REGION1,CO2,2037 +-0.014572746545426708,Constr E8_AnnualEmissionsLimit,REGION1,CO2,2038 +-0.011609757344217923,Constr E8_AnnualEmissionsLimit,REGION1,CO2,2039 +0.0,Constr E8_AnnualEmissionsLimit,REGION1,UKWO,2060 \ No newline at end of file