Problem adding an exchange to a process using the python API

Post Reply
mati
Posts: 6
Joined: 13 Sep 2017 11:38

Problem adding an exchange to a process using the python API

Post by mati » 13 Sep 2017 12:25

Hi,

I'd like to use the openLCA python API to modify models and run calculations in bulk. I'm starting slowly, using the openLCA python tutorial on GitHub (many thanks for that).
All I'm trying to do for the moment is add an exchange to a process. I'm running a script in the python-developer-tool-console in openLCA 1.4.2 on Mac OS X Yosemite (10.10.5). Note that I could not try with the latest openLCA version because I don't have the proper rights to install new software on this machine, but if it's likely to cause the problem, this would give me a strong case to have it installed.

The script below runs but when I open the process no input exchange has been added. See the log below.
Note: a couple of days ago, the input exchange actually did appear in the process sheet but with the "Unit" column empty (see below more issues regarding units) and openLCA became unstable and crashed. I had to retype the python script (so I am not 100% sure it was the same as below) and could not reproduce that behaviour since.

Can someone see what I'm doing wrong?
Scripting openLCA would be so powerful, I really want it to work...

Best wishes,
Mathieu

python script:

Code: Select all

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
from org.openlca.core.database import FlowDao

if __name__ == '__main__':
    db_dir = File('/Users/mathieusa/openLCA-data-1.4/databases/phd_ei22_ist_test')
    db = Db(db_dir)
    
    dao_p = ProcessDao(db)
    dao_f = FlowDao(db)

    p = dao_p.getForName("Electricity mix, DE, 2010")[0]
    f = dao_f.getForName("Electricity, wind, onshore, MIX IST")[0]
    
    p_input = model.Exchange()
    p_input.input = True
    p_input.flow = f
    #p_input.unit = MWh
    p_input.amountValue = 1.0
    p_input.flowPropertyFactor = f.getReferenceFactor()    
    
    dao_p.update(p)
    
    db.close()
log file:

Code: Select all

47960945 	Worker-18 	INFO 	org.openlca.core.database.derby.DerbyDatabase 	initialize database folder /Users/mathieusa/openLCA-data-1.4/databases/phd_ei22_ist_test, create=false
47961289 	Worker-18 	INFO 	org.openlca.core.database.derby.DerbyDatabase 	exception: 45000
47961289 	Worker-18 	INFO 	org.openlca.core.database.derby.DerbyDatabase 	database closed
If I uncomment the following line in the script above

Code: Select all

p_input.unit = MWh
I get the following error:

Code: Select all

48113926 	Worker-19 	INFO 	org.openlca.core.database.derby.DerbyDatabase 	initialize database folder /Users/mathieusa/openLCA-data-1.4/databases/phd_ei22_ist_test, create=false
48114004 	Worker-19 	ERROR 	org.openlca.app.devtools.python.Python 	failed to evaluate script
Traceback (most recent call last):
     File "<string>", line 59, in <module>
    NameError: name 'MWh' is not defined
    
     at org.python.core.Py.NameError(Py.java:256)
     at org.python.core.PyFrame.getname(PyFrame.java:257)
     at org.python.pycode._pyx9.f$0(<string>:65)
     at org.python.pycode._pyx9.call_function(<string>)
     at org.python.core.PyTableCode.call(PyTableCode.java:166)
     at org.python.core.PyCode.call(PyCode.java:18)
     at org.python.core.Py.runCode(Py.java:1312)
     at org.python.core.Py.exec(Py.java:1356)
     at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:222)
     at org.openlca.app.devtools.python.Python.doEval(Unknown Source)
     at org.openlca.app.devtools.python.Python.eval(Unknown Source)
     at org.openlca.app.devtools.python.PythonEditor.lambda$0(Unknown Source)
     at org.openlca.app.devtools.python.PythonEditor$$Lambda$36/961994506.run(Unknown Source)
     at org.openlca.app.WrappedJob.run(Unknown Source)
     at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54) 
 

If I put the input unit in quotes like this in the script above

Code: Select all

p_input.unit = "MWh"
I get the following error:

Code: Select all

