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
Advanced data model) object as input. Let's build one:
Getting an upstream tree
climate_change = next(i for i in method.impactCategories if i.name == "Climate change")
tree = UpstreamTree.of(result.provider(), Descriptor.of(climate_change))
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.
class UpstreamNode
def provider(): # () -> TechFlow
"""Returns the provider of the product output or waste input of this upstream tree node."""
def result(): # () -> float
"""Returns the upstream result of this node."""
def requiredAmount(): # () -> float
"""Returns the required amount of the provider flow of this upstream node."""
def scalingFactor(): # () -> float
"""Returns the scaling factor of this upstream node."""
def directContribution(): # () -> float
"""
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.
DEPTH = 5
UNIT = climate_change.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,
)
)
for child in tree.childs(node):
traverse(tree, child, depth - 1)
traverse(tree, tree.root, DEPTH)