Parameterized inventories

This notebook shows how to create parameterized inventories with constants, variables, and formulas.

Note that Brightway2 allows you to write real models in Python, and this is preferable to writing a model in formulas inside an inventory. However, for simple cases parameterized inventories can add real power without too much work.

We start by creating a new project and adding the basic data.

In [1]:
from brightway2 import *
In [2]:
projects.current = "parameterized"
In [3]:
bw2setup()
Creating default biosphere

Applying strategy: drop_unspecified_subcategories
Writing activities to SQLite3 database:
0%                          100%
[##############################] | ETA[sec]: 0.000 
Total time elapsed: 0.664 sec
Title: Writing activities to SQLite3 database:
  Started: 05/22/2015 09:28:54
  Finished: 05/22/2015 09:28:55
  Total time elapsed: 0.664 sec
  CPU %: 90.800000
  Memory %: 1.021481
Created database: biosphere3
Creating default LCIA methods

Applying strategy: set_biosphere_type
Applying strategy: drop_unspecified_subcategories
Applying strategy: link_iterable_by_fields
Wrote 692 LCIA methods with 170915 characterization factors
Creating core data migrations

Create a database

This will hold our parameterized inventories.

In [7]:
db = Database("Woweee!")
db.write({})

Create a new activity

Each activity has its own namespace for variable and formula names.

Lets also define some simple parameters.

In [5]:
act = db.new_activity("first", name="first parameterized inventory", unit="kilogram")
In [8]:
act['parameters'] = {
    'speed': {'amount': 40, 'unit': 'km/h'},
    'time': {'amount': 2.5, 'unit': 'hours', 'comment': 'A long time, but no so long'},
    'distance': {'formula': 'speed * time', 'arbitrary fields': 'can be added as needed'}
}
act.save()

Evaluate our parameter set

Evaluate our parameter set using the bw2parameters library.

In [9]:
from bw2parameters import ParameterSet

ps = ParameterSet(act['parameters'])
ps.evaluate()
Out[9]:
{'distance': 100.0, 'speed': 40, 'time': 2.5}

Add parameterized exchanges

We don't have any other technosphere processes, but we can paramerize links to biosphere flows.

In [19]:
exc = act.new_exchange(input=Database("biosphere3").random(), type='biosphere')
exc.input
Out[19]:
'Plutonium-alpha' (kilo Becquerel, None, ('air',))

We have a bunch of built in functions from the Python math library and numpy. Note that we don't define the amount field - this will be added later when the formula is evaluated.

In [20]:
exc['formula'] = 'sqrt(distance) * pi'

Let's do another one:

In [21]:
exc2 = act.new_exchange(input=Database("biosphere3").random(), type='biosphere')
exc2['formula'] = 'log(speed) ** 2'

The syntax to evaluate the parameterized inventories is maybe not the most intuitive, and could change in the future. We use our ParameterSet as a function, and call it with a list of our exchanges:

In [22]:
ps([exc, exc2])
Out[22]:
[Exchange: 31.41592653589793 kilo Becquerel 'Plutonium-alpha' (kilo Becquerel, None, ('air',)) to 'first parameterized inventory' (kilogram, GLO, None)>,
 Exchange: 13.607831626983932 kilogram 'Diethylamine' (kilogram, None, ('air', 'lower stratosphere + upper troposphere')) to 'first parameterized inventory' (kilogram, GLO, None)>]

Our exchanges have been evaluated, and the amount field has been added. This is the basic form of a parameterized inventory.

Global parameters

We can also have database-level parameters which can be reference by any activity, even one without it's own local parameters.

Currently we have no global parameters:

In [23]:
db.parameters
Out[23]:
Database parameter set with 0 values

Let's add a constant, a variable, and a formula:

In [26]:
from stats_arrays import *

db.parameters['constant'] = {'amount': 42}
db.parameters['variable'] = {
    'amount': 1, 
    'loc': 1,  # Uncertainty parameters
    'minimum': 0, 
    'maximum': 3, 
    'uncertainty type': TriangularUncertainty.id
}
db.parameters['formula'] = {'formula': 'constant + variable'}
In [28]:
act2 = db.new_activity("second", name="second parameterized inventory", unit="kilogram")
exc3 = act2.new_exchange(input=Database("biosphere3").random(), type='biosphere')
exc3['formula'] = 'formula + 7'

When evaluating with global parameters, we still have to pass our local parameter set. Because we don't have any, we can pass an empty dictionary.

Note that we have to evaluate the global parameters.

In [29]:
ps = ParameterSet({}, global_params=db.parameters.evaluate())
ps([exc3])
Out[29]:
[Exchange: 50 kilogram 'Boron' (kilogram, None, ('water',)) to 'second parameterized inventory' (kilogram, GLO, None)>]

This is the current state of parameterized inventories in Brightway2. One important caveat is that parameterized inventories dont work yet with Monte Carlo sampling - it is not simple to do this in an efficient way, and the methodology is still being thought about.

For anything complicated, it is (again) recommended to write a separate model in Python and use that model to dynamically generate life cycle inventories.

In [ ]: