Using calculation setups

# Using Calculation Setups¶

Calculation setups are a way to efficiently do LCA calculations for multiple functional units and methods at the same time.

This notebook builds on the `Getting started with Brightway2` notebook, and won't work if you haven't done that notebook yet.

In [1]:

    from brightway2 import *

In [2]:

    if "Calculation setups" not in projects:
        projects.set_current("BW2 introduction")
        projects.copy_project("Calculation setups")
    else:
        projects.set_current("Calculation setups")

## Defining a calculation setup¶

A calculation setups is defined by three things:

- A name
- A list of functional units
- A list of LCIA methods

In this example, we will choose both activities and methods at random.

In [3]:

    functional_units = [{Database('forwast').random(): 1} for _ in range(20)]

We can't choose methods completely at random, though, as the `forwast` database doesn't have as many biosphere flows as ecoinvent, so many methods will only characterize flows that aren't provided anywhere in `forwast`. So lets only choose from the methods which will have a non-zero LCA score:

In [4]:

    import random

    all_forwast_flows = {exc.input for ds in Database("forwast") for exc in ds.biosphere()}
    suitable_methods = [method
                        for method in methods
                        if {cf[0] for cf in Method(method).load()}.intersection(all_forwast_flows)]

    print("Can use {} of {} LCIA methods".format(len(suitable_methods), len(methods)))
    chosen_methods = random.sample(suitable_methods, 8)

    Can use 306 of 665 LCIA methods

A calculation setup is a normal Python dictionary, with keys `inv` and `ia`, for the functional units and LCIA methods, respectively.

In [5]:

    my_calculation_setup = {'inv': functional_units, 'ia': chosen_methods}

You define a calculation setup by name in the metadata store `calculation_setups`, similar to the way that LCIA methods are defined.

In [6]:

    calculation_setups['some random stuff'] = my_calculation_setup

We can examine what we have just randomly created:

In [7]:

    calculation_setups['some random stuff']

