Contribution tree
As you probably know from using the Contribution tree tab in openLCA, it is a visual representation of the environmental impacts of a system across its entire supply chain. It helps identify which stages of the life cycle contribute most to the overall environmental impact.
The contribution tree can be obtained from the LcaResult object by using the UpstreamTree.of
method. It takes a ResultProvider as well as an EnviFlow or ImpactDescriptor (see
Meta classes) object as input. Let's build one:
Getting an upstream tree
Build the tree from the result provider and the descriptor of the impact category you want to inspect.
# retrieve the first impact category
category = method.impactCategories[0]
tree = UpstreamTree.of(result.provider(), Descriptor.of(category))
The UpstreamTree is composed of UpstreamNode objects. Each UpstreamNode provides different
types of result and the provider (TechFlow). The root node of the tree can be retrieved via the
UpstreamTree.root attribute. And the children of a node can be retrieved via the
UpstreamTree.childs method.
provider(): Returns the provider of the product output or waste input of this upstream tree node.result(): Returns the upstream result of this node.requiredAmount(): Returns the required amount of the provider flow of this upstream node.scalingFactor(): Returns the scaling factor of this upstream node.directContribution(): Returns the direct contribution of the process (tech-flow) of the node to the total result the node.
Traversing the tree, breath-first
The tree can be traversed using the UpstreamTree.childs method recursively. A good practice is to
set a maximum depth to avoid long computation times.
# retrieve the first impact category
category = method.impactCategories[0]
tree = UpstreamTree.of(result.provider(), Descriptor.of(category))
DEPTH = 5
UNIT = category.referenceUnit
def traverse(tree, node, depth):
if depth == 0:
return
print(
"%sThe impact result of %s is %s %s (%s%%)."
% (
" " * (DEPTH - depth),
node.provider().provider().name,
node.result(),
UNIT,
node.result() / tree.root.result() * 100,
)
)
# recursively traverse the tree
for child in tree.childs(node):
traverse(tree, child, depth - 1)
traverse(tree, tree.root, DEPTH)