# HG changeset patch
# User Chris Mutel
# Date 1381496746 7200
# Node ID 3240aeefbbd9abcd33325026dc347a659014537d
# Parent 08eb5438f3952ccbe275fa9d911c94216c2c210e
Big addition of documentation, including reorganization
diff git a/bw2calc/graph_traversal.py b/bw2calc/graph_traversal.py
 a/bw2calc/graph_traversal.py
+++ b/bw2calc/graph_traversal.py
@@ 7,8 +7,32 @@
class GraphTraversal(object):
 """Master class for graph traversal."""
+ """
+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 it position in the graph, this is neither a breadthfirst nor a depthfirst search, but rather "importancefirst".
+
+This class is written in a functional style  no variables are stored in *self*, only methods.
+
+Should be used by calling the ``calculate`` method.
+
+ """
def calculate(self, demand, method, cutoff=0.005, max_calc=1e5):
+ """
+Traverse the supply chain graph.
+
+Args:
+ * *demand* (dict): The functional unit. Same format as in LCA class.
+ * *method* (tuple): LCIA method. Same format as in LCA class.
+ * *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, LCA object, and number of LCA calculations.
+
+ """
counter = 0
lca, supply, score = self.build_lca(demand, method)
@@ 36,6 +60,14 @@
}
def initialize_heap(self, demand, lca, supply, characterized_biosphere):
+ """
+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``.
+
+ """
heap, nodes, edges = [], {}, []
for activity, value in demand.iteritems():
index = lca.technosphere_dict[mapping[activity]]
@@ 46,9 +78,6 @@
index, supply, characterized_biosphere, lca),
"ind": self.unit_score(index, supply, characterized_biosphere)
}
 # 1 is a special index for total demand, which can be
 # composite. Initial edges are inputs to the
 # functional unit.
