Source code for bw_hestia_bridge.strategies.linking

import csv
from collections import defaultdict
from pathlib import Path
from typing import Optional
from uuid import uuid4

import bw2data as bd
from bw2io import activity_hash
from constructive_geometries import Geomatcher

[docs] DATA_DIR = Path(__file__).parent.parent.resolve() / "data"
[docs] def add_code_from_hestia_attributes(data: list) -> list: FIELDS = ("name", "unit", "reference product", "transformation_id") for obj in data: obj["code"] = activity_hash(obj, fields=FIELDS) return data
[docs] def pick_from_overlapping( exc: dict, possibles: defaultdict, overlapping: list, ) -> None: """Try to find a provider of the supplied demand. `exc` is a dictionary; we use `term_id` (e.g. `manureSaltsKgK2O`) to search in `possibles`. `possibles` is a dictionary with keys of Hestia term `@id` keys, and values of bw2data processes which were mapped against the Hestia term ids in "ecoinvent_mappings_technosphere.csv". `overlapping` is an ordered list, from smallest to largest, or each region in ecoinvent which completely overlaps the `exc` dataset's location. We try to find the process in the correct `possibles` value list which most closely matches the `exc` dataset location. We also use fallback locations if necessary. The fallback locations are `RoE` (rest of Europe), `RoW` (rest of world), and `GLO` (global). If a match is found, adds `input` to the `exc`. """ mapping = {ds["location"]: ds for ds in possibles} for location in overlapping: if location in mapping: exc["input"] = mapping[location].key return if ( any("Europe" in geo for geo in overlapping) or ("RER" in overlapping) ) and "RoE" in mapping: exc["input"] = mapping["RoE"].key elif "RoW" in mapping: exc["input"] = mapping["RoW"].key elif "GLO" in mapping: exc["input"] = mapping["GLO"].key
[docs] def previous_transformation(val: str) -> str: # Definitely going to be punished in the afterlife for this... if val == "0": return "0" else: return str(int(val) - 1)
[docs] def create_mocks(data): new_data = [] for ds in data: for exc in ds.get("exchanges", []): if not exc.get("input") and exc.get("type") == "technosphere": code = uuid4().hex # TBD: We should check and not create multiple products for same flow part_one = { "database": ds["database"], "code": code, "type": "product", "name": "Mock " + exc["name"], "mock": True, "cycle_id": exc["cycle_id"], "term_id": exc["term_id"], } part_two = { key: exc.get(key) for key in ( "cycle_id", "transformation_id", "term_id", "unit", "group", ) } new_data.append(part_one | part_two) exc["input"] = (ds["database"], code) data.extend(new_data) return data