# brightway2-calc / docs / index.rst

## Brightway2-calc

This is the documentation for Brightway2-calc, part of the Brightway2 life cycle assessment framework.

Brightway2-calc does calculations: static LCA calculations, stochastic LCA calculations, and traversals through the supply chain. A core part of Brightway2-calc is the matrix builder, a class that convert parameter arrays into SciPy sparse matrices.

Graph traversal is covered in depth on a separate page.

### Other Resources

The following online resources are available:

## Building matrices

A parameter array is a NumPy structured or record array, where each column has a label and data type. Here is an sample of the parameter array for the US LCI:

input output row col type amount
9829 9829 4294967295 4294967295 0 1.0
9708 9708 4294967295 4294967295 0 1.0
9633 9633 4294967295 4294967295 0 1.0
9276 9276 4294967295 4294967295 0 3.0999
8778 8778 4294967295 4294967295 0 1.0
9349 9349 4294967295 4294967295 0 1000.0
5685 9349 4294967295 4294967295 2 14.895
9516 9349 4294967295 4294967295 1 1032.7
9433 9349 4294967295 4294967295 1 4.4287
8838 9349 4294967295 4294967295 1 1.5490

As this is a parameter array for a LCI database, it gives values that will be inserted into the technosphere and biosphere matrices, i.e. values from the dataset exchanges.

There are also some columns for uncertainty information, but these would only be a distraction for now. The complete spec for the uncertainty fields is given in the stats_arrays documentation.

We notice several things:

• Both the input and output columns have numbers, but we don't know what they mean yet
• Both the row and col columns are filled with a large number
• The type column has only a few values, but they are also mysterious
• The amount column is the only one that seems reasonable, and gives the values that should be inserted into the matrix

### Input and Output

The input and output columns gives values for biosphere flows or transforming activity data sets. Brightway2-data uses a mapping dictionary to translate keys like ("Douglas Adams", 42) into integer values. So, each number uniquely identifies an activity dataset.

If the input and output values are the same, then this is a production exchange - it describes how much product is produced by the transforming activity dataset.

Warning

Integer mapping ids are not transferable from machine to machine or installation to installation, as the order of insertion (and hence the integer id) is more or less at random. Always process new datasets.

### Rows and columns

The row and col columns have the data type unsigned integer, 32 bit, and the maximum value is therefore $$2^{32} - 1$$ , i.e. 4294967295. This is just a dummy value telling Brightway2 to insert better data.

The method MatrixBuilder.build_dictionary is used to take input and output values, respectively, and figure out which rows and columns they correspond to. The actual code is succinct - only one line - but what it does is:

1. Get all unique values, as each value will appear multiple times
2. Sort these values
3. Give them integer indices, starting with zero

For our example parameter array, the dictionary from input values to row would be:

{5685: 0,
8778: 1,
8838: 2,
9276: 3,
9349: 4,
9433: 5,
9516: 6,
9633: 7,
9708: 8,
9829: 9}


And the dictionary from output to col would be:

{8778: 0,
9276: 1,
9349: 2,
9633: 3,
9708: 4,
9829: 5}


The method MatrixBuilder.add_matrix_indices would replace the 4294967295 values with dictionary values based on input and output. At this point, we have enough to build a sparse matrix using MatrixBuilder.build_matrix:

row col amount
9 5 1.0
8 4 1.0
7 3 1.0
3 1 3.0999
1 0 1.0
4 2 1000.0
0 2 14.895
6 2 1032.7
5 2 4.4287
2 2 1.5490

Indeed, the coordinate (coo) matrix takes as inputs exactly the row and column indices, and the values to insert.

Of course, there are some details for specific matrices - technosphere matrices need to be square, and should have ones by default on the diagonal, etc. etc., but this is the general idea.

### Types

The type column indicates whether a value should be in the technosphere or biosphere matrix: 0 is a transforming activity production amount, 1 is a technosphere exchange, and 2 is a biosphere exchange.

## Static LCA

The actual LCA class then is more of a coordinator then an accountant, as the matrix builder is doing much of the data manipulation. The :ref:lca class only has to do the following:

• Translate the functional unit into a demand array
• Find the right parameter arrays, and ask matrix builder for matrices
• Solve the linear system $$Ax=B$$ using UMFpack
• Multiply the result by the LCIA CFs, if a LCIA method is present

The LCA class also has some convenience functions for redoing some calculations with slight changes, e.g. for uncertainty and sensitivity analysis. See the "redo_*" and "rebuild_*" methods in the LCA class.

## Stochastic LCA

The various stochastic Monte Carlo LCA classes function almost the same as the static LCA, and reuse most of the code. The only change is that instead of building matrices once, random number generators from stats_arrays are instantiated directly from each parameter array. For each Monte Carlo iteration, the amount column is then overwritten with the output from the random number generator, and the system solved as normal. The code to do a new Monte Iteration is quite succinct:

def next(self):
self.rebuild_technosphere_matrix(self.tech_rng.next())
self.rebuild_biosphere_matrix(self.bio_rng.next())
if self.lcia:
self.rebuild_characterization_matrix(self.cf_rng.next())

self.lci_calculation()

if self.lcia:
self.lcia_calculation()
return self.score
else:
return self.supply_array
`

This design is one of the most elegant parts of Brightway2.

Because there is a common procedure to build static and stochastic matrices, any matrix can easily support uncertainty, e.g. not just LCIA characterization factors, but also weighting, normalization, and anything else you can think of; see tutorial 5: defining a new matrix.

Note