edges.append({
"to": 1,
"from": index,
@@ 58,6 +87,7 @@
return heap, nodes, edges
def build_lca(self, demand, method):
+ """Build LCA object from *demand* and *method*."""
lca = LCA(demand, method)
lca.lci()
lca.lcia()
@@ 65,20 +95,23 @@
return lca, lca.solve_linear_system(), lca.score
def cumulative_score(self, index, supply, characterized_biosphere, lca):
+ """Compute cumulative LCA score for a given activity"""
demand = np.zeros((supply.shape[0],))
demand[index] = supply[index]
return float((characterized_biosphere * lca.solver(demand)).sum())
def unit_score(self, index, supply, characterized_biosphere):
+ """Compute the LCA impact caused by the direct emissions and resource consumption of a given activity"""
return float(characterized_biosphere[index] * supply[index])
def traverse(self, heap, nodes, edges, counter, max_calc, cutoff,
total_score, supply, characterized_biosphere, lca):
"""
Build a directed graph of the supply chain.
+Build a directed graph by traversing the supply chain.
Use a heap queue to store a sorted list of processes that need to be examined,
and traverse the graph using an "importancefirst" search.
+Returns:
+ (nodes, edges, number of calculations)
+
"""
while heap and counter < max_calc:
parent_score_inverted, parent_index = heappop(heap)
@@ 127,6 +160,7 @@
return nodes, edges, counter
def add_metadata(self, nodes, lca):
+ """Add metadata to nodes, like name and category."""
rm = dict([(v, k) for k, v in mapping.data.iteritems()])
rt = dict([(v, k) for k, v in lca.technosphere_dict.iteritems()])
lookup = dict([(index, self.get_code(index, rm, rt)) for index in nodes if index != 1])
@@ 152,21 +186,13 @@
return dict(new_nodes)
def get_code(self, index, rev_mapping, rev_tech):
+ """Turn technosphere index into database identifier."""
return rev_mapping[rev_tech[index]]
def edge_cutter(nodes, edges, total, limit=0.0025):
"""The default graph traversal includes links which might be of small magnitude. This function cuts links that have small cumulative impact."""
 to_delete = []
 for i, e in enumerate(edges):
 if e["impact"] < (total * limit):
 to_delete.append(i)
 else:
 continue
 # print e
 # print nodes[e[1]]
 # print (e[2] / nodes[e[1]]["amount"] * nodes[e[1]]["cum"]) / (total * limit)
 return [e for i, e in enumerate(edges) if i not in to_delete]
+ return [e for e in edges if e["impact"] >= (total * limit)]
def node_pruner(nodes, edges):
diff git a/bw2calc/lca.py b/bw2calc/lca.py
 a/bw2calc/lca.py
+++ b/bw2calc/lca.py
@@ 144,9 +144,12 @@
####################
def decompose_technosphere(self):
 """Factorize the technosphere matrix into lower and upper triangular matrices, :math:`A=LU`. Does not solve the linear system :math:`Ax=B`.
+ """
+Factorize the technosphere matrix into lower and upper triangular matrices, :math:`A=LU`. Does not solve the linear system :math:`Ax=B`.
 Doesn't return anything, but creates ``self.solver``.
+Doesn't return anything, but creates ``self.solver``.
+
+.. warning:: Incorrect results could occur if a technosphere matrix was factorized, and then a new technosphere matrix was constructed, as ``self.solver`` would still be the factorized older technosphere matrix. You are responsible for deleting ``self.solver`` when doing these types of advanced calculations.
"""
self.solver = factorized(self.technosphere_matrix.tocsc())
@@ 161,9 +164,7 @@
We use `UMFpack `_, which is a very fast solver for sparse matrices.
If the technosphere matrix has already been factorized, then the decomposed technosphere is reused. Otherwise the calculation is redone completely.

.. warning:: Incorrect results could occur if a technosphere matrix was factorized, and then a new technosphere matrix was constructed, as ``self.solver`` would still be the factorized older technosphere matrix. You are responsible for deleting ``self.solver`` when doing these types of advanced calculations.
+If the technosphere matrix has already been factorized, then the decomposed technosphere (``self.solver``) is reused. Otherwise the calculation is redone completely.
"""
if hasattr(self, "solver"):
diff git a/bw2calc/matrices.py b/bw2calc/matrices.py
 a/bw2calc/matrices.py
+++ b/bw2calc/matrices.py
@@ 13,7 +13,9 @@
class MatrixBuilder(object):
"""
The class, and its subclasses, loads structured arrays, manipulates them, and generates sparse matrices.
+The class, and its subclasses, loads structured arrays, manipulates them, and generates `SciPy sparse matrices `_.
+
+Matrix builders use an array of row indices, an array of column indices, and an array of values to create a `coordinate (coo) matrix `_, which is then converted to a `compressed sparse row (csr) matrix `_.
See the following for more information on structured arrays:
diff git a/docs/graph_traversal.rst b/docs/graph_traversal.rst
new file mode 100644
 /dev/null
+++ b/docs/graph_traversal.rst
@@ 0,0 +1,13 @@
+Graph traversal
+===============
+
+To generate graphs of impact like supply chain or Sankey diagrams, we need to traverse the graph of the supply chain. The ``GraphTraversal`` class does this in a relatively intelligent way, assessing each inventory activity only once regardless of how many times it is used, and prioritizing activities based on their LCA score. It is usually possible to create a reduced graph of the supply chain, with only the most relevant pathways and flows included, in a few seconds.
+
+Illustration of graph traversal
+
+
+Technical reference
+
+
+.. autoclass:: bw2calc.GraphTraversal
+ :members:
diff git a/docs/index.rst b/docs/index.rst
 a/docs/index.rst
+++ b/docs/index.rst
@@ 26,7 +26,11 @@
.. toctree::
:maxdepth: 2
 technical
+ matrix
+ lca
+ monte_carlo
+ graph_traversal
+ regio
Indices and tables
==================
diff git a/docs/lca.rst b/docs/lca.rst
new file mode 100644
 /dev/null
+++ b/docs/lca.rst
@@ 0,0 +1,10 @@
+.. _LCA:
+
+Static life cycle assessment
+============================
+
+Technical reference
+
+
+.. autoclass:: bw2calc.LCA
+ :members:
diff git a/docs/matrix.rst b/docs/matrix.rst
new file mode 100644
 /dev/null
+++ b/docs/matrix.rst
@@ 0,0 +1,15 @@
+.. _matrixbuilders:
+
+Matrix builders
+===============
+
+One of the most basic and most important components of ``bw2calc`` is the ability to build a sparse matrix from a processed parameter array.
+
+Technical reference
+
+
+.. autoclass:: bw2calc.MatrixBuilder
+ :members:
+
+.. autoclass:: bw2calc.TechnosphereBiosphereMatrixBuilder
+ :members:
diff git a/docs/monte_carlo.rst b/docs/monte_carlo.rst
new file mode 100644
 /dev/null
+++ b/docs/monte_carlo.rst
@@ 0,0 +1,13 @@
+.. _montecarlo:
+
+Monte Carlo uncertainty analysis
+================================
+
+Technical reference
+
+
+.. autoclass:: bw2calc.MonteCarloLCA
+ :members:
+
+.. autoclass:: bw2calc.ParallelMonteCarlo
+ :members:
diff git a/docs/regio.rst b/docs/regio.rst
new file mode 100644
 /dev/null
+++ b/docs/regio.rst
@@ 0,0 +1,12 @@
+Regionalization
+===============
+
+Only a simple form of regionalization is provided in ``bw2calc``  more complex types of regionalization can be found in extension packages.
+
+The ``SimpleRegionalizedLCA`` class can match LCIA characterization factors to inventory datasets when their locations match.
+
+Technical reference
+
+
+.. autoclass:: bw2calc.SimpleRegionalizedLCA
+ :members:
diff git a/docs/technical.rst b/docs/technical.rst
deleted file mode 100644
 a/docs/technical.rst
+++ /dev/null
@@ 1,46 +0,0 @@
Technical guide
***************

Currently, there is no overview documentation, only classspecific stuff.

.. _LCA:

Static LCA
==========

.. autoclass:: bw2calc.LCA
 :members:

.. _matrixbuilders:

Matrix builders
===============

.. autoclass:: bw2calc.MatrixBuilder
 :members:

.. autoclass:: bw2calc.TechnosphereBiosphereMatrixBuilder
 :members:

.. _montecarlo:

Monte Carlo uncertainty analysis
================================

.. autoclass:: bw2calc.MonteCarloLCA
 :members:

.. autoclass:: bw2calc.ParallelMonteCarlo
 :members:

Graph traversal
===============

.. autoclass:: bw2calc.GraphTraversal
 :members:

Regionalization
===============

.. autoclass:: bw2calc.SimpleRegionalizedLCA
 :members: