0 votes
1.7k views

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:

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:


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 p_input.unit = MWh I get the following error:

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 p_input.unit = "MWh" I get the following error:


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)

 

in openLCA by
by
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.
by

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: https://forum.openlca.org/viewtopic.php?f=16&t=32919 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.):


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()

 

Please log in or register to answer this question.

...