Source code for bw2io.strategies.products

from pprint import pformat
from typing import List
from uuid import uuid4

import bw2data as bd

[docs] EDGE_CORE_COLUMNS = [ "name", "amount", "database", "location", "unit", "functional", "type", "uncertainty type", "loc", "scale", "shape", "minimum", "maximum", ]
[docs] def create_products_as_new_nodes(data: List[dict]) -> List[dict]: """ Create new product nodes and link to them if needed. We create new `product` if the following conditions are met: * The dataset is not multifunctional ( `dataset.get("type") != bd.labels.multifunctional_node_default`). Multifunctional datasets handle product creation separately. * The edge is functional (`obj.get("functional") is True`) * The edge is unlinked (`obj.get("input")` is falsey) * The given edge has a `name`, and that `name` is different than the dataset `name` * The combination of `name` and `location` is not present in the other dataset nodes. If no `location` attribute is given for the edge under consideration, we use the `location` of the dataset. Create new nodes, and links the originating edges to the new product nodes. Modifies data in-place, and returns the modified `data`. """ combos = {(ds.get("name"), ds.get("location")) for ds in data} nodes = [] for ds in data: if ds.get("type") == bd.labels.multifunctional_node_default: # Has its own product handling continue for edge in ds.get("exchanges", []): if ( edge.get("functional") and not edge.get("input") and edge.get("name") and edge["name"] != ds.get("name") ): if not ds.get("database"): raise KeyError( """ Can't create a new `product` node, as dataset is missing `database` attribute: {}""".format( pformat(ds) ) ) key = (edge["name"], edge.get("location") or ds.get("location")) if key not in combos: code = uuid4().hex nodes.append( { "name": edge["name"], "location": key[1] or bd.config.global_location, "unit": edge.get("unit") or ds.get("unit"), "exchanges": [], "code": code, "type": bd.labels.product_node_default, "database": ds["database"], } | {k: v for k, v in edge.items() if k not in EDGE_CORE_COLUMNS} ) edge["input"] = (ds["database"], code) combos.add(key) if nodes: data.extend(nodes) return data