bw2calc.graph_traversal
#
Module Contents#
Classes#
Traverse a supply chain, following paths of greatest impact. |
|
Traverse a supply chain, following paths of greatest impact. Can handle the differentiation between products and activities, and makes no assumptions about multifunctionality, substitution, or the special status of numbers on the diagonal. |
- class bw2calc.graph_traversal.AssumedDiagonalGraphTraversal[source]#
Traverse a supply chain, following paths of greatest impact.
This implementation uses a queue of datasets to assess. As the supply chain is traversed, datasets inputs are added to a list sorted by LCA score. Each activity in the sorted list is assessed, and added to the supply chain graph, as long as its impact is above a certain threshold, and the maximum number of calculations has not been exceeded.
Because the next dataset assessed is chosen by its impact, not its position in the graph, this is neither a breadth-first nor a depth-first search, but rather âimportance-firstâ.
This class is written in a functional style - no variables are stored in self, only methods.
Should be used by calling the
calculate
method.Warning
Graph traversal with multioutput processes only works when other inputs are substituted (see Multioutput processes in LCA for a description of multiputput process math in LCA).
- calculate(lca, cutoff=0.005, max_calc=100000.0, skip_coproducts=False)[source]#
Traverse the supply chain graph.
- Args:
lca (dict): An instance of
bw2calc.lca.LCA
.cutoff (float, default=0.005): Cutoff criteria to stop LCA calculations. Relative score of total, i.e. 0.005 will cutoff if a dataset has a score less than 0.5 percent of the total.
max_calc (int, default=10000): Maximum number of LCA calculations to perform.
- Returns:
Dictionary of nodes, edges, and number of LCA calculations.
- cumulative_score(index, supply, characterized_biosphere, lca)[source]#
Compute cumulative LCA score for a given activity
- initialize_heap(lca, supply, characterized_biosphere)[source]#
Create a priority queue or
heap
to store inventory datasets, sorted by LCA score.Populates the heap with each activity in
demand
. Initial nodes are the functional unit, i.e. the complete demand, and each activity in the functional unit. Initial edges are inputs from each activity into the functional unit.The functional unit is an abstract dataset (as it doesnât exist in the matrix), and is assigned the index
-1
.
- traverse(heap, nodes, edges, counter, max_calc, cutoff, total_score, supply, characterized_biosphere, lca, skip_coproducts)[source]#
Build a directed graph by traversing the supply chain.
Node ids are actually technosphere row/col indices, which makes lookup easier.
- Returns:
(nodes, edges, number of calculations)
- class bw2calc.graph_traversal.MultifunctionalGraphTraversal[source]#
Traverse a supply chain, following paths of greatest impact. Can handle the differentiation between products and activities, and makes no assumptions about multifunctionality, substitution, or the special status of numbers on the diagonal.
As soon as non-diagonal values are allowed, we lose any concept of a reference product. This means that we can trace the edges for an activity (both inputs and outputs, though in the matrix there is no functional difference), but we canât for a product, as we canât use the graph structure to determine which activity produced the product. There could be more than one, or even zero, depending on how your mental model of substitution works. Our algorithm is therefore:
Start with products (initially the products in the functional unit)
2. For each product, determine which activities produced it by solving the linear system 3a. For each of these activities, add on to our list of products to consider by looking at the edges for that activity, and excluding the edge which led to our original product 3b. If we have already examined this activity, donât visit it again 4. Keep iterating over the list of products until we run out of activities or hit our calculation limit
The
.calculate()
function therefore returns the following:{ 'counter': int, # Number of LCA calculations done, 'products': { id: { # id is either the database integer id (if `translate_indices` is True) or the matrix row index 'amount': float # Total amount of this product produced to satisfy the functional unit 'supply_chain_score': float # The total impact of producing this product } }, 'activities': { id: { # id is either the database integer id (if `translate_indices` is True) or the matrix column index 'amount': float # Total amount of this activity produced to satisfy the entire functional unit 'direct_score': float # The impact of the direct emissions associated to this activity and its amount }, 'edges': [{ 'target': int, # product id if type is activity else activity id 'source': int, # activity id if type is product else product id 'type': str, # 'product' or 'activity' 'amount': float, # Total amount of the flow 'exc_amount': float, # Value given in the technosphere matrix 'supply_chain_score': float, # Total impact from the production of this product. Only for type 'product' 'direct_score': float, # Impact from direct emissions of this activity. Only for type 'activity' }] }
As in AssumedDiagonalGraphTraversal, we use a priority queue to examine products in order of their total impact.
This class is written in a functional style, with only class methods.
- classmethod calculate(lca: bw2calc.LCA, cutoff: float = 0.005, max_calc: int = 100000.0, translate_indices: bool = True)[source]#
Traverse the supply chain graph.
- Args:
lca (dict): An instance of
bw2calc.lca.LCA
.cutoff (float, default=0.005): Cutoff criteria to stop LCA calculations. Relative score of total, i.e. 0.005 will cutoff if a dataset has a score less than 0.5 percent of the total.
max_calc (int, default=10000): Maximum number of LCA calculations to perform.
- Returns:
Dictionary of nodes, edges, and number of LCA calculations.
- classmethod initialize_heap(lca: bw2calc.LCA, solver: CachingSolver, translate_indices: bool, counter: int)[source]#
Create a priority queue or
heap
to store inventory datasets, sorted by LCA score.Populates the heap with each activity in
demand
. Initial nodes are the functional unit, i.e. the complete demand, and each activity in the functional unit. Initial edges are inputs from each activity into the functional unit.The functional unit is an abstract dataset (as it doesnât exist in the matrix), and is assigned the index
-1
.
- classmethod traverse(heap: list, solver: CachingSolver, activities: dict, products: dict, edges: list, max_calc: int, cutoff: float, total_score: float, lca: bw2calc.LCA, translate_indices: bool, counter: int)[source]#
Build a directed graph by traversing the supply chain.
Node ids are actually technosphere row/col indices, which makes lookup easier.
- Returns:
(nodes, edges, number of calculations)
- classmethod visit_activity(heap: list, activity_index: int, counter: int, activities: dict, products: dict, edges: list, lca: bw2calc.LCA, characterized_biosphere: scipy.sparse.csr_matrix, solver: CachingSolver, cutoff_score: float, origin_product_index: int, translate_indices: bool)[source]#