Out[7]:

    {'ia': [('ReCiPe Midpoint (H)', 'metal depletion', 'MDP'),
      ('EDIP w/o LT',
       'environmental impact w/o LT',
       'human toxicity, via surface water w/o LT'),
      ('ReCiPe Midpoint (E) w/o LT', 'fossil depletion w/o LT', 'FDP w/o LT'),
      ('EDIP2003 w/o LT', 'non-renewable resources w/o LT', 'aluminium w/o LT'),
      ('ecological footprint', 'total', 'total'),
      ('ReCiPe Endpoint (H,A) w/o LT', 'resources w/o LT', 'total w/o LT'),
      ('EDIP2003', 'photochemical ozone formation', 'impacts on human health'),
      ('ecological scarcity 2006', 'total', 'energy resources')],
     'inv': [{'_89 Post and telecommunication, EU27' (EUR2003, GLO, ['Input Output', 'EU27 2003']): 1},
      {'_73 Furniture and other manufactured goods n.e.c., EU27' (kilogram, GLO, ['Input Output', 'EU27 2003']): 1},
      {'__1 Bovine meat and milk, EU27' (kilogram, GLO, ['Input Output', 'EU27 2003']): 1},
      {'130 Membership organisations, EU27' (EUR2003, GLO, ['Input Output', 'EU27 2003']): 1},
      {'_58 Office machinery and computers, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'111 Waste treatment, Landfill of waste, Alu, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'_30 Wearing apparel and furs, EU27' (kilogram, GLO, ['Input Output', 'EU27 2003']): 1},
      {'_61 Instruments, medical, precision, optical, clocks, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'103 Waste treatment, Composting of food waste, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'_54 Recycling of copper basic, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'131 Household use, Meals, DK' (EUR2003, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'__8 Recycling of waste wood, EU27' (kilogram, GLO, ['Input Output', 'EU27 2003']): 1},
      {'120 Waste treatment, Land application of compost, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'_31 Leather products, footwear, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'_74 Retail  trade and repair services, DK' (EUR2003, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'_32 Wood products, except furniture, EU27' (kilogram, GLO, ['Input Output', 'EU27 2003']): 1},
      {'128 Waste treatment, Landfill of waste, Slag' (kilogram, ash, EU27, ['Input Output', 'EU27 2003']): 1},
      {'_29 Textiles, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'120 Waste treatment, Land application of compost, DK' (kilogram, GLO, ['Input Output', 'Denmark 2003']): 1},
      {'__5 Crops n.e.c., EU27' (kilogram, GLO, ['Input Output', 'EU27 2003']): 1}]}

The normal create, update, and delete machanisms apply:

- To create a new calculation setup, assign by name, as in cell above
- To replace a calculation setup, just assign new data, i.e. `calculation_setups['some random stuff'] = some_new_stuff`.
- To delete a calculation setup, use `del`, i.e. `del calculation_setups['some random stuff']`.

## Using a calculation setup¶

Use the `MultiLCA` class to get LCA results for a calculation setup. Note that this class does all the calculations as soon as you create it.

In [8]:

    mlca = MultiLCA('some random stuff')

In [9]:

    mlca.results

Out[9]:

    array([[  2.01992360e-02,   5.41100722e-06,   8.46148810e-02,
              6.61679078e-04,   1.42901040e+00,   1.17617425e-02,
              1.28948520e-04,   1.27063423e+01],
           [  3.42570244e-01,   7.08964005e-05,   1.07109057e+00,
              2.16505158e-02,   1.70176907e+01,   1.52923265e-01,
              1.69952888e-03,   1.60852771e+02],
           [  8.54603999e-02,   8.20893591e-05,   8.59786378e-01,
              2.41886966e-03,   1.35256790e+01,   1.14021466e-01,
              1.02473129e-02,   1.29275666e+02],
           [  1.38804898e-02,   9.26976794e-06,   1.40957937e-01,
              4.54331969e-04,   2.48256765e+00,   1.86521880e-02,
              2.23869508e-04,   2.11117955e+01],
           [  3.34442558e+00,   3.32505885e-04,   5.29992430e+00,
              2.08351234e-01,   7.90777941e+01,   8.33465266e-01,
              7.67466305e-03,   7.96400917e+02],
           [  2.65436174e-03,   1.79663207e-06,   2.71179542e-02,
              4.83997043e-05,   3.35531721e-01,   3.59813477e-03,
              3.63611861e-05,   4.08631436e+00],
           [  2.98027138e-01,   2.65968682e-04,   4.87916050e+00,
              2.02559781e-02,   6.88469431e+01,   6.38612312e-01,
              7.05066663e-03,   7.34177367e+02],
           [  1.73794610e+00,   3.03233270e-04,   4.42945481e+00,
              9.69016355e-02,   6.25006630e+01,   6.47544599e-01,
              6.69818467e-03,   6.65724592e+02],
           [  4.11230870e-04,   1.87116136e-06,  -3.51387683e-01,
             -7.71789294e-05,   2.90108609e-01,  -4.42014831e-02,
              1.92414412e-04,  -5.10539989e+01],
           [ -1.93323569e+01,   6.99587535e-05,   4.28280943e-01,
              3.48533774e-01,   8.00092714e+00,  -8.43024115e-01,
              1.50923061e-03,   6.37612809e+01],
           [  1.87993088e-02,   2.33919217e-05,   2.80539817e-01,
              2.24872423e-04,   4.77588432e+00,   3.67011896e-02,
              6.61535727e-04,   4.19915185e+01],
           [  8.68322913e-05,  -1.80879514e-06,  -1.44139358e-02,
              1.72417862e-05,  -2.19647814e-01,  -1.83291263e-03,
             -2.95201063e-05,  -2.14831874e+00],
           [ -2.93513576e-03,  -1.94108729e-06,  -4.90487423e-01,
             -1.54424488e-04,  -7.66110015e-01,  -6.19688279e-02,
             -1.11368000e-04,  -7.15154981e+01],
           [  8.49469480e-01,   8.64262824e-04,   1.01367857e+01,
              1.67812037e-02,   1.43058798e+02,   1.33767259e+00,
              1.97762031e-02,   1.52583574e+03],
           [  1.17946656e-02,   9.52604590e-06,   1.09768383e-01,
              1.23571916e-04,   1.63443814e+00,   1.45884813e-02,
              1.99786699e-04,   1.64821999e+01],
           [  1.96479851e-02,   1.80017134e-05,   1.75696168e-01,
              8.73941647e-04,   3.12080542e+00,   2.34034028e-02,
              3.98288935e-04,   2.64216756e+01],
           [  3.30914057e-03,   1.20266327e-06,   1.53790378e-02,
              1.69859774e-04,   3.02970929e-01,   2.12255070e-03,
              2.70444442e-05,   2.31324601e+00],
           [  1.41039455e-01,   1.35668820e-04,   2.04153889e+00,
             -9.72030282e-03,   2.75440996e+01,   2.67912963e-01,
              2.92791763e-03,   3.07072036e+02],
           [ -2.93513576e-03,  -1.94108729e-06,  -4.90487423e-01,
             -1.54424488e-04,  -7.66110015e-01,  -6.19688279e-02,
             -1.11368000e-04,  -7.15154981e+01],
           [  1.44529443e-02,   1.22454377e-05,   2.03155483e-01,
              4.51652358e-04,   3.01491530e+00,   2.66933258e-02,
              3.51663523e-04,   3.05886931e+01]])

## Visualizing the results¶

There isn't any code built into Brightway2 yet, but Seaborn has some great visualizations for this type of result array.

In [10]:

    %matplotlib inline

    Warning: metadata {'config': True} was set from the constructor.  Metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2')
    Warning: metadata {'config': True} was set from the constructor.  Metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2')
    Warning: metadata {'config': True} was set from the constructor.  Metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2')
    Warning: metadata {'config': True} was set from the constructor.  Metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2')
    Warning: metadata {'config': True} was set from the constructor.  Metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2')
    Warning: InlineBackend._config_changed is deprecated: use @observe and @unobserve instead.
    Warning: A parent of InlineBackend._config_changed has adopted the new @observe(change) API

You can ignore any errors that show up here.

In [11]:

    import numpy as np
    import matplotlib.pyplot as plt
    import seaborn as sns

    Warning: axes.color_cycle is deprecated and replaced with axes.prop_cycle; please use the latter.

In [12]:

    # From https://stanford.edu/~mwaskom/software/seaborn/tutorial/color_palettes.html
    cmap = sns.cubehelix_palette(8, start=.5, rot=-.75, as_cmap=True)

    sns.heatmap(
        mlca.results / np.average(mlca.results, axis=0), # Normalize to get relative results
        annot=True,
        linewidths=.05,
        cmap=cmap,
        xticklabels=["\n".join(x) for x in mlca.methods]
    )
    plt.xticks(rotation=70)

Out[12]:

    (array([ 0.5,  1.5,  2.5,  3.5,  4.5,  5.5,  6.5,  7.5]),
     <a list of 8 Text xticklabel objects>)

Could also adapt https://stanford.edu/~mwaskom/software/seaborn/examples/structured_heatmap.html, but this is more work.