Run a tier sequence

This tutorial explains the core functionality of the bonsai_ipcc package. Let´s assume we want to determine the CO2 emissions from waste incineration based on the tier 1 approach. According to the IPCC guidelines, different waste fractions are available. Here we chose year 2010, Germany and waste type msw_plastics, which stands for municipal plastic waste (you can check all availbe waste types by my_ipcc.waste.incineration.dimension.waste_type) and unspecified incineration technology.

import bonsai_ipcc
my_ipcc = bonsai_ipcc.IPCC()
my_ipcc.waste.incineration.sequence.tier1_co2(year=2010, region="DE",wastetype="msw_plastics", incintype="inc_unspecified", uncertainty="def")
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
Cell In[1], line 1
----> 1 import bonsai_ipcc
      2 my_ipcc = bonsai_ipcc.IPCC()
      3 my_ipcc.waste.incineration.sequence.tier1_co2(year=2010, region="DE",wastetype="msw_plastics", incintype="inc_unspecified", uncertainty="def")

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/__init__.py:9
      6 from os.path import dirname
      7 from pathlib import Path
----> 9 from .core import IPCC, PPF
     10 from .log_setup import setup_logger
     12 # setup the default logger

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/core.py:8
      5 import pandas as pd
      6 import yaml
----> 8 from . import agriculture, industry, ppf, waste
      9 from ._metadata import MetaData  # TODO
     10 from .sample import create_sample

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/waste/__init__.py:1
----> 1 from . import biological, incineration, swd, waste_generation, wastewater

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/waste/incineration/__init__.py:1
----> 1 from . import elementary, sequence
      2 from ._data import concordance, dimension, parameter

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/waste/incineration/sequence.py:24
     22 from ..._sequence import Sequence
     23 from . import elementary as elem
---> 24 from ._data import concordance as conc
     25 from ._data import dimension as dim
     26 from ._data import parameter as par

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/waste/incineration/_data.py:3
      1 from ..._data import Concordance, Dimension, Parameter
----> 3 dimension = Dimension(path_in="data/", activitycode="incineration", productcode="waste")
      5 parameter = Parameter(["data/waste/incineration/", "data/waste/waste_generation/"])
      7 concordance = Concordance("data/")

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/_data.py:40, in Dimension.__init__(self, path_in, activitycode, productcode)
     38         df = self._filter_dataframe(df, activitycode)
     39     elif filename == "dim_product.csv":
---> 40         df = self._filter_dataframe(df, productcode)
     41     setattr(self, filename[4:-4], df)
     42 except Exception:
     43     # print(f"error reading {filename}")

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/_data.py:56, in Dimension._filter_dataframe(self, df, code)
     54         child_codes.append(index)
     55         # Recursively call the function to find child codes of this child code
---> 56         child_codes.extend(self._filter_dataframe(df, index).index.tolist())
     58 # Filter the DataFrame to include all child codes found
     59 filtered_df = df.loc[child_codes]

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/_data.py:56, in Dimension._filter_dataframe(self, df, code)
     54         child_codes.append(index)
     55         # Recursively call the function to find child codes of this child code
---> 56         child_codes.extend(self._filter_dataframe(df, index).index.tolist())
     58 # Filter the DataFrame to include all child codes found
     59 filtered_df = df.loc[child_codes]

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/_data.py:56, in Dimension._filter_dataframe(self, df, code)
     54         child_codes.append(index)
     55         # Recursively call the function to find child codes of this child code
---> 56         child_codes.extend(self._filter_dataframe(df, index).index.tolist())
     58 # Filter the DataFrame to include all child codes found
     59 filtered_df = df.loc[child_codes]

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/_data.py:51, in Dimension._filter_dataframe(self, df, code)
     48 child_codes = []
     50 # Iterate through the index of the DataFrame to find child codes
---> 51 for index, row in df.iterrows():
     52     if row["parent_code"] == code:
     53         # Add the child code to the list
     54         child_codes.append(index)

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/pandas/core/frame.py:1559, in DataFrame.iterrows(self)
   1557 using_cow = using_copy_on_write()
   1558 for k, v in zip(self.index, self.values):
-> 1559     s = klass(v, index=columns, name=k).__finalize__(self)
   1560     if using_cow and self._mgr.is_single_block:
   1561         s._mgr.add_references(self._mgr)  # type: ignore[arg-type]

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/pandas/core/series.py:584, in Series.__init__(self, data, index, dtype, name, copy, fastpath)
    582         data = data.copy()
    583 else:
--> 584     data = sanitize_array(data, index, dtype, copy)
    586     manager = _get_option("mode.data_manager", silent=True)
    587     if manager == "block":

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/pandas/core/construction.py:604, in sanitize_array(data, index, dtype, copy, allow_2d)
    602 subarr = data
    603 if data.dtype == object:
--> 604     subarr = maybe_infer_to_datetimelike(data)
    605     if object_index and using_string_dtype() and is_string_dtype(subarr):
    606         # Avoid inference when string option is set
    607         subarr = data

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/pandas/core/dtypes/cast.py:1205, in maybe_infer_to_datetimelike(value, convert_to_nullable_dtype)
   1193     return value
   1195 # error: Incompatible return value type (got "Union[ExtensionArray,
   1196 # ndarray[Any, Any]]", expected "Union[ndarray[Any, Any], DatetimeArray,
   1197 # TimedeltaArray, PeriodArray, IntervalArray]")
   1198 return lib.maybe_convert_objects(  # type: ignore[return-value]
   1199     value,
   1200     # Here we do not convert numeric dtypes, as if we wanted that,
   1201     #  numpy would have done it for us.
   1202     convert_numeric=False,
   1203     convert_non_numeric=True,
   1204     convert_to_nullable_dtype=convert_to_nullable_dtype,
-> 1205     dtype_if_all_nat=np.dtype("M8[ns]"),
   1206 )

KeyboardInterrupt: 

Trying to do so, generates a an KeyError mentioning that it could not find the coordinate for year 2010 and Germany in the paramter table urb_population. Let´s have a look into this parameter table.

my_ipcc.waste.incineration.parameter.urb_population

It is empty. The reason is that the IPCC guidelines do not provide default data for all parameters. In these cases we need to add the data to the specific parameter. Let´s do this for the urban population in Germany in 2010.

import pandas as pd

# urban population
d = {
    "year": [2010,2010,2010,2010,2010],
    "region": ["DE","DE","DE","DE","DE"],
    "property": [
        "def","min","max","abs_min","abs_max"
    ],
    "value": [
        62940432,61996325.52,63884538.48,0.0,"inf",
    ],
    "unit": [
    "cap/yr","cap/yr","cap/yr","cap/yr","cap/yr",
    ],
}
urb_pop = pd.DataFrame(d).set_index(["year", "region", "property"])

my_ipcc.waste.incineration.parameter.urb_population=urb_pop

And run the sequence again.

my_tier = my_ipcc.waste.incineration.sequence.tier1_co2(
          year=2010, region="DE",wastetype="msw_plastics", incintype="inc_unspecified", uncertainty="def")
my_tier.to_dict()

Each step involved in the calculation is stored in the dictionary. It starts with the input signature and ends with the final result of CO2 emsissions.