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)