Parameters - manual creation

This notebooks illustrates how to manually create parameterized datasets in Brightway2. You should be familiar with the input data types listed in the technical documentation.

In [1]:
from brightway2 import *
from bw2data.parameters import ActivityParameter, DatabaseParameter, ProjectParameter, Group

Create a new project for this notebook

In [2]:
if "parameters - manual creation" in projects:
    projects.delete_project("parameters - manual creation", True)
projects.set_current("parameters - manual creation")

We don't have any parameters of any kind yet

In [3]:
len(parameters)
Out[3]:
0

Some parameters are database-specific, so we need to create a new database

In [4]:
db = Database("example")
db.register()

Similarly, we need some activities and exchanges. We don't need the correct value for the amount field, as this will be calculated by the formula.

In [5]:
a = db.new_activity(code="A", name="An activity")
a.save()
b = db.new_activity(code="B", name="Another activity")
b.save()
a.new_exchange(amount=0, input=b, type="technosphere", formula="foo * bar + 4").save()

for exc in a.exchanges():
    print(exc)
Exchange: 0 None 'Another activity' (None, GLO, None) to 'An activity' (None, GLO, None)>

We are now ready to create some parameters. These can be defined at three different levels: project-level, database-level, and activity-level. Parameters are also grouped together, but the group names for project- and database-level parameters are generated automatically.

Create some project-level parameters; amounts are evaluated when the parameters are entered.

In [6]:
project_data = [{
    'name': 'foo',
    'formula': 'green / 7',
}, {
    'name': 'green',
    'amount': 7
}]
parameters.new_project_parameters(project_data)

for param in ProjectParameter.select():
    print(param, param.amount)
Project parameter: foo 1.0
Project parameter: green 7.0

We can do a similar thing for database-level parameters. Note that these parameters automatically get access to the project-level parameter variables.

Note that here you have to specify which database the parameters belong to.

In [7]:
database_data = [{
    'name': 'red',
    'formula': '(foo + blue ** 2) / 5',
}, {
    'name': 'blue',
    'amount': 12
}]
parameters.new_database_parameters(database_data, "example")

for param in DatabaseParameter.select():
    print(param, param.amount)
Database parameter: example:red 29.0
Database parameter: example:blue 12.0

And again for activity-level parameters. These also get access to project- and database-level variables, but activity-level parameters can also refer to other activity-level variables (though this capability is not shown in this example). You must specify such relationships explicitly using Group.order:

Group.create(name="One")
Group.create(name="Two", order=['One'])

You should therefore make sure to enter things in the right order, and create the group with the right order; otherwise you will get errors. Don't worry - you can't wreck your database (I think :), there are a lot of checks to prevent improper data from being saved.

Group names are created automatically if you use new_activity_parameters.

In [8]:
activity_data = [{
    'name': 'reference_me',
    'formula': 'sqrt(red - 20)',
    'database': 'example',
    'code': "B",
}, {
    'name': 'bar',
    'formula': 'reference_me + 2',
    'database': 'example',
    'code': "A",    
}]
parameters.new_activity_parameters(activity_data, "my group")

for param in ActivityParameter.select():
    print(param, param.amount)
Activity parameter: my group:reference_me 3.0
Activity parameter: my group:bar 5.0

We have entered the activity parameters, but haven't told Brightway to activate the exchanges and their formulas. Therefore, the amount is still zero:

In [9]:
for exc in a.exchanges():
    print(exc)
Exchange: 0 None 'Another activity' (None, GLO, None) to 'An activity' (None, GLO, None)>

Activation is a two-step process: first, tell the parameter code that these exchanges have formulas:

In [10]:
parameters.add_exchanges_to_group("my group", a)

Then calculate the "activated" formula values:

In [11]:
ActivityParameter.recalculate_exchanges("my group")

We now get the correct result, for a formula that needed calculations at all parameter levels.

In [12]:
for exc in a.exchanges():
    print(exc.amount, exc.input, exc.output)
9.0 'Another activity' (None, GLO, None) 'An activity' (None, GLO, None)