brightwaypython-3.12

Brightway 2.5 - Use of datapackage to compare scenarios with my own database and Ecoinvent


I am trying to create some code to compare scenario with the same database (actvities and exchanges). The value of the exchanges will be updated on each run.

I wanted to avoid using "exc['amount'] and exc.save()" for each exchange. And I understand that datapackage could do the trick faster, as in this notebook

I end up with the following code for an small database example but I get the following error : bw2calc.errors.NonsquareTechnosphere: Technosphere matrix is not square: 1 activities (columns) and 4 products (rows).

At the end I will have more than 50 scenarios and a database with around 70 new activities.

Does anyone have an example of code with a datapackage and the Ecoinvent database? I have the idea that my error comes from the link between Ecoinvent and my database.

I work with Python 3.12.2 and the following package of Brightway 2.5:

bw2calc                   2.0.dev18                  
bw2data                   4.0.dev46                
bw2io                     0.9.dev30                                     
bw_processing             0.9.6     

    
import bw2data as bd
import bw2io as bi
import numpy as np
import bw2calc as bc
import bw_processing as bwp


bd.projects.set_current("Save3")

# ====== Import ecoinvent ======
if 'Ecoinvent_3.9.1_apos' in bd.databases:
    print("Database has already been imported.")

# ======  Database creation ====== 
MyDB = bd.Database('MyDB')
MyDB.register()

eidb = bd.Database('Ecoinvent_3.9.1_apos')
eidb.order_by='name'
bio = bd.Database("biosphere3")

# ======  Create New Activity ====== 
Prod_Sirop = MyDB.new_activity(code='Psirop', name="Production de sirop", unit="kilogram",
                            comment="production de sirop sur l'année de référence (2019)")
Prod_Sirop.save()

electricityMix_FR = bd.utils.get_node(database = 'Ecoinvent_3.9.1_apos', name = 'market for electricity, medium voltage', location = 'FR', unit = 'kilowatt hour')
Prod_Sirop.new_exchange(input=electricityMix_FR.key, amount=0,unit="kWh", type="technosphere").save()

market_selsNACl = bd.utils.get_node(database = 'Ecoinvent_3.9.1_apos', name = 'market for sodium chloride, powder', location = 'GLO', unit = 'kilogram')
Prod_Sirop.new_exchange(input=market_selsNACl.key, amount=50000, unit="kilogram", type="technosphere").save()

SiropProduction = 20000000 # m3/an
Prod_Sirop.new_exchange(input=Prod_Sirop, amount=SiropProduction, unit="cubic meter", type="production").save()
Prod_Sirop.save()


# ======  create datapackage ====== 
dp_newscenario = bwp.create_datapackage()

t_indices= np.array([(electricityMix_FR.id, Prod_Sirop.id),
                     (market_selsNACl.id, Prod_Sirop.id)],
                    dtype=bwp.INDICES_DTYPE)
t_data =np.array([2000, 4000])

# Create vector for a new scenario
dp_newscenario.add_persistent_vector(
    matrix='technosphere_matrix',
    indices_array=t_indices,
    data_array=t_data,
    flip_array=np.array([True, True]),
    name='Sc1')

# ======  Do lci/ lcia ====== 
lca = bc.LCA(
    demand={Prod_Sirop: 1},
    data_objs=[dp_newscenario],
    use_distributions=False,
    use_arrays=True,
    method=('ReCiPe 2016 v1.03, midpoint (H)','climate change','global warming potential (GWP1000)'))

lca.lci()
lca.lcia()


Solution

  • when you define the LCA, I think you need more than the datapackage you've created, which tells what needs to be modified in the technosphere matrix. The LCA object needs the rest of the information.

    Check this example

    Try running fu, data_objs , _ = bd.prepare_lca_inputs before the lca to get all the rest of the info and then fed it to the lca object.

    I also suspect that you're missing some square brackets in your t_data. note that the example you're using it is only modifying one exchange and you're modifying two. Try first modifying just one and then you make the example more complicated.