SCRIPTS FITTING spl_modΒΆ

# -*-Python-*-
# Created by bgrierson at 13 Dec 2016  07:57

# Demonstration of the GAprofiles spline fitter "spl_mod"


def spl_mod_idl(x, y, ye, knotloc, autoknot, sol, bcs):

    # write the data to text file
    scratch['spl_mod_input'] = OMFITascii('spl_mod_input.dat')
    with open(scratch['spl_mod_input'].filename, 'w') as index:
        for i in range(len(x)):
            index.write('{} {} {}\n'.format(x[i], y[i], ye[i]))

    nk = len(knotloc)

    if autoknot:
        ak = 'yes'
    else:
        ak = 'no'

    if sol:
        edge = 'fit'
    else:
        edge = 'ignore'

    if bcs['y0'] is not None:
        y0 = bcs['y0']
    else:
        y0 = 'free'

    if bcs['y1'] is not None:
        y1 = bcs['y1']
    else:
        y1 = 'free'

    if bcs['y1p'] is not None:
        y1p = bcs['y1p']
    else:
        y1p = 'free'

    model = '''
model = create_struct('autoknot','{}')
model = create_struct(model,'numknot',{})
model = create_struct(model,'knotloc',knotloc)
model = create_struct(model,'type','point')
model = create_struct(model,'axis','{}')
model = create_struct(model,'boundary','{}')
model = create_struct(model,'edgeslope','{}')
model = create_struct(model,'edge','{}')
model = create_struct(model,'x_axis','rho')
model = create_struct(model,'normalize','no')
model = create_struct(model,'ftol',0.01)
model = create_struct(model,'maxit',200)
'''.format(
        ak, nk, y0, y1, y1p, edge
    ).strip()

    # Define IDL text
    runName = 'idl_input.pro'
    idl_cmd = []
    idl_cmd.append("!PATH = !PATH + ':' + getenv('VERSION4D')+'FITTING/'")
    idl_cmd.append(".compile spl_mod")
    idl_cmd.append('data = FLTARR(3,{})'.format(len(x)))
    idl_cmd.append("OPENR,lun,'spl_mod_input.dat',/GET_LUN")
    idl_cmd.append('READF,lun,data')
    idl_cmd.append('x = data[0,*]')
    idl_cmd.append('y = data[1,*]')
    idl_cmd.append('ye = data[2,*]')
    idl_cmd.append('knotloc={}'.format(knotloc.tolist()))
    idl_cmd.append("model_interp = 'spline'")
    idl_cmd.append(model)
    idl_cmd.append('f = spl_mod(x,y,ye,MODEL=model)')
    idl_cmd.append("SAVE,f,FILENAME='spl_mod_f.sav'")
    idl_cmd.append('exit')

    # Define executable variables for remote execution
    runScript = OMFITascii(runName, fromString='\n'.join(idl_cmd))
    server = IDE['idl']['server']
    tunnel = IDE['idl']['tunnel']
    remotedir = OMFITworkDir(root, IDE['idl']['server']) + '/spl_mod/'
    workdir = MainSettings['SETUP']['workDir'] + '/spl_mod/'

    # Execute the fit
    OMFITx.executable(
        root,
        inputs=[runScript, scratch['spl_mod_input']],
        outputs=['spl_mod_f.sav'],
        executable=IDE['idl']['idl'] + ' ' + runName + ';ls *',
        workdir=workdir,
        server=server,
        tunnel=tunnel,
        remotedir=remotedir,
    )

    # Save result to the OMFIT tree
    if 'spl_mod_f' in scratch:
        del scratch['spl_mod_f']
    scratch['spl_mod_f'] = OMFITidlSav('spl_mod_f.sav')


nxdata = 51
xdata = linspace(0, 1, nxdata)
ydata = np.sin(2.0 * np.pi * xdata) + 2.0
yerr = np.repeat(0.1, nxdata)
wgt = 1.0 / yerr
# Some fixed knots
knotloc = np.array([0.0, 0.33, 0.66, 1.0])
# Boundary conditions
bcs = {'y0': None, 'y0p': 0.0, 'y1': None, 'y1p': None}
# Fit SOL?
sol = False
# Autoknotter?
autoknot = False

spl_mod_idl(xdata, ydata, yerr, knotloc, autoknot, sol, bcs)

# Compute the residual (data-fit)/err
yfit = interpolate.interp1d(scratch['spl_mod_f']['f']['XFIT'], scratch['spl_mod_f']['f']['YFIT'])(xdata)
resid = (ydata - yfit) * wgt

fig, ax = plt.subplots(nrows=2)
uerrorbar(xdata, uarray(ydata, yerr), ax=ax[0], markersize=3.0, label='Data')
ax[0].plot(scratch['spl_mod_f']['f']['XFIT'], scratch['spl_mod_f']['f']['YFIT'], label='IDL')
ax[0].plot(
    scratch['spl_mod_f']['f']['KNOTLOC'], np.repeat(np.mean(ydata), len(knotloc)), marker='o', ls='None', color='r', label='knot locations'
)
ax[0].legend(loc='best')
ax[0].text(0.05, 3.2, '$\\chi_r^2={0:0.2f}$'.format(scratch['spl_mod_f']['f']['REDCHISQ']))
ax[1].plot(xdata, resid, marker='o', ls='None')
ax[1].axhline(0.0, ls='dashed', color='black')
ax[1].set_ylim([-np.max(np.abs(ax[1].get_ylim())), np.max(np.abs(ax[1].get_ylim()))])