openlca-python-tutorial icon indicating copy to clipboard operation
openlca-python-tutorial copied to clipboard

Select flow in database by name and provider

Open gvoigt opened this issue 7 years ago • 5 comments

Getting a flow from the database elcd_3_2_greendelta_v2_16 is no problem with the following function

def find(db, clazz, name):
    """ Find something by name"""
    dao = Daos.createBaseDao(db, clazz)
    for item in dao.getAll():
        if item.name == name:
            return item

But if the flow has several providers how can I pick one? For example I can get the flow transport in t*km but I cannot choose the provider Lorry transport, Euro 0, 1, 2, 3, 4 mix, 22 t total weight, 17,3t max payload - RER. I don't even know how to verify which provider is assigned to the flow.

gvoigt avatar Jan 04 '18 14:01 gvoigt

The providers cannot be attached to a flow but to an exchange. An exchange is an input or output of a flow in a process. And there it is just a marker for the product system completion algorithms. In general, a provider of a product is a process with this product in an output exchange (and since openLCA 1.6+ a process with a provider of a waste treatment service is a process with a waste flow as input).

There are some helper methods in the openLCA core API for finding providers of flows, e.g.

from org.openlca.core.database import FlowDao, ProcessDao
from org.openlca.core.matrix.cache import FlowTypeTable, ProcessTable

f_table = FlowTypeTable.create(db)
p_table = ProcessTable.create(db, f_table)

my_product = FlowDao(db).getForName('p1')[0]
p_dao = ProcessDao(db)

for process_id in p_table.getProviders(my_product.id):
    process = p_dao.getForId(process_id)
    log.info('{}', process.name)

msrocka avatar Jan 15 '18 15:01 msrocka

I tried to use your @msrocka code regarding the implementation of providers for flows in a process. The implementation of a flow in the existing process at my database works find, despite the fact that I can´t implement it with the corresbonding unit [t*km]. `

from org.openlca.core.database.derby import DerbyDatabase as Db
from java.io import File
import org.openlca.core.model as model
from org.openlca.core.database import ProcessDao
import util
from org.openlca.core.database import FlowDao
from org.openlca.core.matrix.cache import FlowTypeTable, ProcessTable

if __name__ == '__main__':
db_dir = File('C:\\Users\\user\\openLCA-data-1.4\\databases\\test_ProBas')
db = Db(db_dir)

# PROCESSES
# Find the process to be modified
dao_p = ProcessDao(db)
p = dao_p.getForName("Steel production")[0]

# FLOWS
# f_in is the input flow to be added to the process
f_in = util.find(db, model.Flow, 'Guetertransport-Dienstleistung (LKW-2010-mix-DE)') 
# f_out is the output flow (reference product) of the process
f_out = util.find(db, model.Flow, 'Steel production')

km = model.Unit()
# EXCHANGES
# e_out is the output exchange of the process
e_out = util.find_exchange(f_out, p)
# e_in is the new input exchange to be added to the process
e_in = model.Exchange()
e_in.input = True
e_in.flow = f_in
#e_in.unit = e_out.unit
e_in.unit = km
e_in.amountValue = 1.0
e_in.flowPropertyFactor = f_in.getReferenceFactor()  



f_table = FlowTypeTable.create(db)
p_table = ProcessTable.create(db, f_table)

my_product = FlowDao(db).getForName("Guetertransport-Dienstleistung (LKW-2010-mix-DE)")[0]

for e_in in p_table.getProviders(my_product.id):
    process = dao_p.getForId(e_in)
    log.info('{LKW-2010-mix-DE 2010 (System)}', process.name)    
    
    
# Add the input exchange to the process and update the process 
p.exchanges.add(e_in)
util.update(db, p)

db.close()

` I always get the following error:

console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp0.
log4j:WARN No appenders could be found for logger (org.openlca.core.database.derby)
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Traceback (most recent call last):
File "C:\Users\user\eclipse-workspace\test\Database.py", line 45, in <module>
        for e_in in p_table.getProviders(my_product.id):
AttributeError: 'org.openlca.core.matrix.cache.ProcessTable' object has no attribute 'getProviders'

` What am I doing wrong here? Thanks

Brotrand avatar Jan 22 '18 09:01 Brotrand

You are using openLCA 1.6, right? The method getProductProviders was renamed to getProviders in version 1.7 (as we now also support "providers of waste treatment services"). You can get the current beta version of openLCA 1.7 from the openLCA web site. Or you could try the getProductProviders method with openLCA 1.6.

msrocka avatar Jan 22 '18 12:01 msrocka

With getProductProviders it worked. Thank you Yes, I am still using openLCA 1.6 and I will try to switch to the latest version.

Has the command for log.info('{LKW-2010-mix-DE 2010 (System)}', process.name) also changed? Because now, I get the error: `

Traceback (most recent call last):
File "C:\Users\user\eclipse-workspace\test\Database.py", line 47, in <module>
        log.info('{LKW-2010-mix-DE 2010 (System)}', process.name) 
NameError: name 'log' is not defined

`

Brotrand avatar Jan 22 '18 13:01 Brotrand

Update: As I don´t have much experience with programming, I don´t know whether the different code I wrote is helpful. Nevertheless, I get the same output. I could update an existing process with a new Input (Flow with the corresbonding provider).

from org.openlca.core.database.derby import DerbyDatabase
from java.io import File
import org.openlca.core.model as model
from org.openlca.core.database import ProcessDao
import util

if __name__ == '__main__':
    folder = 'C:\\Users\\user\\openLCA-data-1.4\\databases\\test_ProBas'
    db = DerbyDatabase(File(folder))

    # Find the process to be modified
    dao = ProcessDao(db)
    p = dao.getForName("Steel production")[0]

# insert Flow and Provider
    transport = util.find(db, model.Flow, 'Guetertransport-Dienstleistung (LKW-2010-mix-DE)') 
    LKW = util.find(db, model.Process, 'LKW-2010-mix-DE 2010 (System)')
    t_in = util.create_exchange(transport, 1.0, is_input=True)
    t_in.defaultProviderId = LKW.id

    p.exchanges.add(t_in)
    util.insert(db, t_in)

    dao.update(p)
    db.close()

Brotrand avatar Jan 22 '18 14:01 Brotrand