Negative lognormal results in Monte Carlo simulation with Brightway2

374 Views Asked by At

I can't figure out how to set up BW2 to get negative values in a MC simulation for a parameter with lognormal distribution, e.g. to model negative emissions. Example:

from brightway2 import *
import numpy as np


mydb = Database('mydb')

mydb.write({
    ('mydb', 'Some activity'): {
        'name': 'Some activity',
        'unit': 'kWh',
        'exchanges': [{
            'input': ('mydb', 'Carbon dioxide'),
            'amount': 20, # positive!
            'unit': 'kg',
            'type': 'biosphere', 
            'uncertainty type' : 2,
            'loc' : np.log(20), 
            'scale' : 1.01 
            }]
    },
    ('mydb', 'Carbon dioxide'): {'name': 'Carbon dioxide', 'unit': 'kg', 'type': 'biosphere'}
    })

exc = list(mydb.get('Some activity').exchanges())[0]
exc.as_dict()
exc.random_sample(n=10)  

This works. I get:

Out[8]: 
array([ 25.20415107,  17.48476344,  16.98842921,   3.79548038,
    12.54165042,  27.93752377,   7.57070571,  43.22285015,
    48.44984804,  13.83083672]) # everything fine

Now let's assume I want to get the same values but negative: array([ -25.20415107, -17.48476344, etc. ... because I assume I have a carbon uptake of -20 kg Carbon dioxide. If I write 'amount': -20 I get a weird result:

Out[9]: 
array([   0.73060359,   36.69825867,    5.71416558,   10.78119397,
     16.24447705,    2.96507057,    6.73564118,   19.24411117,
      7.23110067,  126.42690714])

I know lognormal distributions can't be negative, but what I was expecting is that the distribution was calculated on positive values based on the 'loc' and 'scale' information and then reversed based on the 'amount' information. This is necessary to perform MC on an inventory with negative emissions. Any clue? Thanks

1

There are 1 best solutions below

1
On BEST ANSWER

There were two problems preventing expected behaviour:

  1. It isn't enough to give a negative value in the field amount; the RNG code is in the stats_arrays library, and you must set the field negative to True (see docs).
  2. There was a bug in brightway2-data, fixed in 7e3341c and release 2.4.6, that prevented the key negative from being used in exchange.uncertainty.

In general, when importing data from other formats the negative field is set automatically, e.g. SimaPro CSV, Ecospold 1. Moreover, when a database is processed to a parameter array, the negative field is also always set from the amount field. The difference in this case is that you are calling functions from stats_arrays directly, instead of through brightway2-calc.

Adding the negative field on an up-to-date installation:

from brightway2 import *
import numpy as np
projects.set_current("SO 45935773")
bw2setup()

mydb = Database('mydb')
gwp = ('IPCC 2013', 'climate change', 'GWP 100a')
co2 = get_activity(('biosphere3', '349b29d1-3e58-4c66-98b9-9d1a076efd2e'))

mydb.write({
    ('mydb', 'Some activity'): {
        'name': 'Some activity',
        'unit': 'kWh',
        'exchanges': [{
            'input': co2.key,
            'amount': -20, # negative
            'negative': True,
            'unit': 'kg',
            'type': 'biosphere', 
            'uncertainty type' : 2,
            'loc' : np.log(20), 
            'scale' : 1.01 
        }]
    }
})

exc = list(mydb.get('Some activity').exchanges())[0]
exc.random_sample(n=10)  

Produces the expected behaviour:

array([ -3.24683872,  -5.01873359, -31.54532003, -40.59523805,
       -54.00447092,  -6.11459063, -41.5250442 ,  -8.05295075,
       -31.46077832, -29.8769442 ])