JuliaRheology / RHEOS.jl

RHEOS - Open Source Rheology data analysis software
MIT License
40 stars 9 forks source link

Python interface to RHEOS #116

Open akabla opened 3 years ago

akabla commented 3 years ago

I made an attempt to access RHEOS from Python using PyJulia. This seems to work well enough, although I had to call Julia with certain options to get it to work. See below.

It would be good to explore further what PyJulia can do. Very promising so far.

(base) alexandre@albacore:~$ python
Python 3.7.6 (default, Jan  8 2020, 19:59:22) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from julia import Julia
>>> jl = Julia(runtime="/home/alexandre/Software/julia-1.6.2/bin/julia",compiled_modules=False)
>>> from julia import RHEOS
>>> RHEOS.Maxwell
<PyCall.jlwrap 
Model name: maxwell

Free parameters: η and k

                ___
            _____| |________╱╲  ╱╲  ╱╲  ___
                _|_|          ╲╱  ╲╱  ╲╱
                  η                  k
               >
>>> a=RHEOS.timeline(t_start=0,t_end=10)
>>> a
t = 0.0 0.04    0.08    0.12    0.16    0.2 0.24    0.28    0.32    0.36    ...
<PyCall.jlwrap >
>>> a.t[2]
0.08
akabla commented 3 years ago

The use of Unicode symbols makes it more complicated to call RHEOS from the Python REPL. The epsilon symbol seems in particular to be problematic for some reason.

>>> d = RHEOS.RheoTimeData(t=[1,2,3,4])

>>> d = RHEOS.RheoTimeData(t=[1,2,3,4], σ=[1,2,3,4])

>>> d = RHEOS.RheoTimeData(t=[1,2,3,4], ϵ=[1,2,3,4])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: <PyCall.jlwrap (in a Julia function called from Python)
JULIA: MethodError: no method matching RHEOS.RheoTimeData(; t=[1, 2, 3, 4], ε=[1, 2, 3, 4])
Closest candidates are:
  RHEOS.RheoTimeData(; ϵ, σ, t, comment, savelog, log) at /home/alexandre/.julia/dev/RHEOS/src/definitions.jl:73 got unsupported keyword argument "ε"

This may be due to the fact that there are different symbols for epsilon that python aggregates together, but not julia:

julia> ε = 1
1
julia> ϵ
ERROR: UndefVarError: ϵ not defined
>>> ε = 1
>>> ϵ
1

Python interprets in the same way \epsilon and \varepsilon, but not Julia.

akabla commented 3 years ago

Here is a Python code sample that works fine so far. Translation to unicode is in place. Modelfit takes parameters as dictionary too which are better integrated with python. getparams also has a new keyword to return a dictionary rather than a namedtuple. It seems to be more or less usable now.

from julia import Julia
jl = Julia(runtime="/home/alexandre/Software/julia-1.6.2/bin/julia",compiled_modules=False)
from julia import RHEOS as rh

data = rh.importcsv("C1_S_0A5_90_rheos.csv", time = 1, strain = 2, stress = 3)
model=rh.modelfit(data, rh.FractD_Maxwell, rh.stress_imposed, p0={'beta':0.05, 'c_beta':0.05, 'eta':10.0})
print(rh.getparams(model, unicode=False, dict=True))

data_stress = rh.extract(data, rh.stress_only)
data_fit = rh.modelpredict(data_stress, model)

from matplotlib import pyplot as plt

plt.plot(rh.gettime(data_fit),rh.getstrain(data))
plt.plot(rh.gettime(data_fit),rh.getstrain(data_fit))
plt.show()  
akabla commented 3 years ago

Rather than adding keywords in functions such as getparams to provide dictionaries for python users, it may be simpler to include helper functions that can easily and convert namedtuples and dictionaries. New syntaxes would be:

model=rh.modelfit(data, rh.FractD_Maxwell, rh.stress_imposed, p0=rh.namedtuple(beta=0.05, c_beta=0.05, eta=10.0) )

rh.dict(rh.getparams(model, unicode=False))

Note that Julia's NamedTuples are functional in python and the content can be easily extracted. They are just difficult to create from python.

akabla commented 3 years ago

Function taking symbols as parameters should also accept strings, see modelfit for instance. 20bd63b6407acf0ac5d51f417c32db95c66a57e8

akabla commented 3 years ago

strainfunction and similar take a function as parameter. Not sure how these could be ported easily. Probably best to get array in Numpy and add it to the RheoTimeData directly.

akabla commented 3 years ago

There are currently issues with Python 3.9. https://github.com/JuliaPy/pyjulia/issues/444 I confirm I can't get it to work on my new linux install with Python 3.9.7 and Julia 1.6.2. Reverting to 3.8 on conda solves the problem, but the setup seems a bit fragile. I hope this can be fixed. Python 3.10 is coming soon...

akabla commented 3 years ago

Here is a test repo for Binder that installs what's needed for Rheos with Python. It takes a long time to start though. https://github.com/akabla/BinderTest

Binder