Hi Sean,

On Tue, Nov 1, 2016 at 1:39 PM, Sean Fackler <swfack...@lbl.gov> wrote:

> Dear Matt,
>
> I’ve been working to implement Larch functions as a Python library. During
> the implementation I found a number of things I needed to do including:
>
>
You can use Larch functions from Python, of course.   Normally, you'd do
something like

    import larch
    from larch_plugins.xafs import pre_edge, mback



> 1. Identifiying a functions’ python callable name, i.e. _group as a python
> callable function instead of group as the larch function.
>

I'm not sure I understand.  You shouldn't need "a function's python
callable name", you should just need the function.  Maybe I misunderstand.

If you need a larch Group, you should be able to do
    import larch
    agroup = larch.Group(name='mygroupname', xdata = range(100),
label='hello')




>
> 2. The need to pass '_larch = mylarch’ in the said function or I get the
> 'AttributeError: 'NoneType' object has no attribute ‘symtable’ ‘
>
>
Yes, many of the larch plugin functions either require or are much happier
with an instance of a larch session passed in as the '_larch' argument.
It's kind of a feature ;).


> 3. The need to run the script through the Python console as oppose to
> running as a script.
>
>
I'm not sure I understand what this means.  You should be able to run a
python program from any environment.


> You can see my sample script with data attached. Keep in mind I am a
> Python novice. So for point 3 in particular *I don’t understand the
> difference between running some selected code in the Python console and
> running the whole script in the shell *(I am using PyCharm CE). I checked
> my Python interpreter with sys.executable (path) and sys.version_info
> (version) which are the same between the console and interpreter which were
> initial issues I found online. Is the interpreter somehow not seeing the
> xraylarch library?
>

Hmm, that doesn't make a lot of sense to me either.  What errors do you get
when you run your script?

I don't use PyCharm, so maybe that's not seeing all of the modules from
anaconda?   Is PyCharm seeing your  anaconda distribution?

A few comments on your script:
   a) there should be no need to do a os.chdir() to any folder, especially
not to source code folders.
   b) doing   from xxx import *  is bound to lead to confusion.  Import
what you need, and don't import what you don't need.


Finally: 1. Is there an easier way to use the larch functions as a python
> library?
>

Is the above suggestion better?


> 2. Is a larch group basically a python dictionary?
>

Actually, it's basically an empty class:

    class Group:
        def __init__(self, **kws):
             ....

    mygroup = Group()
    mygroup.x = 1
    mygroup.y = 'a string'

even in more detail, it's an empty class.  In most cases it would probably
be OK to substitute almost any class instance as a Group.

In Larch, I tend to make as many things as possible "group-like" so that
accessing elements is easy.


> If so, this could be made clearer in the documentation. I am interested to
> contribute to the documentation if that’s of interest/help.
>
>
Sure!  The docs are definitely in need of some serious work.



> I am running MacOS Sierra 10.12.1 on a mid-2015 15" MacBook Pro with
> Python 2.7.
>
> Ron and Alpha: Maybe you have some ideas to the above points?
>
> Thanks everyone for any help.
>
> Sean
>
>
The attached modified version of your script works for me from a Terminal
(The fit's not very good, yet, but it did run).   On Mac OSX with anaconda,
you probably have to run this as "pythonw import_fit.py"  (note: pythonw,
not python).

Hope that helps,

--Matt
import os
import sys
import numpy as np
import matplotlib.pyplot as plt

import larch
from larch import Interpreter, Group
from larch.fitting import guess, minimize

from larch_plugins.math.lineshapes import gaussian
from larch_plugins.xafs import pre_edge, mback

import pandas as pd


def rdin(filename):
    scandata_f = pd.read_csv(filename, sep='\t', skiprows=12)
    if not ("Counter 0" in scandata_f.columns):
        scandata_f = pd.read_csv(filename, sep='\t', skiprows=8)  # TrajScan files need 8 header lines somehow?
    print scandata_f.columns

    if not ("Counter 0" in scandata_f.columns):
        print ("Problem with header. skipping 12 or 10 lines did not make it. Check input file.")
        return None
    return scandata_f



def prepare_scan(scandata_f, datacounter="Counter 3", reference_counter='Counter 2'):
    # Preparing Scan (normalization)
    if 'Counter 4' in scandata_f.columns:
        clockname = 'Counter 4'
    elif 'Counter 6' in scandata_f.columns:
        clockname = 'Counter 6'
    else:
        print("No counter for clock found (looked for 'Counter 4' and 'Counter 6'). Defaulting to 'Counter 0'.")
        clockname = 'Counter 0'

    scandata_f["I_Norm0"] = scandata_f[datacounter].astype(float) / scandata_f[reference_counter].astype(float)
    scandata_f["I_Normt"] = scandata_f[datacounter].astype(float) / scandata_f[clockname].astype(float)
    scandata_f["Energy"] = scandata_f["Energy"].round(1)
    # scandata_f["Z"] = scandata_f["Z"].round(2)
    return scandata_f

scandata_f = rdin("TrajScan21930_swf.txt")
prepare_scan(scandata_f)


mylarch = Interpreter()

mdat = scandata_f
mdat.x = mdat.Energy
mdat.y = mdat.I_Norm0

# create a group of fit parameters
params = Group(off=guess(0),
                amp=guess(5, min=0),
                cen=guess(535),
                wid=guess(1, min=0))   # Need an edge value for the first guess for the center of the
# guassian: 'cen='. Can use the edge-finder for that

init = params.off + params.amp *  gaussian(mdat.x, params.cen, params.wid)


# define objective function for fit residual
def resid(p, data):
    return data.y - (p.off + p.amp * gaussian(data.x, p.cen, p.wid))


# perform fit
minimize(resid, params, args=(mdat,), _larch=mylarch)

# make final array
final = params.off + params.amp * \
                     gaussian(mdat.x, params.cen, params.wid)

# plot results
plt.plot(mdat.x, mdat.y)
plt.plot(mdat.x, init)
plt.plot(mdat.x, final)
plt.show()
_______________________________________________
Ifeffit mailing list
Ifeffit@millenia.cars.aps.anl.gov
http://millenia.cars.aps.anl.gov/mailman/listinfo/ifeffit
Unsubscribe: http://millenia.cars.aps.anl.gov/mailman/options/ifeffit

Reply via email to