48153240 	Worker-16 	INFO 	org.openlca.core.database.derby.DerbyDatabase 	initialize database folder /Users/mathieusa/openLCA-data-1.4/databases/phd_ei22_ist_test, create=false
48153256 	Worker-16 	ERROR 	org.openlca.app.devtools.python.Python 	failed to evaluate script
Traceback (most recent call last):
     File "<string>", line 59, in <module>
    TypeError: can't convert 'MWh' to org.openlca.core.model.Unit
    
     at org.python.core.Py.TypeError(Py.java:231)
     at org.python.core.Py.tojava(Py.java:536)
     at org.python.core.PyBeanProperty._doset(PyBeanProperty.java:63)
     at org.python.core.PyObject.__set__(PyObject.java:3731)
     at org.python.core.PyObject.object___setattr__(PyObject.java:3795)
     at org.python.core.PyObject.object___setattr__(PyObject.java:3785)
     at org.python.core.PyObject$object___setattr___exposer.__call__(Unknown Source)
     at org.python.core.PyObjectDerived.__setattr__(PyObjectDerived.java:1004)
     at org.python.pycode._pyx10.f$0(<string>:65)
     at org.python.pycode._pyx10.call_function(<string>)
     at org.python.core.PyTableCode.call(PyTableCode.java:166)
     at org.python.core.PyCode.call(PyCode.java:18)
     at org.python.core.Py.runCode(Py.java:1312)
     at org.python.core.Py.exec(Py.java:1356)
     at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:222)
     at org.openlca.app.devtools.python.Python.doEval(Unknown Source)
     at org.openlca.app.devtools.python.Python.eval(Unknown Source)
     at org.openlca.app.devtools.python.PythonEditor.lambda$0(Unknown Source)
     at org.openlca.app.devtools.python.PythonEditor$$Lambda$36/961994506.run(Unknown Source)
     at org.openlca.app.WrappedJob.run(Unknown Source)
     at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
 

mati
Posts: 6
Joined: 13 Sep 2017 11:38

Re: Problem adding an exchange to a process using the python API

Post by mati » 15 Sep 2017 12:37

Update on my original post:
I tried the same python scripts with openLCA 1.6.3 on a Linux machine (ubuntu 16.04) and got the same errors as reported in the original post.

mati
Posts: 6
Joined: 13 Sep 2017 11:38

Re: Problem adding an exchange to a process using the python API

Post by mati » 18 Sep 2017 13:23

Another update to my post:
I found a workaround for my problem but the general issue with "exchange.unit = MWh" (or MJ or whatever) throwing an error remains.
Here's what I did to be able to add an exchange to a process:

1) I realised that I had forgotten to add the exchange before updating the process (have to use "process.exchanges.add(exchange)"). This is why no new exchange appeared in my process.

2) However, I still had the issue with the unit: if I didn't specify the unit, the exchange would appear in the process sheet but without any unit. If I specified a unit by hand, I would get an error (see original post). In my case the unit of the new input exchange should be the same as the unit of the reference output exchange of the process. So the workaround was to look for that output exchange and pass its unit to the input exchange when building it.

Note: this worked also because I could use the utility functions defined in "util.py" on the GitHub openlca-python-tutorial. Originally I was using openLCA 1.4.2 and couldn't import the utility functions but now I'm using openLCA 1.6.3 and it works. For more details on that issue see this other thread on the forum: Import error when using the python API.

Finally, here's the code for my functioning script (a.o. I changed a few variable names compared to my original post, to better keep track of what is a flow, an exchange etc.):

Code: Select all

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

if __name__ == '__main__':
    db_dir = File('/Users/mathieusa/openLCA-data-1.4/databases/phd_ei22_ist_test')
    db = Db(db_dir)
    
    # PROCESSES
    # Find the process to be modified
    dao_p = ProcessDao(db)
    p = dao_p.getForName("Electricity mix, DE, 2010")[0]
    
    # FLOWS
    # f_in is the input flow to be added to the process
    f_in = util.find(db, model.Flow, 'Electricity, wind, onshore, MIX IST') 
    # f_out is the output flow (reference product) of the process
    f_out = util.find(db, model.Flow, 'Electricity mix, DE, 2010')
    
    # 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 = MWh
    e_in.amountValue = 1.0
    e_in.flowPropertyFactor = f_in.getReferenceFactor()    
    
    # Add the input exchange to the process and update the process 
    p.exchanges.add(e_in)
    util.update(db, p)
    
    db.close()

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 1 guest