xraylarch icon indicating copy to clipboard operation
xraylarch copied to clipboard

Using io.save() in Jupyter Lab

Open BGerwe opened this issue 4 years ago • 3 comments

I'm not sure if this is truly a bug or my misunderstanding. For what it's worth I'm using larch 0.9.47 in JupyterLab 2.2.5 with Python 3.7.6 on Windows 10, and I have replicated this problem in both a "fresh" conda env and the base env.

When trying to save a Group I get the following error:

~\Anaconda3\lib\site-packages\larch\io\save_restore.py in save(fname, _larch, *args, **kws)
     48     for name, arg in zip(names, args):
     49         buff.append("#=> %s" % name)
---> 50         buff.append(json.dumps(encode4js(arg, grouplist=grouplist)))
     51     buff.append("")
     52     with open(fname, "w") as fh:

~\Anaconda3\lib\site-packages\larch\utils\jsonutils.py in encode4js(obj, grouplist)
     23     if grouplist is not None:
     24         for g in grouplist:
---> 25             _groups[g.__name__] = g
     26 
     27     if isinstance(obj, np.ndarray):

AttributeError: 'tuple' object has no attribute '__name__'

A minimal example based on the Jupyter Notebook example:

import larch
from larch import Interpreter
mylarch = Interpreter()
from larch.io import read_athena
project = read_athena('fe_athena.prj')
fe2o3 = project.fe2o3_rt1_xmu
larch.io.save('test.', fe2o3, _larch=mylarch)

Digging into the error I found that grouplist contains a list of tuples from _larch.symtable._sys.saverestore_groups

[(larch.xrf.roi.ROI, larch.xrf.mca.MCA),
 (larch.xafs.diffkk.diffKKGroup,
  larch.xafs.feffrunner.FeffRunner,
  larch.xafs.feffdat.FeffDatFile,
  larch.xafs.feffdat.FeffPathGroup,
  larch.xafs.feffit.TransformGroup,
  larch.xafs.feffit.FeffitDataSet)]

My ultimate goal is looping through a list of XAFS spectra, using pre_edge and autobk, and then saving the results (either all together or in separate files). Maybe there is a simpler way to accomplish this?

BGerwe avatar Sep 07 '20 08:09 BGerwe

I figured out the solution for my use-case by using Athena project Groups. However, I'll keep the issue open unless it is expected behavior.

To show this behavior isn't tied to anything to Athena project Groups, here's another minimal example (loosely based on #58:

import larch
from larch import Group, Interpreter
from larch import io
    
mylarch = Interpreter()

x = [1, 2, 3, 4]
y = [0.5, 1, 1, 0.1]
z = ['a', 'b', 'c', 'd']
g = Group('mygroup', x=x, y=y, z=z)

io.save('test.lsav', g, _larch=mylarch)

BGerwe avatar Sep 07 '20 23:09 BGerwe

@BGerwe Yeah, saving a Project file should be easy with projectfile.save(). And then you have a resulting file that can be easily loaded into Athena or XAS_Viewer - that would definitely be the way to go.

The io.save() was meant to try to replace Ifeffit's save() function, which would basically save the state of the interpreter to be reloadable. This turns out to be much harder with something as complex as Python. So, it's sort of a "known wart". I'm OK with leaving this open a nudge to do something about it - maybe remove save() altogether or maybe "save the simple things that can be saved" (as this is almost always enough).

newville avatar Sep 08 '20 13:09 newville

@newville @BGerwe doing some housekeeping with this issue, as it is relatively simple to solve. I propose to stick with Athena project files only to store/restore the state of a Larch project:

  • [ ] check AthenaProject().save() works correctly also outside xas_viewer
  • [ ] io.save() save to Athena project file
  • [ ] io.restore() restore from Athena project file
  • [ ] add minimal documentation
  • [ ] add testing

maurov avatar Jun 14 '21 04:06 maurov