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/biological/__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/biological/sequence.py:16
     14 from ..._sequence import Sequence
     15 from . import elementary as elem
---> 16 from ._data import concordance as conc
     17 from ._data import dimension as dim
     18 from ._data import parameter as par

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/bonsai_ipcc/waste/biological/_data.py:3
      1 from ..._data import Concordance, Dimension, Parameter
----> 3 dimension = Dimension("data/", activitycode="biological", productcode="waste")
      5 parameter = Parameter(["data/waste/biological/", "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: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:588, in Series.__init__(self, data, index, dtype, name, copy, fastpath)
    586 manager = _get_option("mode.data_manager", silent=True)
    587 if manager == "block":
--> 588     data = SingleBlockManager.from_array(data, index, refs=refs)
    589 elif manager == "array":
    590     data = SingleArrayManager.from_array(data, index)

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/pandas/core/internals/managers.py:1872, in SingleBlockManager.from_array(cls, array, index, refs)
   1870 array = maybe_coerce_values(array)
   1871 bp = BlockPlacement(slice(0, len(index)))
-> 1872 block = new_block(array, placement=bp, ndim=1, refs=refs)
   1873 return cls(block, index)

File /builds/bonsamurais/bonsai/util/ipcc/.tox/docs/lib/python3.12/site-packages/pandas/core/internals/blocks.py:2801, in new_block(values, placement, ndim, refs)
   2789 def new_block(
   2790     values,
   2791     placement: BlockPlacement,
   (...)   2798     # - check_ndim/ensure_block_shape already checked
   2799     # - maybe_coerce_values already called/unnecessary
   2800     klass = get_block_type(values.dtype)
-> 2801     return klass(values, ndim=ndim, placement=placement, refs=refs)

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.