#MAIN SamXAS Routine GUI

from Tkinter import *
from spdirvars import *
from spglobalfuncs import *
import tkFileDialog
import tkSimpleDialog
import tkMessageBox
import Pmw
import os
import Tix
from math import *
from string import *
from Ifeffit import *
import spsamview
import spkpca
import lsqfitter
import spplotter
import httplib
import cbselfabs

root=Tix.Tk()
root.title("SixPACK")
Pmw.initialise(root)
pm='+/-'
if os.name=='nt':os.sep='/'
filepath=os.getcwd()+os.sep
#if count(upper(filepath),'IFEFFIT')>0:filepath=filepath+'sixpack'+os.sep
iffc=Ifeffit(screen_echo=1)
iffc.ifeffit("load mnexafsfit.iff")

global lastfeffdir
lastfeffdir=''
global lastreaddir
global lastsavedir

#return main menu
def getmainmenu(win):
    root.deiconify()
    iffc.ifeffit("erase @arrays")
    iffc.ifeffit("erase @scalars")
    win.destroy()

###########################################################
##
##        
##  Periodic Table Interface for FEFF SS Maker
##
##
###########################################################
class PT:
    def __init__(self):
        ptwin=root.ptwin=Toplevel(root)
        ptwin.title("Single Scattering FEFF Path Maker")
        ptwin.protocol("WM_DELETE_WINDOW", self.closemod)
        root.iconify()
        #change focus...
        ptwin.focus_set()
        #periodic table
        #define elements 1=noble, 2=alkali, 3=pseudo, 4=non, 5=metal, 6=lanth, 7=act
        self.elist={'H':(1,0,1),'He':(2,0,1),
            'Li':(3,1,2),'Be':(4,1,2),'B':(5,1,3),'C':(6,1,4),'N':(7,1,4),'O':(8,1,4),'F':(9,1,4),'Ne':(10,1,1),
            'Na':(11,2,2),'Mg':(12,2,2),'Al':(13,2,5),'Si':(14,2,3),'P':(15,2,4),'S':(16,2,4),'Cl':(17,2,4),'Ar':(18,2,1),
            'K':(19,3,2),'Ca':(20,3,2),'Sc':(21,3,5),'Ti':(22,3,5),'V':(23,3,5),'Cr':(24,3,5),'Mn':(25,3,5),'Fe':(26,3,5),
            'Co':(27,3,5),'Ni':(28,3,5),'Cu':(29,3,5),'Zn':(30,3,5),'Ga':(31,3,5),'Ge':(32,3,3),'As':(33,3,3),'Se':(34,3,4),'Br':(35,3,4),'Kr':(36,3,1),
            'Rb':(37,4,2),'Sr':(38,4,2),'Y':(39,4,5),'Zr':(40,4,5),'Nb':(41,4,5),'Mo':(42,4,5),'Tc':(43,4,5),'Ru':(44,4,5),'Rh':(45,4,5),
            'Pd':(46,4,5),'Ag':(47,4,5),'Cd':(48,4,5),'In':(49,4,5),'Sn':(50,4,5),'Sb':(51,4,3),'Te':(52,4,3),'I':(53,4,4),'Xe':(54,4,1),
            'Cs':(55,5,2),'Ba':(56,5,2),'La':(57,8,6),'Ce':(58,8,6),'Pr':(59,8,6),'Nd':(60,8,6),'Pm':(61,8,6),'Sm':(62,8,6),'Eu':(63,8,6),
            'Gd':(64,8,6),'Tb':(65,8,6),'Dy':(66,8,6),'Ho':(67,8,6),'Er':(68,8,6),'Tm':(69,8,6),'Yb':(70,8,6),'Lu':(71,5,5),'Hf':(72,5,5),
            'Ta':(73,5,5),'W':(74,5,5),'Re':(75,5,5),'Os':(76,5,5),'Ir':(77,5,5),'Pt':(78,5,5),'Au':(79,5,5),'Hg':(80,5,5),'Tl':(81,5,5),
            'Pb':(82,5,5),'Bi':(83,5,5),'Po':(84,5,5),'At':(85,5,3),'Rn':(86,5,1),'Fr':(87,6,2),'Ra':(88,6,2),'Ac':(89,9,7),'Th':(90,9,7),
            'Pa':(91,9,7),'U':(92,9,7),'Np':(93,9,7),'Pu':(94,9,7),'Am':(95,9,7),'Cm':(96,9,7),'Bk':(97,9,7),'Cf':(98,9,7),'Es':(99,9,7),
            'Fm':(100,9,7),'Md':(101,9,7),'No':(102,9,7),'Lr':(103,6,5),'Rf':(104,6,5),'Db':(105,6,5),'Sg':(106,6,5),'Bh':(107,6,5),'Hs':(108,6,5),'Mt':(109,6,5)}        
        table=Frame(ptwin,relief=SUNKEN,bd=2,)
        table.pack(side=TOP)
        for en in self.elist.keys():
            eprop=self.elist[en]
            cp=eprop[0]
            if eprop[0]==1:
                cp=0
            elif eprop[0]==2:
                cp=17
            elif 3<=eprop[0]<=4:
                cp=cp-3
            elif 5<=eprop[0]<=10:
                cp=cp+7
            elif 11<=eprop[0]<=12:
                cp=cp-11
            elif 13<=eprop[0]<=18:
                cp=cp-1
            elif 19<=eprop[0]<=36:
                cp=cp-19
            elif 37<=eprop[0]<=54:
                cp=cp-37
            elif 55<=eprop[0]<=70:
                cp=cp-55
            elif 71<=eprop[0]<=86:
                cp=cp-69
            elif 87<=eprop[0]<=102:
                cp=cp-87
            elif 103<=eprop[0]<=118:
                cp=cp-101
            self.addelement(table,en,eprop[1],cp,eprop[2])
        spc=Frame(table,height=20)
        spc.grid(row=7)
        f=Frame(ptwin)
        f.pack(side=TOP,pady=2,fill=X)
        iact=Frame(f,relief=SUNKEN,bd=2)
        iact.pack(side=LEFT,pady=2,padx=10,fill=X)
        self.cbase="Absorbing atom: "
        self.ctext=StringVar()
        self.ctext.set(self.cbase)
        self.center=Label(iact,textvariable=self.ctext,width=50)
        self.center.pack(fill=X)
        self.sbase="Scattering atom: "
        self.stext=StringVar()
        self.stext.set(self.sbase)
        self.scat=Label(iact,textvariable=self.stext,width=50)
        self.scat.pack(fill=X)
        inst=Frame(f,relief=SUNKEN, bd=2)
        inst.pack(side=LEFT,pady=2,padx=10,fill=BOTH)
        insttext="Left click to select absorbing atom \n Right click to select scattering atom"
        instlab=Label(inst,text=insttext,fg="dark green",width=50)
        instlab.pack(side=TOP,fill=BOTH)
        fopt=Frame(ptwin,relief=SUNKEN,bd=2)
        l=Label(fopt,text="FEFF Options",relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=4)
        f=Frame(fopt,relief=GROOVE,bd=2)
        f.pack(side=TOP,padx=2,pady=2,fill=X)
        g=Frame(f)
        g.pack(side=LEFT,padx=2,pady=2)
        b=Button(g,text="Run FEFF",bg="steel blue",fg="ivory",command=self.runfeff, width=15)
        b.pack(side=TOP,padx=2,pady=15)
        self.feffversion=Pmw.RadioSelect(g,labelpos=N,label_text="FEFF Version",buttontype='radiobutton',command=self.changevers)
        self.feffversion.pack(fill=X,padx=8,pady=4)
        for text in ('FEFF6-7','FEFF8'):
            self.feffversion.add(text)
        self.feffcom=Pmw.EntryField(g,labelpos=W,label_text="FEFF Command:",value="feff800",entry_width=15)
        self.feffcom.pack(side=TOP,padx=15,pady=15)
        self.feffversion.invoke('FEFF8')
        g1=Frame(f)
        g1.pack(side=LEFT,padx=2,pady=2)
        edges=('K','L1','L2','L3','M1','M2','M3','M4','M5')
        self.feffedge=Pmw.ScrolledListBox(g1,items=edges,labelpos=N,label_text='Edge:',listbox_height=4,listbox_exportselection=0)
        self.feffedge.select_set(0)
        self.feffedge.pack(side=LEFT,padx=2,pady=2)
        g2=Frame(f)
        g2.pack(side=LEFT,padx=2,pady=2)
        #distance of scatterer and rough geometry
        self.scatdist=Pmw.EntryField(g2,labelpos=N,label_text="Distance to Scatterer:",entry_width=5,validate='real')
        self.scatdist.pack(padx=2,pady=5)
        gitems=('Tetrahedral','Sq Planar','Octahedral')
        self.feffgeom=Pmw.ScrolledListBox(g2,items=gitems,labelpos=N,label_text='Geometry:',listbox_height=4,listbox_exportselection=0)
        self.feffgeom.select_set(2)
        self.feffgeom.pack(padx=2,pady=5)
        g3=Frame(f)
        g3.pack(side=LEFT,padx=2,pady=2)
        #other options
        self.feffafolp=Pmw.EntryField(g3,labelpos=N,label_text="AFOLP:",value=1.15,entry_width=7,validate={'validator':'real','min':1,'max':1.3})
        self.feffafolp.pack(padx=2,pady=2)
        xitems=('0 - Hedin-Lundqvist','1 - Dirac-Hara','2 - Ground State','3 - DH+HL','5 - Partially Nonlocal')
        self.feffxchange=Pmw.ComboBox(g3,labelpos=N,scrolledlist_items=xitems,label_text="Exchange:",listheight=100,listbox_exportselection=0,history=0)
        self.feffxchange.selectitem(xitems[0])        
        self.feffxchange.pack(padx=2,pady=2)
        fopt.pack(side=TOP,pady=2,fill=BOTH)

    def closemod(self):
        getmainmenu(root.ptwin)

    def addelement(self,master,ename,rpos,cpos,etyp):
        #add an element button 1=noble, 2=alkali, 3=pseudo, 4=non, 5=metal, 6=lanth, 7=act
        if etyp==1: bc='goldenrod'
        if etyp==2: bc='tan'
        if etyp==3: bc='orange'
        if etyp==4: bc='light blue'
        if etyp==5: bc='dark green'
        if etyp==6: bc='rosy brown'
        if etyp==7: bc='dark red'
        b=Button(master,text=ename,width=2,height=1,font='Arial 14 bold',bg=bc)
        b.grid(row=rpos,column=cpos)
        b.bind("<Button-1>",self.centerclick)
        b.bind("<Button-3>",self.scatclick)
        b.bind("<ButtonRelease-3>",self.returnclick)

    def centerclick(self,event):
        atom=event.widget.cget('text')
        self.catom=atom
        self.ctext.set(self.cbase+atom)
        
    def scatclick(self,event):
        atom=event.widget.cget('text')
        event.widget.config(state=ACTIVE)
        event.widget.config(relief=SUNKEN)
        self.satom=atom
        self.stext.set(self.sbase+atom)

    def returnclick(self,event):
        event.widget.config(state=NORMAL)
        event.widget.config(relief=RAISED)

    def changevers(self,arg):
        if self.feffversion.getcurselection()=='FEFF8':
            self.feffcom.setentry('feff800')
        else:
            self.feffcom.setentry('feff7')

    def runfeff(self):
        #routine to run a feff script!
        #puts all work in the folder fefftemp
        os.chdir(filepath)
        try:
            os.chdir("fefftemp")
        except:
            os.chdir(filepath+'sixpack'+os.sep+'fefftemp')
        #clear directory!
        os.system("del *.bin")
        os.system("del *.dat")
        #open feff.inp
        fid=open("feff.inp","w")
        #set variable parameters
        exch=self.feffxchange.get()[0]
        rad=atof(self.scatdist.get())
        mrad=str(rad+2)
        cnum=str(self.elist[self.catom][0])
        snum=str(self.elist[self.satom][0])
        #determine coordinates for geometry...
        if self.feffgeom.getcurselection()[0]=='Tetrahedral':
            d=rad/sqrt(3)
            d1=str(d)
            geotext=""" 0          0          0          0   Ct
 """+d1+"""          """+d1+"""          """+d1+"""          1   Sc
 -"""+d1+"""          -"""+d1+"""          """+d1+"""          1   Sc
 -"""+d1+"""          """+d1+"""          -"""+d1+"""          1   Sc
 """+d1+"""          -"""+d1+"""          -"""+d1+"""          1   Sc
 """
        if self.feffgeom.getcurselection()[0]=='Sq Planar':
            d=self.scatdist.get()
            geotext=""" 0          0          0          0   Ct
 """+d+"""          0          0          1   Sc
 -"""+d+"""          0          0          1   Sc
 0          """+d+"""          0          1   Sc
 0         -"""+d+"""          0          1   Sc
 """
        if self.feffgeom.getcurselection()[0]=='Octahedral':
            d=self.scatdist.get()
            geotext=""" 0          0          0          0   Ct
 """+d+"""          0          0          1   Sc
 -"""+d+"""          0          0          1   Sc
 0          """+d+"""          0          1   Sc
 0         -"""+d+"""          0          1   Sc
 0          0          """+d+"""          1   Sc
 0          0         -"""+d+"""          1   Sc
 """
        #begin file writing
        if self.feffversion.getcurselection()=='FEFF8':
            fid.write(""" * This file created by SamXAS
TITLE """+self.catom+"""-"""+self.satom+""" Single Scatering
EDGE     """+self.feffedge.getcurselection()[0]+"""
S02      1
CONTROL  1 1 1 1 1 1
PRINT    1 0 0 0 0 3

EXCHANGE """+exch+"""
AFOLP    """+self.feffafolp.get()+"""
SCF      4
NLEG     2
RPATH    """+mrad+"""
EXAFS    """+mrad+"""

POTENTIALS
  0  """+cnum+"""  """+self.catom+"""    
  1  """+snum+"""  """+self.satom+"""    

ATOMS
 * x          y          z          ipot tag
"""+geotext+"""
""")
            fid.close()
        else:
            holevar=int(self.feffedge.curselection()[0])+1
            fid.write(""" * This file created by SamXAS
TITLE """+self.catom+"""-"""+self.satom+""" Single Scatering
HOLE     """+str(holevar)+""" 1
CONTROL  1 1 1 1
PRINT    1 0 0 3

RMAX     """+mrad+"""
EXCHANGE """+exch+"""
AFOLP    """+self.feffafolp.get()+"""
NLEG     2

POTENTIALS
  0  """+cnum+"""  """+self.catom+"""    
  1  """+snum+"""  """+self.satom+"""    

ATOMS
 * x          y          z          ipot tag
"""+geotext+"""
""")
            fid.close()
        #run feff
        os.system(self.feffcom.get())
        #move files to proper locations
        resdir=lower(self.catom+"paths")
        dp=str(int(rad*1000))
        filnm=self.catom+self.feffedge.getcurselection()[0]+"-"+self.satom+"-"+dp+".dat"
        #copy results into buffer
        fid=open("feff0001.dat","r")
        feffout=fid.read()
        fid.close()
        #find directories
        dirs=os.listdir('..')
        dirpres=0
        for dr in dirs:
            if lower(dr)==resdir: dirpres=1
        if dirpres==0:
            os.chdir(filepath)
            os.mkdir(resdir)
        fid=open(filepath+resdir+os.sep+filnm,"w")
        fid.write(feffout)
        fid.close()
        os.chdir(filepath)

##############################################################################
##
##
## Advanced Fitting Routine
##
##
##############################################################################

class DefPath:
    def __init__(self,master,pnum):
        f=Frame(master)
        f.pack(side=TOP,padx=2,pady=0)
        self.pon=IntVar()
        self.dset=IntVar()
        self.dset.set(0)
        textlab="Use "+pnum+" in fit?"
        cb=Checkbutton(f,text=textlab,variable=self.pon,anchor=W)
        cb.pack(side=LEFT,padx=10,pady=2)
        cb=Checkbutton(f,text="Set DEGEN = 1?",variable=self.dset,anchor=W)
        cb.pack(side=LEFT,padx=10,pady=2)
        b=Button(f,bitmap="@"+filepath+"xbms"+os.sep+"openfolder.xbm",command=self.feffpathme,height=21,width=30,bg='lightyellow')
        b.pack(side=LEFT,padx=2,pady=2)
        l=Label(f,text="Choose Path")
        l.pack(side=LEFT,padx=2,pady=2)
        g=Frame(master)
        g.pack(side=TOP,padx=2,pady=0)
        self.loc=Pmw.EntryField(g,label_text="Path Location:",labelpos=W,entry_width=55)
        self.loc.pack(side=TOP,padx=2,pady=2)
        self.descr=Pmw.EntryField(g,label_text="Path Label:",labelpos=W,entry_width=55)
        self.descr.pack(side=TOP,padx=2,pady=2)
        self.descr.setentry("label")
        self.s02=Pmw.EntryField(g,label_text="S02:",labelpos=W,entry_width=55)
        self.s02.pack(side=TOP,padx=2,pady=2)
        self.e0=Pmw.EntryField(g,label_text="E0:",labelpos=W,entry_width=55)
        self.e0.pack(side=TOP,padx=2,pady=2)
        self.deltaR=Pmw.EntryField(g,label_text="deltaR:",labelpos=W,entry_width=55)
        self.deltaR.pack(side=TOP,padx=2,pady=2)
        self.sig=Pmw.EntryField(g,label_text="sigma2:",labelpos=W,entry_width=55)
        self.sig.pack(side=TOP,padx=2,pady=2)
        self.third=Pmw.EntryField(g,label_text="third:",labelpos=W,entry_width=55)
        self.third.pack(side=TOP,padx=2,pady=2)
        self.fourth=Pmw.EntryField(g,label_text="fourth:",labelpos=W,entry_width=55)
        self.fourth.pack(side=TOP,padx=2,pady=2)
        Pmw.alignlabels([self.loc,self.descr,self.s02,self.e0,self.deltaR,self.sig,self.third,self.fourth])

    def feffpathme(self):
        global lastfeffdir
        fn=ask_for_file([("feff files","*.dat"),("all files","*")],lastfeffdir,check=0)
        sdir=rfind(fn,os.sep)
        lastfeffdir=fn[:sdir]        
        entry_replace(self.loc,fn)
        root.adwin.focus_set()

class DefVar:
    def __init__(self,master):
        self.f=Frame(master)
        self.f.pack(side=TOP,padx=2)
        self.von=IntVar()
        self.von.set(1)
        self.cb=Checkbutton(self.f,variable=self.von)
        self.cb.pack(side=LEFT,padx=2,pady=0)
        self.type=Pmw.RadioSelect(self.f,buttontype='radiobutton',labelpos=None,padx=0,pady=0)
        for text in ('G','S','D'):
            self.type.add(text)
        self.type.pack(side=LEFT,padx=2,pady=0)
        self.vname=Pmw.EntryField(self.f,entry_width=15)
        self.vname.pack(side=LEFT,padx=2,pady=0)
        self.vexp=Pmw.EntryField(self.f,entry_width=45)
        self.vexp.pack(side=LEFT,padx=2,pady=0)
        self.buffer=' '
        self.restraint=0
        
class AdvFit:
    def __init__(self):
        adwin=root.adwin=Toplevel(root)
        adwin.title("Advanced EXAFS Fitting Dialog")
        adwin.protocol("WM_DELETE_WINDOW", self.closemod)
        self.adwin=adwin
        self.root=root
        root.iconify()
        #change focus...
        adwin.focus_set()

        #GUI for fitting window...
        #create menu for fitting window
        menubar=Pmw.MenuBar(adwin)
        #file menu
        menubar.addmenu('File','')
        menubar.addmenuitem('File','command',label='Open Data',command=self.menuopen)
        menubar.addmenuitem('File','separator')
        menubar.addmenuitem('File','command',label='Edit Default Directories',command=self.callchangedefdirs)
        menubar.addmenuitem('File','separator')
        menubar.addmenuitem('File','command',label='Close',command=self.closemod)
        menubar.addmenuitem('File','command',label='Quit',command=root.quit)
        menubar.addmenu('Save','')
        menubar.addmenuitem('Save','command',label='Fit Data',command=self.savefitdata)
        menubar.addmenuitem('Save','command',label='Spec Data',command=self.saverawdata)
        menubar.addmenuitem('Save','command',label='Residuals',command=self.saveresiddata)
        menubar.addmenu('Workspace','')
        menubar.addmenuitem('Workspace','command',label='Save Workspace',command=self.saveallvars)
        menubar.addmenuitem('Workspace','command',label='Load Workspace',command=self.loadallvars)
        menubar.addmenu('Templates','')
        menubar.addmenuitem('Templates','command',label='Simple',command=self.pathsimple)
        menubar.addmenuitem('Templates','command',label='Simple-Linked',command=self.pathsimplel)
        menubar.addmenuitem('Templates','command',label='CNs-Unique',command=self.pathcnumu)
        menubar.addmenuitem('Templates','command',label='CNs-Linked',command=self.pathcnuml)
        menubar.addcascademenu('Templates','Debye Models')
        menubar.addmenuitem('Debye Models','command',label='General',command=self.pathdebye)
        menubar.addmenuitem('Debye Models','command',label='O shell',command=self.pathodebye)
        menubar.addmenuitem('Debye Models','command',label='Me Shell',command=self.pathMedebye)           
        menubar.addmenuitem('Templates','command',label='Einstein Model',command=DISABLED,state=DISABLED)
        menubar.addmenuitem('Templates','command',label='Pair Potential',command=DISABLED,state=DISABLED)
        menubar.addmenu('Path Vars','')
        menubar.addmenuitem('Path Vars','command',label='Add reff',command=self.varreff)
        menubar.addmenuitem('Path Vars','command',label='Add abs to sigma2',command=self.abssigma)
        menubar.addmenuitem('Path Vars','command',label='Add P-P Vars',command=DISABLED,state=DISABLED)
        menubar.addmenuitem('Path Vars','separator')
        menubar.addmenuitem('Path Vars','command',label='Sort by Name',command=self.sortfitvarsbyname)
        menubar.addmenuitem('Path Vars','command',label='Sort by Letter',command=self.sortfitvarsbyletter)                
        menubar.addmenuitem('Path Vars','command',label='Sort by Creation',command=self.sortfitvarsbycreation)
        menubar.addmenuitem('Path Vars','command',label='Sort by Path',command=self.sortfitvarsbypath)
        menubar.addmenuitem('Path Vars','separator')
        menubar.addmenuitem('Path Vars','command',label='Recall Last Fit Result',command=self.recallvarbuffer)
        menubar.addmenuitem('Path Vars','separator')        
        menubar.addmenuitem('Path Vars','command',label='Search and Replace FEFF file Paths',command=self.activateSRFEFF)
        menubar.addmenu('Fit','')
        menubar.addcascademenu('Fit','Fit k-weight',tearoff=1)
        self.fitmenukweight=IntVar()
        menubar.addmenuitem('Fit k-weight','radiobutton',label='default',value=0,variable=self.fitmenukweight)
        menubar.addmenuitem('Fit k-weight','radiobutton',label='3210',value=1,variable=self.fitmenukweight)
        menubar.addmenuitem('Fit k-weight','radiobutton',label='321',value=2,variable=self.fitmenukweight)
        menubar.addmenuitem('Fit k-weight','radiobutton',label='32',value=3,variable=self.fitmenukweight)        
        self.fitmenukweight.set(0)
        menubar.addcascademenu('Fit','Fit Background Spline',tearoff=1)
        self.fitmenuspline=IntVar()
        menubar.addmenuitem('Fit Background Spline','radiobutton',label='Off',value=0,variable=self.fitmenuspline)
        menubar.addmenuitem('Fit Background Spline','radiobutton',label='On',value=1,variable=self.fitmenuspline)
        self.fitmenuspline.set(0)
        
        menubar.addmenu('Help','',side=RIGHT)
        menubar.addmenuitem('Help','command',label='About SixPack',command=callprogramabout)
        menubar.addmenuitem('Help','separator')
        menubar.addmenuitem('Help','command',label='IFEFFIT Command Line',command=RunIFEFFITCmdLine)        
        menubar.grid(row=0,columnspan=24,sticky=W+E)
        #create toolbar space
        toolbar=Frame(adwin, relief=SUNKEN,borderwidth=2)
        b=Button(toolbar,text="Fit",width=6,command=self.dofit,bg="red", fg="white")
        b.pack(side=LEFT,padx=2,pady=2)
        b=Button(toolbar,text="ff2chi",width=6,command=self.doff2chi,bg="red", fg="white")
        b.pack(side=LEFT,padx=2,pady=2)
        b=Button(toolbar,text="path ff2chi",width=8,command=self.dopathff2chi,bg="red", fg="white")
        b.pack(side=LEFT,padx=2,pady=2)
        s=Frame(toolbar,width=60)
        s.pack(side=LEFT,padx=2,pady=2)
        b=Button(toolbar,text="Plot Paths",width=10,command=self.plotpathcontributions,bg="red", fg="white")
        b.pack(side=RIGHT,padx=2,pady=2)
        b=Button(toolbar,text="Plot q",width=6,command=self.make_q_plot,bg="red", fg="white")
        b.pack(side=RIGHT,padx=2,pady=2)
        b=Button(toolbar,text="Plot R",width=6,command=self.make_R_plot,bg="red", fg="white")
        b.pack(side=RIGHT,padx=2,pady=2)
        b=Button(toolbar,text="Plot k",width=6,command=self.make_k_plot,bg="red", fg="white")
        b.pack(side=RIGHT,padx=2,pady=2)
        #display
        toolbar.grid(row=1,columnspan=24,sticky=W+E)
        #add body
        #first area for data file
        filebar=Frame(adwin, relief=SUNKEN,bd=2)
        self.fileentry=Pmw.EntryField(filebar, label_text="Data File:",labelpos=W,validate=None,entry_width=60)
        self.fileentry.pack(side=LEFT,padx=5,pady=2,fill=X)
        b=Button(filebar,bitmap="@"+filepath+"xbms"+os.sep+"openfolder.xbm",command=self.fileme,height=21,width=30,bg='lightyellow')
        b.pack(side=LEFT,padx=2,pady=2)
        b=Button(filebar,text="Load",bg='darkgreen',fg='snow',command=self.load_data_file)
        b.pack(side=LEFT,padx=2,pady=2)
        filebar.grid(row=2,columnspan=16,rowspan=2,sticky=W+E+N+S)
        s=Frame(filebar,width=55)   #spacer to reduce flicker
        s.pack(side=LEFT,padx=2,pady=2)
        #FEFF Path Parameters
        fitwin=Frame(adwin,relief=SUNKEN,bd=2)
        l=Label(fitwin,text="FEFFIT Variables", relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=4)
        feffnb=Pmw.NoteBook(fitwin)
        if sys.platform == 'win32':
            feffnb.configure(hull_background="SystemButtonFace")
        else:
            feffnb.configure(hull_background='#d4d0c8')
        feffnb.recolorborders()        
        feffnb.pack(fill="both",expand=1)
        pathpage=feffnb.add('Paths')
        s1=Frame(pathpage, relief=GROOVE,bd=2)
        s1.pack(side=LEFT,padx=2,pady=2)
        b=Button(s1,text="Define Path",bg='#c7dded',fg='black',command=self.deffeffpath)
        b.pack(side=TOP,padx=2,pady=2,fill=X)
        self.pathlist=[]
        self.pathsel=Pmw.ScrolledListBox(s1,label_text="Path List:",labelpos=NW,selectioncommand=self.changepath,
                                  items=self.pathlist,listbox_height=7,vscrollmode='static',listbox_exportselection=0)
        self.pathsel.pack(side=TOP,padx=2,pady=2,fill=X)
        b=Button(s1,text="Add Path",bg='darkseagreen4',fg='ivory',command=self.addfeffpath)
        b.pack(side=TOP,padx=2,pady=2,fill=X)
        b=Button(s1,text="Remove Path",bg='darkred',fg='ivory',command=DISABLED,state=DISABLED)
        b.pack(side=TOP,padx=2,pady=2,fill=X)
        self.pathdes=Pmw.NoteBook(pathpage,tabpos=None)
        if sys.platform == 'win32':
            self.pathdes.configure(hull_background="SystemButtonFace")
        else:
            self.pathdes.configure(hull_background='#d4d0c8')
        self.pathdes.recolorborders()
        self.pathwidlist=[]
        self.npath=0
        self.addfeffpath()
        self.pathdes.pack(side=LEFT,padx=2,pady=2,fill=BOTH,expand=1)
        self.pathdes.setnaturalsize()
        #variable page
        varpage=feffnb.add('Variables')
        f=Frame(varpage)
        b=Button(f,text="Add Variable",command=self.addfitvar,bg='slateblue',fg='snow',width=20)
        b.pack(side=LEFT,padx=2,pady=2)
        b=Button(f,text="Add All Variables",command=self.addallfitvar,bg='darkblue',fg='snow',width=20)
        b.pack(side=LEFT,padx=2,pady=2)
        b=Button(f,text="Remove Variable",command=self.deletefitvar,bg='darkred',fg='snow',width=20)
        b.pack(side=LEFT,padx=2,pady=2)
        b=Button(f,text="Set as Restraint",command=self.restraintfitvar,bg='dark orange',fg='snow',width=20)
        b.pack(side=LEFT,padx=2,pady=2)
        f.pack(pady=0,padx=2)
        self.vsf=Pmw.ScrolledFrame(varpage)
        self.vsf.pack(padx=2,pady=2,fill=BOTH)
        self.vfield=self.vsf.interior()
        l=Label(self.vfield,text="Use     Guess     Set      Def       Variable                   Expression",font="Arial 9 bold",anchor=W)
        l.pack(padx=2,pady=0,fill=X)
        self.varwidlist=[]
        respage=feffnb.add('Results')
        self.respathvar=IntVar()
        self.respathvar.set(0)
        cb=Checkbutton(respage,text='Print FEFF path variables?',variable=self.respathvar,anchor=W,pady=0)
        cb.pack(padx=2,pady=0)
        self.restext=Pmw.ScrolledText(respage,hscrollmode='none',vscrollmode='static',label_text="Results of all guessed and defined variables",
                                      labelpos=N,borderframe=1,text_font="Courier 9") #,text_state=DISABLED)
        self.restext.pack(padx=2,pady=0)
        self.pathdes.setnaturalsize()
        fitwin.grid(row=4,columnspan=20,rowspan=23,sticky=N+E+S+W) 
        #Add Fit params
        fitpwin=Frame(adwin,relief=SUNKEN,bd=2)
        l=Label(fitpwin,text="Fit Parameters",relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=4)
        entframe=Frame(fitpwin)
        entframe.pack(side=TOP)
        lhe=Frame(entframe)
        lhe.pack(side=LEFT,fill=X,padx=2,pady=2)
        rhe=Frame(entframe)
        rhe.pack(side=LEFT,fill=X,padx=2,pady=2)
        #define entries
        self.kmin=Pmw.EntryField(lhe,label_text="kmin:",labelpos=W,validate='real',entry_width=5,value='3')
        self.kmax=Pmw.EntryField(rhe,label_text="kmax:",labelpos=W,validate='real',entry_width=5,value='13')
        self.rmin=Pmw.EntryField(lhe,label_text="Rmin:",labelpos=W,validate='real',entry_width=5,value='1')
        self.rmax=Pmw.EntryField(rhe,label_text="Rmax:",labelpos=W,validate='real',entry_width=5,value='4')
        self.kweight=Pmw.EntryField(lhe,label_text="kweight:",labelpos=W,validate='integer',entry_width=5,value='3')
        self.dk=Pmw.EntryField(rhe,label_text="dk:",labelpos=W,validate='real',entry_width=5,value='1')
        self.fitplhe=[self.kmin,self.rmin,self.kweight]
        self.fitprhe=[self.kmax,self.rmax,self.dk]
        for ne in self.fitplhe:
            ne.pack(fill=X,expand=1,padx=2,pady=2)
        for ne in self.fitprhe:
            ne.pack(fill=X,expand=1,padx=2,pady=2)
        Pmw.alignlabels(self.fitplhe)
        Pmw.alignlabels(self.fitprhe)
        #Add ComboBox to options
        cbframe=Frame(fitpwin)
        windows=('Hanning','Kaiser-Bessel','Parzen','Welch','Sine')
        self.winparam=Pmw.ComboBox(cbframe,label_text='FT Window:',labelpos=W,scrolledlist_items=windows,listheight=100)
        self.winparam.selectitem(windows[1])
        self.winparam.pack(side=TOP,fill=X,padx=2,pady=3)
        fitspc=('q','R','k')
        self.spcparam=Pmw.ComboBox(cbframe,label_text='Fitting Space:',labelpos=W,scrolledlist_items=fitspc,listheight=70)
        self.spcparam.selectitem(fitspc[1])
        self.spcparam.pack(fill=X,padx=2,pady=3)
        Pmw.alignlabels([self.spcparam,self.winparam])
        cbframe.pack(side=BOTTOM,fill=X,padx=2,pady=2)        
        fitpwin.grid(row=2,column=20,columnspan=4,rowspan=8,sticky=W+E+N+S)
        #Add plot options
        plotoptwin=Frame(adwin,relief=SUNKEN,bd=2)
        l=Label(plotoptwin,text="Plot Options",relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=4)        
        #add notebook
        plotnb=Pmw.NoteBook(plotoptwin)
        if sys.platform == 'win32':
            plotnb.configure(hull_background="SystemButtonFace")
        else:
            plotnb.configure(hull_background='#d4d0c8')
        plotnb.recolorborders()        
        plotnb.pack(fill="both",expand=1)
        #add k-page
        kpage=plotnb.add('k')
        self.kplots=Pmw.RadioSelect(kpage, buttontype='checkbutton',orient='vertical',labelpos=W)
        self.kplots.pack(side=TOP,padx=5,pady=5)
        for text in ('Data','Fit','Residuals','FT Window'):
            self.kplots.add(text)
        self.kplots.invoke('Data')
        self.kplotwt=Pmw.EntryField(kpage,labelpos=W,label_text='kweight:',validate='integer',entry_width=5,value='3')
        self.kplotmin=Pmw.EntryField(kpage,labelpos=W,label_text='kmin:',validate='real',entry_width=5,value='3')
        self.kplotmax=Pmw.EntryField(kpage,labelpos=W,label_text='kmax:',validate='real',entry_width=5,value='13')
        self.kplotwt.pack(side=TOP,padx=5,pady=5)
        self.kplotmin.pack(side=LEFT,padx=5,pady=2)
        self.kplotmax.pack(side=LEFT,padx=5,pady=2)
        #add R-page
        rpage=plotnb.add('R')
        rframe=Frame(rpage)
        rframe.pack(side=TOP,fill=X)
        self.rplots=Pmw.RadioSelect(rframe, buttontype='checkbutton',orient='vertical',labelpos=W)
        self.rplots.pack(side=LEFT,padx=5,pady=5)
        for text in ('Data','Fit'):
            self.rplots.add(text)
        self.rplots.invoke('Data')
        self.rptype=Pmw.RadioSelect(rframe, buttontype='checkbutton',orient='vertical',labelpos=W)
        self.rptype.pack(side=LEFT,padx=5,pady=5)
        for text in ('Magnitude','Real','Imaginary'):
            self.rptype.add(text)
        self.rptype.invoke('Magnitude')
        self.rplotmin=Pmw.EntryField(rpage,labelpos=W,label_text='Rmin:',validate='real',entry_width=5,value='0')
        self.rplotmax=Pmw.EntryField(rpage,labelpos=W,label_text='Rmax:',validate='real',entry_width=5,value='6')
        self.rplotmin.pack(side=LEFT,padx=5,pady=5)
        self.rplotmax.pack(side=LEFT,padx=5,pady=5)
        #add q-page
        qpage=plotnb.add('q')
        qframe=Frame(qpage)
        qframe.pack(side=TOP,fill=X)
        self.qplots=Pmw.RadioSelect(qframe, buttontype='checkbutton',orient='vertical',labelpos=W)
        self.qplots.pack(side=LEFT,padx=5,pady=5)
        for text in ('Data','Fit'):
            self.qplots.add(text)
        self.qplots.invoke('Data')
        self.qptype=Pmw.RadioSelect(qframe, buttontype='checkbutton',orient='vertical',labelpos=W)
        self.qptype.pack(side=LEFT,padx=5,pady=5)
        for text in ('Real','Imaginary'):
            self.qptype.add(text)
        self.qptype.invoke('Real')
        self.qplotmin=Pmw.EntryField(qpage,labelpos=W,label_text='qmin:',validate='real',entry_width=5,value='3')
        self.qplotmax=Pmw.EntryField(qpage,labelpos=W,label_text='qmax:',validate='real',entry_width=5,value='13')
        self.qplotmin.pack(side=LEFT,padx=5,pady=5)
        self.qplotmax.pack(side=LEFT,padx=5,pady=5)
        #add Path Page
        ppage=plotnb.add('Path')
        self.cumpathsels=Pmw.RadioSelect(ppage,buttontype='checkbutton',orient='vertical',labelpos=W)
        self.cumpathsels.pack(side=LEFT,padx=5,pady=5)
        for text in ('Data','Fit'):
            self.cumpathsels.add(text)
        self.cumpathsels.invoke('Data')
        self.cumpathtype=Pmw.RadioSelect(ppage,buttontype='radiobutton',orient='vertical',labelpos=W)
        self.cumpathtype.pack(side=LEFT,padx=5,pady=5)
        for text in ('k','R','q'):
            self.cumpathtype.add(text)
        self.cumpathtype.invoke('R')
        #finis
        plotnb.setnaturalsize()
        plotoptwin.grid(row=10,column=20,columnspan=4,rowspan=17,sticky=W+E+N+S)
        #Fit Quality Bar
        bar=Frame(adwin, relief=SUNKEN,bd=2)
        l=Label(bar,text="Chi Sq: ",anchor=W)
        self.ChiSq=Label(bar,text="",width=20,anchor=W)
        l.pack(side=LEFT,padx=2,pady=2)
        self.ChiSq.pack(side=LEFT,padx=2,pady=2)
        l=Label(bar,text="Red Chi Sq: ",anchor=W)
        self.ChiSqR=Label(bar,text="",width=20,anchor=W)
        l.pack(side=LEFT,padx=2,pady=2)
        self.ChiSqR.pack(side=LEFT,padx=2,pady=2)
        m=Label(bar,text="R factor: ",anchor=W)
        self.Rvalue=Label(bar,text="",width=20,anchor=W)
        m.pack(side=LEFT,padx=2,pady=2)
        self.Rvalue.pack(side=LEFT,padx=2,pady=2)
        #check box for correlations
        self.calccorels=Pmw.RadioSelect(bar,labelpos=W,padx=1,pady=1,command=self.showcorelwin,buttontype='checkbutton')
        self.calccorels.pack(side=RIGHT,padx=10,pady=1)
        self.calccorels.add('Display Correlations?')
        bar.grid(row=27,columnspan=24,sticky=W+E)        
        #add status bar to bottom of window
        if sys.platform=='win32':
            self.status=Label(adwin,text="",bd=2,relief=RAISED,anchor=W,fg='blue',bg='SystemButtonFace')
        else:
            self.status=Label(adwin,text="",bd=2,relief=RAISED,anchor=W,fg='blue',bg='#d4d0c8')
        self.status.grid(row=28,columnspan=24,sticky=W+E)
        setstatus(self.status,"Ready")
        self.mstat=0
        #error window
        self.box=Pmw.MessageDialog(root,title='File Error',defaultbutton=0,message_text='Wrong type of parameter file chosen!',
                 iconpos='n',icon_bitmap='warning')
        self.box.iconname('File Error')
        self.box.withdraw()
        #correlation window
        self.corwin=Pmw.TextDialog(root,title='Fit Correlations',command=self.killcorelwin,deactivatecommand=self.killcorelwin,scrolledtext_hscrollmode='static',scrolledtext_vscrollmode='static',text_wrap='none',scrolledtext_labelpos=N,label_text='Fit Variable Correlations',buttons=('Remove',))
        self.corwin.iconname('Fit Correlations')
        self.corwin.tag_config('hi',foreground='red')
        self.corwin.withdraw()
        iffc.ifeffit("read_data(file="+filepath+"test.inp, group=firsttest,label='energy xmu')")
        self.pathdegen={}
        self.pathdegenf={}

        #define searchreplaceFEFF diaglog
        self.SRFEFFdialog=Pmw.Dialog(self.adwin,buttons=('OK','Cancel'),defaultbutton='OK',title='Search and Replace FEFF Paths',command=self.searchreplaceFEFF)
        self.SRFEFFdialog.withdraw()
        #add guts of dialog window
        self.SRFpathlist=[]
        self.SRFpath=Pmw.Counter(self.SRFEFFdialog.interior(),labelpos='w',label_text='Replace Path:     ',entry_width=60,datatype=self.SRFdatatype)
        self.SRFreplace=Pmw.EntryField(self.SRFEFFdialog.interior(),labelpos='w',label_text='With Path:',entry_width=60)
        entries=(self.SRFpath,self.SRFreplace)
        Pmw.alignlabels(entries)
        for entry in entries:
            entry.pack(fill='x',expand=1,padx=5,pady=5)
        
    def callprogramabout(self):
        programabout(self.root)
        
    def callchangedefdirs(self):
        global lastsavedir,lastreaddir
        s=changedefdirs(self.adwin)
        lastreaddir=s.newdir
        lastsavedir=s.newdir

    def closemod(self):
        #erase paths
        for pth in self.pathlist:
            pi=self.pathlist.index(pth)
            pnum=str(pi+1)
            iffc.ifeffit("erase @path="+pnum)
        getmainmenu(root.adwin)

    def SRFdatatype(self,text,factor,increment):
        if self.SRFpathlist==[]:
            return ''
        #find index of current path
        try:
            i=self.SRFpathlist.index(text)
        except:
            self.SRFreplace.setentry(self.SRFpathlist[0])           
            return self.SRFpathlist[0]
        i=i+factor
        if i>(len(self.SRFpathlist)-1): i=0
        newtext=self.SRFpathlist[i]
        self.SRFreplace.setentry(newtext)
        return newtext

    def searchreplaceFEFF(self,result):
        #search and replace FEFF paths in current workspace
        if result=='Cancel':
            self.SRFEFFdialog.deactivate()
            return
        st=self.SRFpath.getvalue()
        rt=self.SRFreplace.getvalue()
        if st==rt:
            self.SRFEFFdialog.deactivate()
            return
        #perform search and replace
        i=0
        for pth in self.pathwidlist:
            ptext=pth.p.loc.getvalue()
            new=replace(ptext,st,rt,1)
            if new!=ptext: i=i+1
            pth.p.loc.setvalue(new)
        self.SRFEFFdialog.deactivate()        
        setstatus(self.status,"FEFF Path replaced in "+str(i)+" occurences")

    def activateSRFEFF(self):
        #create list of FEFF file path routes
        self.SRFpathlist=[]
        for pth in self.pathwidlist:
            ptext=pth.p.loc.getvalue()
            if ptext!='':
                #delete file info
                pdirind=rfind(ptext,os.sep)
                pdir=ptext[:pdirind]
                if pdir not in self.SRFpathlist:
                    self.SRFpathlist.append(pdir)
        #activate dialog
        self.SRFEFFdialog.activate()
        
    def showcorelwin(self,*arg):
        if self.calccorels.getcurselection()!=():
            #show box
            self.corwin.deiconify()
        else:
            #remove box
            self.killcorelwin()

    def killcorelwin(self,*arg):
        #empty=[]
        #self.calccorels.setvalue(empty)
        self.corwin.withdraw()
        if self.calccorels.getcurselection()!=():
            self.calccorels.invoke(0)

    def printcorels(self):
        #print correlations in window
        self.corwin.clear()
        self.corwin.insert(END,"Correlations for fit\n")
        self.corwin.insert(END,"File: "+self.fileentry.get()+"\n\n")
        #print chisquare and R-value
        line="NumIDP:     "+str(iffc.get_scalar('n_idp'))+"\t\tNumVars:"+str(iffc.get_scalar('n_varys'))
        self.corwin.insert(END,line+'\n')
        line="Chi-Sq:     "+str(iffc.get_scalar('chi_square'))+"\t\tR-value: "+str(iffc.get_scalar('r_factor'))
        self.corwin.insert(END,line+'\n')
        line="Red Chi-Sq: "+str(iffc.get_scalar('chi_reduced'))
        self.corwin.insert(END,line+'\n\n')
        #get list of all guessed variables
        guessvar=[]
        for v in self.varwidlist:
            if v.type.getcurselection()=='G' and v.von.get()==1:
                guessvar.append(v)
        #get correlations
        gvar2=guessvar
        for v0 in guessvar:
            for v1 in gvar2:
                #get v0-v1 correlation
                xvar=v0.vname.get()
                yvar=v1.vname.get()
                if xvar!=yvar:
                    iffc.ifeffit("correl(x="+xvar+",y="+yvar+",min=0,out=correl_last)")
                    corel=iffc.get_scalar('correl_last')
                    if abs(corel)>0.10:
                        vartext=ljust(xvar+'-'+yvar+':',30)
                        if abs(corel)>0.75:
                            self.corwin.insert(END,vartext+'\t'+str(corel)+'\n',"hi")
                        else:
                            self.corwin.insert(END,vartext+'\t'+str(corel)+'\n')
            gvar2.remove(v0)
       
    def addfitvar(self):
        new=DefVar(self.vfield)
        self.varwidlist.append(new)

    def addallfitvar(self):
        for path in self.pathwidlist:
            if path.p.pon.get()==1:
                if path.p.s02.get()<>'': self.parsevarlist(path.p.s02)
                if path.p.e0.get()<>'': self.parsevarlist(path.p.e0)
                if path.p.deltaR.get()<>'': self.parsevarlist(path.p.deltaR)
                if path.p.sig.get()<>'': self.parsevarlist(path.p.sig)
                if path.p.third.get()<>'': self.parsevarlist(path.p.third)
                if path.p.fourth.get()<>'': self.parsevarlist(path.p.fourth)

    def parsevarlist(self,vf):
        vtotal=vf.get()
        parsed=['-','+','*','/','(',')',',','abs','sqrt','exp','log','erf','erfc','sign','debye','eins','min','max','cos','sin','tan','reff']
        for x in parsed:
            vtotal=replace(vtotal,x,' ')
        vtotal=split(vtotal)
        for y in vtotal:
            self.addtovarlist(y)
 
    def addtovarlist(self,vw):
        #check to see if variable is already there!
        pres=0
        for var in self.varwidlist:
            if var.vname.get()==vw:
                pres=1
        if pres==0:
            self.addfitvar()
            newvar=self.varwidlist[len(self.varwidlist)-1]
            newvar.vname.setentry(vw)

    def restraintfitvar(self):
        curfoc=self.adwin.focus_get()
        curname=curfoc.master
        curframe=curname.master
        focvar=0
        focwid=''
        for v in self.varwidlist:
            if str(v.vname)==str(curfoc.master):
                focvar=1
                focwid=v
            if str(v.vexp)==str(curfoc.master):
                focvar=1
                focwid=v
        if focvar==0:
            #not a variable
            tkMessageBox.showwarning("Variable Restraint","No variable selected")
            return
        #toggle restraint status
        focwid.restraint=focwid.restraint+1
        if int(focwid.restraint)==1:
            #change layout to mark variable        
            focwid.f.configure(bg='red')
            focwid.cb.configure(bg='red')
            focwid.type.configure(Button_bg='red')
        if int(focwid.restraint)==2:
            focwid.restraint=0
            #undo frame
            if sys.platform == 'win32':
                focwid.f.configure(bg='SystemButtonFace')
                focwid.cb.configure(bg='SystemButtonFace')
                focwid.type.configure(Button_bg='SystemButtonFace')
            else:
                focwid.f.configure(bg='#d4d0c8')
                focwid.cb.configure(bg='#d4d0c8')
                focwid.type.configure(Button_bg='#d4d0c8')
                
    def deletefitvar(self):
        curfoc=self.adwin.focus_get()
        curname=curfoc.master
        curframe=curname.master
        focvar=0
        focwid=''
        for v in self.varwidlist:
            if str(v.vname)==str(curfoc.master):
                focvar=1
                focwid=v
            if str(v.vexp)==str(curfoc.master):
                focvar=1
                focwid=v
        if focvar==0:
            #not a variable
            tkMessageBox.showwarning("Remove Variable","No variable selected")
            return
        #make sure
        name=focwid.vname.getvalue()
        suretext="Remove variable named "+name
        ask=tkMessageBox.askyesno("Remove Variable",suretext)
        if ask==0:
            return
        #kill variable in IFEFFIT
        if name!='':
            iffc.ifeffit("erase "+name)
        #remove from varlist
        self.varwidlist.remove(focwid)
        #kill widget
        curframe.destroy()

    def sortfitvarsbyname(self):
        #create dictionary
        vard={}
        for v in self.varwidlist:
            #frame name, var frame
            vard.update({v.vname.getvalue():v.f})
            #unpack all
            v.f.pack_forget()        
        #sort
        keys=vard.keys()
        keys.sort()
        sortlist=[vard[key] for key in keys]
        #repack
        for i in sortlist:
            i.pack(side=TOP,padx=2)

    def sortfitvarsbyletter(self):
        #create dictionary
        vard={}
        for v in self.varwidlist:
            #frame name, var frame
            vard.update({upper(v.vname.getvalue()):v.f})
            #unpack all
            v.f.pack_forget()        
        #sort
        keys=vard.keys()
        keys.sort()
        sortlist=[vard[key] for key in keys]
        #repack
        for i in sortlist:
            i.pack(side=TOP,padx=2)

    def sortfitvarsbycreation(self):
        for v in self.varwidlist:
            #unpack all
            v.f.pack_forget()        
        #repack
        for v in self.varwidlist:
            v.f.pack(side=TOP,padx=2)

    def sortfitvarsbypath(self):
        lefttogo=self.varwidlist
        for v in self.varwidlist:
            #unpack all
            v.f.pack_forget()
        for path in self.pathwidlist:
            if path.p.pon.get()==1:
                wids=[path.p.s02,path.p.e0,path.p.deltaR,path.p.sig,path.p.third,path.p.fourth]
                for w in wids:
                    for v in lefttogo:
                        if rfind(w.get(),v.vname.getvalue())!=-1:
                            v.f.pack(side=TOP,padx=2)
                            lefttogo.remove(v)
        #do the rest by letter
        if len(lefttogo)!=0:
            vard={}
            for v in lefttogo:
                vard.update({upper(v.vname.getvalue()):v.f})
            #sort
            keys=vard.keys()
            keys.sort()
            sortlist=[vard[key] for key in keys]
            #repack
            for i in sortlist:
                i.pack(side=TOP,padx=2)
            
    def addfeffpath(self):
        self.npath=self.npath+1
        pname="Path "+str(self.npath)
        new=self.pathdes.add(pname)
        new.p=DefPath(new,pname)
        self.pathwidlist.append(new)
        self.pathlist.append(pname) #str(self.npath)+":")
        c=self.pathsel.curselection()
        self.pathsel.setlist(self.pathlist)
        if c==():
            self.pathsel.select_set(0)
        else:
            self.pathsel.select_set(c)
 
    def changepath(self):
        #cursel=self.pathsel.getcurselection()[0]
        #ind=find(cursel,':')
        #curnum=cursel[0:ind]
        #page='Path '+curnum
        self.pathdes.selectpage(self.pathsel.getcurselection()[0])

    def varreff(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.deltaR.setentry("R"+pnum+"-reff")

    def abssigma(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.sig.setentry("abs(sig"+pnum+")")

    def pathsimple(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.s02.setentry("s02_"+pnum)
        ap.p.e0.setentry("e0_"+pnum)
        ap.p.deltaR.setentry("delR_"+pnum)
        ap.p.sig.setentry("sig_"+pnum)

    def pathsimplel(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.s02.setentry("s02")
        ap.p.e0.setentry("e0")
        ap.p.deltaR.setentry("delR_"+pnum)
        ap.p.sig.setentry("sig_"+pnum)

    def pathcnumu(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.s02.setentry("N"+pnum+"*s02")
        ap.p.e0.setentry("e0_"+pnum)
        ap.p.deltaR.setentry("delR_"+pnum)
        ap.p.sig.setentry("sig_"+pnum)
        
    def pathcnuml(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.s02.setentry("N"+pnum+"*s02")
        ap.p.e0.setentry("e0")
        ap.p.deltaR.setentry("delR_"+pnum)
        ap.p.sig.setentry("sig_"+pnum)

    def pathdebye(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.s02.setentry("amp_"+pnum)
        ap.p.e0.setentry("e0_"+pnum)
        ap.p.deltaR.setentry("delR_"+pnum)
        ap.p.sig.setentry("debye(temp,theta_"+pnum+")")
        
    def pathMedebye(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.s02.setentry("amp_Me")
        ap.p.e0.setentry("e0_Me")
        ap.p.deltaR.setentry("delR_"+pnum+"-reff")
        ap.p.sig.setentry("debye(temp,thetaMe)")

    def pathodebye(self):
        #get current path
        cptuple=self.pathsel.getcurselection()
        cp=cptuple[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        #set entries
        ap.p.s02.setentry("amp_O")
        ap.p.e0.setentry("e0_O")
        ap.p.deltaR.setentry("delR_"+pnum+"-reff")
        ap.p.sig.setentry("debye(temp,thetaO)")

    def fileme(self):
        fileget(root.adwin,self.fileentry)

    def load_data_file(self):
        self.dataname=trimdirext(self.fileentry.get())
        if self.dataname=='':
            print "   ERROR: Empty file name"
        else:
            iffc.ifeffit("read_data(file="+self.fileentry.get()+", group="+self.dataname+",label='k chi')")
            setstatus(self.status,"Data file "+self.dataname+" loaded!")

    def menuopen(self):
        self.fileme()
        self.load_data_file()

    def sp_plot(self,new,gx,gy,xlab,ylab,title,xmin,xmax,key):
        keytext=""
        if key==1: keytext="""k"""+self.kplotwt.get()+""" chi(k)-data"""
        elif key==2: keytext="""k"""+self.kplotwt.get()+""" chi(k)-fit"""
        elif key==3: keytext="""|chi(R)|-data"""
        elif key==4: keytext="""Re[chi(R)]-data"""
        elif key==5: keytext="""Im[chi(R)]-data"""
        elif key==6: keytext="""|chi(R)|-fit"""
        elif key==7: keytext="""Re[chi(R)]-fit"""
        elif key==8: keytext="""Im[chi(R)]-fit"""
        elif key==9: keytext="""Re[chi(q)]-data"""
        elif key==10: keytext="""Im[chi(q)]-data"""
        elif key==11: keytext="""Re[chi(q)]-fit"""
        elif key==12: keytext="""Im[chi(q)]-fit"""
        elif key==13: keytext="""FT Window"""
        elif key==14: keytext="""Residuals"""
        elif key==15: keytext="""Background Spline"""
        else:
            pathnum=key-15
            keytext="""Path """+str(pathnum)
        xdat=iffc.get_array(gx)
        ydat=iffc.get_array(gy)
        if new==1: spplotter.SPPlotter(self.root,cmd="new",lt=keytext,xd=xdat,yd=ydat,xt=xlab,yt=ylab,
                                       title=title,xmin=xmin,xmax=xmax)
        if new==0: spplotter.SPPlotter(self.root,cmd="stack",lt=keytext,xd=xdat,yd=ydat,xt=xlab,yt=ylab,
                                       title=title,xmin=xmin,xmax=xmax)

    def make_k_plot(self):
        plotme=self.kplots.getcurselection()
        newg=1
        km1=self.kplotmin.get()
        km2=self.kplotmax.get()
        for pt in plotme:
            if pt=='Data':
                dn=self.dataname
                iffc.ifeffit("dokwt "+dn+" "+self.kplotwt.get())
                self.sp_plot(newg,dn+".k",dn+".chi_kw","k","chi",dn,km1,km2,1)
                newg=0
            if pt=='Fit':
                iffc.ifeffit("dokwt fit "+self.kplotwt.get())
                self.sp_plot(newg,"fit.k","fit.chi_kw","k","chi","FEFF Data",km1,km2,2)
                newg=0
            if pt=='Residuals':
                dn=self.dataname
                iffc.ifeffit("dokwt "+dn+" "+self.kplotwt.get())
                iffc.ifeffit("dokwt fit "+self.kplotwt.get())
                iffc.ifeffit("fit.kwres="+dn+".chi_kw-fit.chi_kw")
                self.sp_plot(newg,"fit.k","fit.kwres","k","chi","FEFF Data",km1,km2,14)
                newg=0                
            if pt=='FT Window':
                dn=self.dataname
                iffc.ifeffit("window(k="+dn+".k,group=win,kweight="+self.kweight.get()+",kmin="+\
                         self.kmin.get()+",kmax="+self.kmax.get()+""",kwindow='"""+\
                         self.winparam.get()+"""',dk="""+self.dk.get()+")")
                iffc.ifeffit("win.mwin=win.win*ceil(abs("+dn+".chi_kw))")
                wdat=iffc.get_array("win.mwin")
                self.sp_plot(newg,dn+".k","win.mwin","k","chi","FEFF Data",km1,km2,13)
        if self.fitmenuspline.get()==1:
            self.sp_plot(newg,"fit.k","fit.kbkg","k","chi","FEFF Data",km1,km2,15)
        setstatus(self.status,"k plot complete")

    def make_R_plot(self):
        plotme=self.rplots.getcurselection()
        plottpy=self.rptype.getcurselection()
        win=self.winparam.get(ACTIVE)
        kw=self.kweight.get()
        dk=self.dk.get()
        rm1=self.rplotmin.get()
        rm2=self.rplotmax.get()
        newg=1
        for pt in plotme:
            if pt=='Data':
                dn=self.dataname
                iffc.ifeffit("fftf(real="+dn+".chi,kweight="+kw+",kmin="+self.kmin.get()+\
                             ",kmax="+self.kmax.get()+""",kwindow='"""+win+"""',dk="""+dk+")")
                for pt2 in plottpy:
                    if pt2=='Magnitude':
                        self.sp_plot(newg,dn+".r",dn+".chir_mag","R","Amp",dn,rm1,rm2,3)
                        newg=0
                    if pt2=='Real':
                        self.sp_plot(newg,dn+".r",dn+".chir_re","R","Amp",dn,rm1,rm2,4)
                        newg=0
                    if pt2=='Imaginary':
                        self.sp_plot(newg,dn+".r",dn+".chir_im","R","Amp",dn,rm1,rm2,5)
                        newg=0
            if pt=='Fit':
                iffc.ifeffit("fftf(real=fit.chi,kweight="+kw+",kmin="+self.kmin.get()+\
                             ",kmax="+self.kmax.get()+""",kwindow='"""+win+"""',dk="""+dk+")")
                for pt2 in plottpy:
                    if pt2=='Magnitude':
                        self.sp_plot(newg,"fit.r","fit.chir_mag","R","Amp","FEFF Data",rm1,rm2,6)
                        newg=0
                    if pt2=='Real':
                        self.sp_plot(newg,"fit.r","fit.chir_re","R","Amp","FEFF Data",rm1,rm2,7)
                        newg=0
                    if pt2=='Imaginary':
                        self.sp_plot(newg,"fit.r","fit.chir_im","R","Amp","FEFF Data",rm1,rm2,8)
                        newg=0
        setstatus(self.status,"R plot complete")
        
    def make_q_plot(self):
        plotme=self.qplots.getcurselection()
        plottpy=self.qptype.getcurselection()
        qm1=self.qplotmin.get()
        qm2=self.qplotmax.get()
        newg=1
        for pt in plotme:
            if pt=='Data':
                dn=self.dataname
                iffc.ifeffit("fftr(real="+dn+".chir_re,imag="+dn+".chir_im,rmin="+self.rmin.get()+\
                             ",rmax="+self.rmax.get()+",dr=0.2)")
                for pt2 in plottpy:
                    if pt2=='Real':
                        self.sp_plot(newg,dn+".q",dn+".chiq_re","q","chi",dn,qm1,qm2,9)
                        newg=0
                    if pt2=='Imaginary':
                        self.sp_plot(newg,dn+".q",dn+".chiq_im","q","chi",dn,qm1,qm2,10)
                        newg=0
            if pt=='Fit':
                iffc.ifeffit("fftr(real=fit.chir_re,imag=fit.chir_im,rmin="+self.rmin.get()+\
                             ",rmax="+self.kmax.get()+",dr=0.2)")
                for pt2 in plottpy:
                    if pt2=='Real':
                        self.sp_plot(newg,"fit.q","fit.chiq_re","q","chi","FEFF Data",qm1,qm2,11)
                        newg=0
                    if pt2=='Imaginary':
                        self.sp_plot(newg,"fit.q","fit.chiq_im","q","chi","FEFF Data",qm1,qm2,12)
                        newg=0
        setstatus(self.status,"q plot complete")

    def deffeffpath(self):
        #get current path
        cp=self.pathsel.getcurselection()[0]
        #get index of Path with pathlist
        #refer to correct widgets in pathwidlist.p.XXXX
        pi=self.pathlist.index(cp)
        ap=self.pathwidlist[pi]
        pnum=str(pi+1)
        self.deffeffpathfin(pnum,ap.p)
        setstatus(self.status,"FEFF Path "+pnum+" defined!")
        
    def deffeffpathfin(self,pnum,path):        
        #tell ifeffit to define path...
        iffc.ifeffit("path("+pnum+",feff="+path.loc.get()+")")
        iffc.ifeffit("path("+pnum+",label="+path.descr.get()+")")
        iffc.ifeffit("path("+pnum+",s02="+path.s02.get()+",e0="+path.e0.get()+",delr="+path.deltaR.get()+",sigma2="+path.sig.get()+")")
        iffc.ifeffit("get_path("+pnum+")")
        pzn=zfill(pnum,3)
        #fill default degen if needed
        if not self.pathdegenf.has_key(pnum):
            self.pathdegenf.update({pnum:path.loc.get()})
            self.pathdegen.update({pnum:iffc.get_scalar("path"+pzn+"_degen")})            
        if self.pathdegenf[pnum]!=path.loc.get():
            self.pathdegenf.update({pnum:path.loc.get()})
            self.pathdegen.update({pnum:iffc.get_scalar("path"+pzn+"_degen")})            
        if path.dset.get()==1:
            iffc.ifeffit("path("+pnum+",degen=1)")
        if path.dset.get()==0:
            iffc.ifeffit("path("+pnum+",degen="+str(self.pathdegen[pnum])+")")
        if path.third.get()<>"":
            iffc.ifeffit("path("+pnum+",third="+path.third.get()+")")
        if path.fourth.get()<>"":
            iffc.ifeffit("path("+pnum+",fourth="+path.fourth.get()+")")

    def doff2chi(self):
        iffc.ifeffit("set_fit_params "+self.kmin.get()+" "+self.kmax.get()+" "+self.rmin.get()+" "+\
                     self.rmax.get()+" "+self.kweight.get()+" "+self.dk.get()+" "+self.winparam.get(ACTIVE)+" "+self.spcparam.get(ACTIVE))
        #update all variables with def
        for var in self.varwidlist:
            if var.von.get()==1:
                iffc.ifeffit("def("+var.vname.get()+"="+var.vexp.get()+")")
            if var.von.get()==0:
                iffc.ifeffit("def("+var.vname.get()+"=0)")
        #get active paths
        aps=[]
        for path in self.pathwidlist:
            if path.p.pon.get()==1:
                pi=self.pathwidlist.index(path)
                pnam=self.pathlist[pi]
                pnum=atoi(pnam[5:])
                aps.append(pnum)
                self.deffeffpathfin(str(pnum),path.p)
        straps=str(aps)
        straps=straps[1:len(straps)-1]        
        #call ff2chi        
        iffc.ifeffit("ff2chi("+straps+",group=fit,do_all)")
        ##calculate the residuals
        ##dn=self.dataname
        ##iffc.ifeffit("fit.kwres="+dn+".chi_kw-fit.chi_kw")
        if self.mstat==0: setstatus(self.status,"ff2chi calculated on checked paths.")
        self.mstat=0

    def dopathff2chi(self):
        iffc.ifeffit("set_fit_params "+self.kmin.get()+" "+self.kmax.get()+" "+self.rmin.get()+" "+\
                     self.rmax.get()+" "+self.kweight.get()+" "+self.dk.get()+" "+self.winparam.get(ACTIVE)+" "+self.spcparam.get(ACTIVE))
        #update all variables with def
        for var in self.varwidlist:
            if var.von.get()==1:
                iffc.ifeffit("def("+var.vname.get()+"="+var.vexp.get()+")")
            if var.von.get()==0:
                iffc.ifeffit("def("+var.vname.get()+"=0)")
        #get current path
        pind=int(self.pathsel.curselection()[0])
        pnam=self.pathlist[pind]
        pnum=atoi(pnam[5:])
        self.deffeffpathfin(str(pnum),self.pathwidlist[pind].p)
        iffc.ifeffit("ff2chi("+str(pnum)+",group=fit,do_all)")
        if self.mstat==0: setstatus(self.status,"ff2chi calculated on active path.")
        self.mstat=0

    def plotpathfittype(self,index,newg):
        #determine plottype
        if index==0:
            key=[2,6,11]
        else:
            key=[index+15,index+15,index+15]
        if self.cumpathtype.getvalue()=='k':
            #plot k
            km1=self.kplotmin.get()
            km2=self.kplotmax.get()
            iffc.ifeffit("dokwt fit "+self.kplotwt.get())
            self.sp_plot(newg,"fit.k","fit.chi_kw","k","chi","FEFF Data",km1,km2,key[0])
            newg=0
        if self.cumpathtype.getvalue()=='R':
            #plot R
            win=self.winparam.get(ACTIVE)
            kw=self.kweight.get()
            dk=self.dk.get()
            rm1=self.rplotmin.get()
            rm2=self.rplotmax.get()
            iffc.ifeffit("fftf(real=fit.chi,kweight="+kw+",kmin="+self.kmin.get()+\
                         ",kmax="+self.kmax.get()+""",kwindow='"""+win+"""',dk="""+dk+")")
            self.sp_plot(newg,"fit.r","fit.chir_mag","R","Amp","FEFF Data",rm1,rm2,key[1])
            newg=0
        if self.cumpathtype.getvalue()=='q':
            #plot q
            win=self.winparam.get(ACTIVE)
            kw=self.kweight.get()
            dk=self.dk.get()
            qm1=self.qplotmin.get()
            qm2=self.qplotmax.get()
            iffc.ifeffit("fftf(real=fit.chi,kweight="+kw+",kmin="+self.kmin.get()+\
                         ",kmax="+self.kmax.get()+""",kwindow='"""+win+"""',dk="""+dk+")")
            iffc.ifeffit("fftr(real=fit.chir_re,imag=fit.chir_im,rmin="+self.rmin.get()+\
                         ",rmax="+self.kmax.get()+",dr=0.2)")
            self.sp_plot(newg,"fit.q","fit.chiq_re","q","chi","FEFF Data",qm1,qm2,key[2])
            newg=0
        
    def plotpathcontributions(self):
        #recalculate w/ current settings
        newg=1
        self.doff2chi()
        #plot data if needed
        if 'Data' in self.cumpathsels.getvalue():
            self.load_data_file()
            dn=self.dataname
            #determine plottype
            if self.cumpathtype.getvalue()=='k':
                #plot k
                km1=self.kplotmin.get()
                km2=self.kplotmax.get()
                iffc.ifeffit("dokwt "+dn+" "+self.kplotwt.get())
                self.sp_plot(newg,dn+".k",dn+".chi_kw","k","chi",dn,km1,km2,1)
                newg=0
            if self.cumpathtype.getvalue()=='R':
                #plot R
                win=self.winparam.get(ACTIVE)
                kw=self.kweight.get()
                dk=self.dk.get()
                rm1=self.rplotmin.get()
                rm2=self.rplotmax.get()
                iffc.ifeffit("fftf(real="+dn+".chi,kweight="+kw+",kmin="+self.kmin.get()+\
                             ",kmax="+self.kmax.get()+""",kwindow='"""+win+"""',dk="""+dk+")")
                self.sp_plot(newg,dn+".r",dn+".chir_mag","R","Amp",dn,rm1,rm2,3)
                newg=0
            if self.cumpathtype.getvalue()=='q':
                #plot q
                qm1=self.qplotmin.get()
                qm2=self.qplotmax.get()
                iffc.ifeffit("fftr(real="+dn+".chir_re,imag="+dn+".chir_im,rmin="+self.rmin.get()+\
                             ",rmax="+self.rmax.get()+",dr=0.2)")
                self.sp_plot(newg,dn+".q",dn+".chiq_re","q","chi",dn,qm1,qm2,9)
                newg=0
        #plot entire fit if desired
        if 'Fit' in self.cumpathsels.getvalue():
            self.plotpathfittype(0,newg)
            newg=0
        pinit=int(self.pathsel.curselection()[0])
        self.pathsel.select_clear(pinit)
        #iterate through dopathff2chi adding plots
        for path in self.pathwidlist:
            if path.p.pon.get()==1:
                pi=self.pathwidlist.index(path)
                self.pathsel.select_set(pi)
                self.dopathff2chi()
                self.pathsel.select_clear(pi)
                #add path plot
                pnam=self.pathlist[pi]
                pnum=atoi(pnam[5:])
                self.plotpathfittype(pnum,newg)
                newg=0
        #reset current path
        self.pathsel.select_set(pinit)        
        setstatus(self.status,"Path contributions calculated on active paths and plotted.")

    def recallvarbuffer(self):
        for var in self.varwidlist:
            temp=var.vexp.get()
            var.vexp.setentry(var.buffer)
            var.buffer=temp
      
    def dofit(self):
        #reload data
        self.load_data_file()
        dn=self.dataname
        #set fit parameters
        fitparamcmd=",rmin="+self.rmin.get()+",rmax="+self.rmax.get()+",kmin="+self.kmin.get()+\
                     ",kmax="+self.kmax.get()+",kweight="+self.kweight.get()+",dk="+self.dk.get()+\
                     ",kwindow="+self.winparam.get(ACTIVE)+",fit_space="+self.spcparam.get(ACTIVE)

        kwmenu=self.fitmenukweight.get()
        if kwmenu!=0:
            fitparamcmd=",rmin="+self.rmin.get()+",rmax="+self.rmax.get()+",kmin="+self.kmin.get()+\
                         ",kmax="+self.kmax.get()+",dk="+self.dk.get()+\
                         ",kwindow="+self.winparam.get(ACTIVE)+",fit_space="+self.spcparam.get(ACTIVE)            
            if kwmenu==1:
                fitparamcmd=fitparamcmd+",kweight=3,kweight=2,kweight=1,kweight=0"
            if kwmenu==2:
                fitparamcmd=fitparamcmd+",kweight=3,kweight=2,kweight=1"
            if kwmenu==3:
                fitparamcmd=fitparamcmd+",kweight=3,kweight=2"
        if self.fitmenuspline.get()==1:
            fitparamcmd=fitparamcmd+",do_bkg=true"
        #update guess, set and defs...
        for var in self.varwidlist:
            var.buffer=var.vexp.get()
            if var.von.get()==1:
                if var.type.getcurselection()=='D':
                    iffc.ifeffit("def("+var.vname.get()+"="+var.vexp.get()+")")
                if var.type.getcurselection()=='S':
                    iffc.ifeffit("set("+var.vname.get()+"="+var.vexp.get()+")")
                if var.type.getcurselection()=='G':
                    iffc.ifeffit("guess("+var.vname.get()+"="+var.vexp.get()+")")
                if var.restraint==1:
                    fitparamcmd=fitparamcmd+",restraint="+var.vname.get()
            if var.von.get()==0:
                iffc.ifeffit("def("+var.vname.get()+"=0)")
        aps=[]
        for path in self.pathwidlist:
            if path.p.pon.get()==1:
                pi=self.pathwidlist.index(path)
                pnam=self.pathlist[pi]
                pnum=atoi(pnam[5:])
                aps.append(pnum)
                self.deffeffpathfin(str(pnum),path.p)
        straps=str(aps)
        straps=straps[1:len(straps)-1]
        setstatus(self.status,"FEFF fit in progress")
        self.status.configure(bg='red')
        self.status.update_idletasks()
        #call ifeffit
        iffc.ifeffit("feffit("+straps+",chi="+dn+".chi,group=fit"+fitparamcmd+")")
        #set fitting statistics
        setstatus_d(self.Rvalue,iffc.get_scalar("r_factor"),5)
        setstatus_d(self.ChiSq,iffc.get_scalar("chi_square"),3)
        setstatus_d(self.ChiSqR,iffc.get_scalar("chi_reduced"),3)
        iffc.ifeffit("show n_idp,n_varys")
        #replace guesses
        for var in self.varwidlist:
            if var.von.get()==1:
                if var.type.getcurselection()=='G':
                    var.vexp.setentry(str(iffc.get_scalar(var.vname.get())))
        #print in results window...   allow 15 spaces per field     
        fwd=15
        #self.restext.config(state=NORMAL)
        self.restext.clear()
        if self.respathvar.get()==1:
            self.restext.insert(END,'PATH VARIABLE VALUES... \n')
            for path in self.pathwidlist:
                if path.p.pon.get()==1:
                    pi=self.pathwidlist.index(path)
                    pnam=self.pathlist[pi]
                    pnum=pnam[5:]
                    pzn=zfill(pnum,3)
                    iffc.ifeffit("get_path("+pnum+")")
                    self.restext.insert(END,'\n '+pnam+'    '+path.p.descr.get()+' \n')
                    #evaluate all path vars...
                    pxso2=self.clipresults(iffc.get_scalar("path"+pzn+"_s02"))
                    pxeo=self.clipresults(iffc.get_scalar("path"+pzn+"_e0"))
                    pxr=self.clipresults(iffc.get_scalar("path"+pzn+"_reff")+iffc.get_scalar("path"+pzn+"_delr"))
                    pxss=self.clipresults(iffc.get_scalar("path"+pzn+"_sigma2"))
                    pxth=self.clipresults(iffc.get_scalar("path"+pzn+"_third"))
                    pxft=self.clipresults(iffc.get_scalar("path"+pzn+"_fourth"))
                    newline=ljust("Amplitude",fwd)+ljust(pxso2,fwd)+"\n"
                    self.restext.insert(END,newline)
                    newline=ljust("e0",fwd)+ljust(pxeo,fwd)+"\n"
                    self.restext.insert(END,newline)
                    newline=ljust("R",fwd)+ljust(pxr,fwd)+"\n"
                    self.restext.insert(END,newline)
                    newline=ljust("Sigma2",fwd)+ljust(pxss,fwd)+"\n"
                    self.restext.insert(END,newline)
                    newline=ljust("Third",fwd)+ljust(pxth,fwd)+"\n"
                    self.restext.insert(END,newline)
                    newline=ljust("Fourth",fwd)+ljust(pxft,fwd)+"\n"
                    self.restext.insert(END,newline)
        self.restext.insert(END,'\nALL VARIABLE VALUES... \n \n')
        for var in self.varwidlist:
            if var.von.get()==1:
                #print var,exp, and error if guessed
                varval=self.clipresults(iffc.get_scalar(var.vname.get()))
                newline=ljust(var.vname.get(),fwd)+ljust(varval,fwd)
                if var.type.getcurselection()=='G':
                    varer=self.clipresults(iffc.get_scalar("delta_"+var.vname.get()))
                    newline=newline+ljust(pm+varer,fwd)
                newline=newline+" \n"
                self.restext.insert(END,newline)
        ####calculate the residuals
        ###iffc.ifeffit("fit.kwres="+dn+".chi_kw-fit.chi_kw")
        #print correlations if needed
        self.printcorels()
        #self.restext.config(state=DISABLED)
        if sys.platform=='win32':
            self.status.configure(bg='SystemButtonFace')
        else:
            self.status.configure(bg='#d4d0c8')
        setstatus(self.status,"FEFF fit completed!")
        self.mstat=1
        self.doff2chi()

    def clipresults(self,v):
        dig=8
        val=str(v)
        decind=rfind(val,'.')
        eind=rfind(val,"e")
        if eind==-1:
            if decind>dig:
                val=val[:decind+2]
            else:
                val=val[:dig]
        else:
            val=val[:4]+val[eind:len(val)]        
        return val

    def savefitdata(self):
        global lastsavedir
        nfn=ask_save_file('',lastsavedir)
        root.adwin.focus_set()
        if nfn<>"":
            sdir=rfind(nfn,os.sep)
            lastsavedir=nfn[:sdir]            
            iffc.ifeffit("write_data(file="+nfn+"_chi.dat, fit.k,fit.chi)")
            iffc.ifeffit("write_data(file="+nfn+"_r.dat, fit.r,fit.chir_mag,fit.chir_re,fit.chir_im)")
            setstatus(self.status,"Fit data saved to "+nfn)

    def saverawdata(self):
        global lastsavedir
        dn=self.dataname
        nfn=ask_save_file('',lastsavedir)
        root.adwin.focus_set()
        if nfn<>"":
            sdir=rfind(nfn,os.sep)
            lastsavedir=nfn[:sdir]            
            iffc.ifeffit("write_data(file="+nfn+"_chi.dat, "+dn+".k,"+dn+".chi)")
            iffc.ifeffit("write_data(file="+nfn+"_r.dat, "+dn+".r,"+dn+".chir_mag,"+dn+".chir_re,"+dn+".chir_im)")
            setstatus(self.status,"File spectral data saved to "+nfn)

    def saveresiddata(self):
        global lastsavedir
        dn=self.dataname
        nfn=ask_save_file('',lastsavedir)
        root.adwin.focus_set()
        if nfn<>"":
            sdir=rfind(nfn,os.sep)
            lastsavedir=nfn[:sdir]    
            #iffc.ifeffit("fit.kwres="+dn+".chi_kw-fit.chi_kw")
            #iffc.ifeffit("fit.knz=fit.k+0.0001")
            #iffc.ifeffit("fit.res=fit.kwres/(fit.knz^"+self.kweight.get()+")")
            iffc.ifeffit("fit.res="+dn+".chi-fit.chi")
            iffc.ifeffit("write_data(file="+nfn+"_res_chi.dat, "+dn+".k,fit.res)")
            setstatus(self.status,"Residual spectral data saved to "+nfn)

    def saveallvars(self):
        global lastsavedir
        #place all paths and varibles into a parameter file
        #get file name
        nfn=ask_save_file('',lastsavedir)
        root.adwin.focus_set()
        if nfn=="":
            setstatus(self.status,"Save parameters aborted")        
        else:
            sdir=rfind(nfn,os.sep)
            lastsavedir=nfn[:sdir]            
            #open file
            #check for extension ending
            ext=rfind(nfn,".")
            if ext==-1:
                nfn=nfn+".prm"
            fid=open(nfn,"w")
            #save data-file parameters
            fid.write("FPARAMS\n")
            #enter filename,kmin,kmax,rmin,rmax,kw,dk
            fid.write(self.fileentry.get()+"\n")
            fid.write(self.kmin.get()+"\n")
            fid.write(self.kmax.get()+"\n")
            fid.write(self.rmin.get()+"\n")
            fid.write(self.rmax.get()+"\n")
            fid.write(self.kweight.get()+"\n")
            fid.write(self.dk.get()+"\n")
            #save all parts of all ACTIVE paths
            for sp in self.pathwidlist:
                if sp.p.pon.get()==1:
                    pi=self.pathwidlist.index(sp)
                    pnam=self.pathlist[pi]
                    pnum=pnam[5:]
                    fid.write(pnam+"\n")
                    fid.write(str(sp.p.pon.get())+"\n")
                    fid.write(str(sp.p.dset.get())+"\n")
                    fid.write(sp.p.loc.get()+"\n")
                    fid.write(sp.p.descr.get()+"\n")
                    fid.write(sp.p.s02.get()+"\n")
                    fid.write(sp.p.e0.get()+"\n")
                    fid.write(sp.p.deltaR.get()+"\n")
                    fid.write(sp.p.sig.get()+"\n")
                    fid.write(sp.p.third.get()+"\n")
                    fid.write(sp.p.fourth.get()+"\n")
            #save all ACTIVE variables
            fid.write("VARS\n")
            for var in self.varwidlist:
                if var.von.get()==1:
                    fid.write(var.vname.get()+"\n")
                    fid.write(str(var.von.get())+"\n")
                    fid.write(var.type.getcurselection()+"\n")
                    fid.write(var.vexp.get()+"\n")
            fid.write("END")
            fid.close()            
            setstatus(self.status,"Fit parameters saved to "+nfn)        

    def loadallvars(self):
        global lastreaddir
        #load paths and variables from files
        #get file name
        fn=ask_for_file([("parameter files","*.prm"),("all files","*")],lastreaddir,check=0)
        root.adwin.focus_set()
        if fn=="":
            setstatus(self.status,"Load parameters aborted")
        else:
            sdir=rfind(fn,os.sep)
            lastreaddir=fn[:sdir]
            #clear all paths and variables
            for dp in self.pathlist:
                self.pathdes.delete(dp)
            self.pathwidlist=[]
            self.pathlist=[]
            self.npath=0
            for dv in self.varwidlist:
                dv.f.destroy()
            self.varwidlist=[]
            #open file
            fid=open(fn,"r")
            param=fid.read()
            fid.close()
            #parse file...
            lp=split(param,'\n')
            ind=0
            for new in lp:
                if new=='EDGEPARAMS' or new=='BSPARAMS':
                    #wrong parameter file
                    self.box.deiconify()
                if new=='FPARAMS':
                    #read data-file parameters
                    #read filename,kmin,kmax,rmin,rmax,kw,dk
                    self.fileentry.setentry(lp[ind+1])
                    self.kmin.setentry(lp[ind+2])
                    self.kmax.setentry(lp[ind+3])
                    self.rmin.setentry(lp[ind+4])
                    self.rmax.setentry(lp[ind+5])
                    self.kweight.setentry(lp[ind+6])
                    self.dk.setentry(lp[ind+7])
                if new[0:5]=='Path ':
                    #do paths
                    self.addfeffpath()
                    ep=self.pathwidlist[len(self.pathwidlist)-1]
                    ep.p.pon.set(int(lp[ind+1]))
                    ep.p.dset.set(int(lp[ind+2]))
                    ep.p.loc.setentry(lp[ind+3])
                    ep.p.descr.setentry(lp[ind+4])
                    ep.p.s02.setentry(lp[ind+5])
                    ep.p.e0.setentry(lp[ind+6])
                    ep.p.deltaR.setentry(lp[ind+7])
                    ep.p.sig.setentry(lp[ind+8])
                    ep.p.third.setentry(lp[ind+9])
                    ep.p.fourth.setentry(lp[ind+10])
                if new=='VARS':
                    #do all variables
                    varread=lp[ind+1:]
                    vind=0
                    for nv in varread:
                        vind=vind+1
                        if nv<>'END':
                            if vind==1:
                                self.addfitvar()
                                newvar=self.varwidlist[len(self.varwidlist)-1]
                                newvar.vname.setentry(nv)
                            if vind==2:
                                newvar.von.set(int(nv))
                            if vind==3:
                                newvar.type.invoke(nv)
                            if vind==4:
                                newvar.vexp.setentry(nv)
                                vind=0
                ind=ind+1                       
            setstatus(self.status,"Parameter file read from "+fn)

################################################################
##
##
## Background Subtraction Routine
##
##
################################################################

def ktoE(k):
    k=float(k)
    e=k**2/0.262468292
    return e

def Etok(e):
    e=float(e)
    k=sqrt(e*0.262468292)
    return k

def remundsc(text):
    return replace(text,'_','')

class DefFParams:
    def __init__(self,master,fname):
        f=Frame(master)
        f.pack(side=TOP,padx=2,pady=0)
        if fname=='firsttest':
            lt=''
        else:
            lt=fname
        self.active=0
        self.calc=1
        self.splknot=0
        self.stepheight=0
        self.lab=Label(f,text=lt,relief=GROOVE,bd=2,width=50,justify=CENTER,font="Arial 10")
        #l.pack(side=TOP,fill=X,padx=2,pady=4)
        w=10
        self.enot=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='E0: ',validate='real',modifiedcommand=self.clicktochange)
        self.rbkg=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='Rbkg: ',value=1,validate='real',modifiedcommand=self.clicktochange)
        self.kwt=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='k-weight: ',value=3,validate='real',modifiedcommand=self.clicktochange)
        self.dk=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='dk: ',value=1,validate='real',modifiedcommand=self.clicktochange)
        self.prea=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='PreEdg: ',validate='real',modifiedcommand=self.clicktochange)
        self.preb=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='to E: ',validate='real',modifiedcommand=self.clicktochange)
        self.norma=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='Norm: ',validate='real',modifiedcommand=self.clicktochange)
        self.normb=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='to E: ',validate='real',modifiedcommand=self.clicktochange)
        self.splka=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='k: ',validate='real',command=self.enterka,modifiedcommand=self.clicktochange)
        self.splkb=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='to k: ',validate='real',command=self.enterkb,modifiedcommand=self.clicktochange)
        self.splea=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='E: ',validate='real',command=self.enterea,modifiedcommand=self.clicktochange)
        self.spleb=Pmw.EntryField(f,labelpos='w',entry_width=w,label_text='to E: ',validate='real',command=self.entereb,modifiedcommand=self.clicktochange)
        l2=Label(f,text='Pre-Edge Normalization')
        l2b=Label(f,text='Post-Edge Normalization')
        l3=Label(f,text='Spline Region')
        self.pretype=Pmw.RadioSelect(f,buttontype='radiobutton',orient='horizontal',labelpos=W,pady=0,command=self.clicktochange)
        for text in ('Linear','Gauss'):
            self.pretype.add(text)
        self.pretype.invoke('Linear')
        self.posttype=Pmw.RadioSelect(f,buttontype='radiobutton',orient='horizontal',labelpos=W,pady=0,command=self.clicktochange)
        for text in ('Linear','Quad'):
            self.posttype.add(text)
        self.posttype.invoke('Quad')
        windows=('Hanning','Kaiser-Bessel','Parzen','Welch','Sine')
        self.winparam=Pmw.ComboBox(f,label_text='FT Window: ',labelpos=W,scrolledlist_items=windows,listheight=100,entryfield_entry_width=15,history=0,
                                   selectioncommand=self.clicktochange)
        self.winparam.selectitem(windows[1])
        clamps=('None','Slight','Weak','Medium','Strong','Rigid')
        self.clamp1=Pmw.ComboBox(f,label_text='Low Clamp: ',labelpos=W,scrolledlist_items=clamps,listheight=120,entryfield_entry_width=10,history=0,
                                   selectioncommand=self.clicktochange)
        self.clamp1.selectitem(clamps[0])
        self.clamp2=Pmw.ComboBox(f,label_text='Hi Clamp: ',labelpos=W,scrolledlist_items=clamps,listheight=120,entryfield_entry_width=10,history=0,
                                   selectioncommand=self.clicktochange)
        self.clamp2.selectitem(clamps[0])        
        #define copyable entries
        self.copyable=[self.enot,self.rbkg,self.kwt,self.dk,self.prea,self.preb,self.norma,self.normb,\
                       self.splka,self.splkb,self.splea,self.spleb]
        for a in self.copyable:
            a.bind(sequence="<FocusIn>",  func=self.clicktochange) 
        #place all entries
        i=0
        d=2
        self.lab.grid(row=i,column=0,columnspan=2,pady=2*d);i=i+1
        self.enot.grid(row=i,column=0,pady=d)
        self.rbkg.grid(row=i,column=1,pady=d);i=i+1
        self.kwt.grid(row=i,column=0,pady=d)
        self.dk.grid(row=i,column=1,pady=d);i=i+1
        self.clamp1.grid(row=i,column=0,pady=2*d)
        self.clamp2.grid(row=i,column=1,pady=2*d);i=i+1        
        self.winparam.grid(row=i,column=0,columnspan=2,pady=2*d);i=i+1
        l2.grid(row=i,column=0,columnspan=1,pady=2*d);
        l2b.grid(row=i,column=1,columnspan=1,pady=2*d);i=i+1
        self.pretype.grid(row=i,column=0,columnspan=1,pady=1);
        self.posttype.grid(row=i,column=1,columnspan=1,pady=1);i=i+1
        self.prea.grid(row=i,column=0,pady=d)
        self.preb.grid(row=i,column=1,pady=d);i=i+1
        self.norma.grid(row=i,column=0,pady=d)
        self.normb.grid(row=i,column=1,pady=d);i=i+1
        l3.grid(row=i,column=0,columnspan=2,pady=2*d);i=i+1
        self.splka.grid(row=i,column=0,pady=d)
        self.splkb.grid(row=i,column=1,pady=d);i=i+1
        self.splea.grid(row=i,column=0,pady=d)
        self.spleb.grid(row=i,column=1,pady=d);i=i+1
        Pmw.alignlabels((self.enot,self.kwt,self.prea,self.norma,self.splka,self.splea),sticky=E)
        Pmw.alignlabels((self.rbkg,self.dk,self.preb,self.normb,self.splkb,self.spleb),sticky=E)

    def clicktochange(self, *arg):
        self.calc=1

    def enterea(self):
        enew=self.splea.get()
        k=Etok(enew)
        entry_replace_d(self.splka,k,4)
        self.splka.checkentry()

    def entereb(self):
        enew=self.spleb.get()
        k=Etok(enew)
        entry_replace_d(self.splkb,k,4)
        self.splkb.checkentry()

    def enterka(self):
        knew=self.splka.get()
        e=ktoE(knew)
        entry_replace_d(self.splea,e,3)
        self.splea.checkentry()
        
    def enterkb(self):
        knew=self.splkb.get()
        e=ktoE(knew)
        entry_replace_d(self.spleb,e,3)
        self.spleb.checkentry()
        
class BSFit:
    def __init__(self):
        bswin=root.bswin=Toplevel(root)
        bswin.title("Background Subtraction Dialog")
        bswin.protocol("WM_DELETE_WINDOW", self.closemod)
        self.root=root
        self.bswin=bswin
        root.iconify()
        #change focus...
        bswin.focus_set()

        #GUI for fitting window...
        #create menu for fitting window
        menubar=Pmw.MenuBar(bswin)
        #file menu
        menubar.addmenu('File','')
        menubar.addmenuitem('File','command',label='Open File',command=self.loaddatafile)
        menubar.addmenuitem('File','command',label='Open Multiple Files',command=self.loadmultdatafile)
        menubar.addmenuitem('File','separator')
        menubar.addmenuitem('File','command',label='Clear All',command=self.clearfilelist)
        menubar.addmenuitem('File','separator')
        menubar.addmenuitem('File','command',label='Edit Default Directories',command=self.callchangedefdirs)
        menubar.addmenuitem('File','separator')
        menubar.addmenuitem('File','command',label='Close',command=self.closemod)
        menubar.addmenuitem('File','command',label='Quit',command=root.quit)
        menubar.addmenu('Save','')
        menubar.addmenuitem('Save','command',label='Edge Data',command=self.savemudata)
        menubar.addmenuitem('Save','command',label='EXAFS Data',command=self.savechidata)
        menubar.addmenuitem('Save','command',label='FT Data',command=self.saveRdata)
        menubar.addmenu('Parameters','')
        menubar.addmenuitem('Parameters','command',label='Mark Current Sample',command=self.menuchoosedata)                                   
        menubar.addmenuitem('Parameters','separator')       
        menubar.addmenuitem('Parameters','command',label='Restore Defaults',command=self.defaultps)
        menubar.addmenuitem('Parameters','command',label='Set All to Current',command=self.setallparam)
        menubar.addmenuitem('Parameters','command',label='Set Marked to Current',command=self.setmarkparam)
        menubar.addmenuitem('Parameters','separator')
        menubar.addmenuitem('Parameters','command',label='Save Parameter file',command=self.savecurparams)
        menubar.addmenuitem('Parameters','command',label='Load Parameter file',command=self.loadsavedparams)
        menubar.addmenuitem('Parameters','separator')
        menubar.addcascademenu('Parameters','Spline Knots',tearoff=1)
        self.splineknots=IntVar()
        menubar.addmenuitem('Spline Knots','radiobutton',label='default',value=0,variable=self.splineknots,command=self.clickedme)
        menubar.addmenuitem('Spline Knots','separator')
        for k in range(5,13):
            menubar.addmenuitem('Spline Knots','radiobutton',label=str(k),value=k,variable=self.splineknots,command=self.clickedme)
        self.splineknots.set(0)
        menubar.addmenuitem('Parameters','separator')        
        menubar.addmenuitem('Parameters','command',label='Run Fitting',command=self.doallanalysis)
        menubar.addmenuitem('Parameters','separator')
        menubar.addmenuitem('Parameters','command',label='Show Parameter Summary',command=self.showresultsum)
        menubar.addmenu('Mu Options','')
        menubar.addmenuitem('Mu Options','command',label='Adjust Energy Scale',command=self.shiftenergy)
        self.optmuderiv=IntVar()
        menubar.addmenuitem('Mu Options','checkbutton',label='Use 1st Derivative',variable=self.optmuderiv)
        self.optmusmooth=IntVar()
        menubar.addmenuitem('Mu Options','checkbutton',label='Apply Smoothing',variable=self.optmusmooth)
        menubar.addmenuitem('Mu Options','command',label='Defined Self Abs. Correction',command=self.selfabscor)
        menubar.addmenu('Deglitching','')
        menubar.addmenuitem('Deglitching','command',label='Edit Data',command=self.deglitchpanel)
        menubar.addmenu('Help','',side=RIGHT)
        menubar.addmenuitem('Help','command',label='About SixPack',command=callprogramabout)
        menubar.addmenuitem('Help','separator')
        menubar.addmenuitem('Help','command',label='IFEFFIT Command Line',command=RunIFEFFITCmdLine)
        menubar.grid(row=0,columnspan=24,sticky=W+E)
        #Add project manager window
        pmwin=Frame(bswin,relief=SUNKEN,bd=2)
        l=Label(pmwin,text='Project Files',relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=4)
        act=Frame(pmwin)
        w=16
        b=Button(act,text="Add File",width=w,command=self.loaddatafile,bg='steel blue',fg='white')
        b.pack(side=LEFT,padx=2,pady=2)
        b=Button(act,text="Add Many Files",width=w,command=self.loadmultdatafile,bg='darkblue',fg='white')
        b.pack(side=LEFT,padx=2,pady=2)
        act.pack(side=TOP,fill=X,padx=2)
        act=Frame(pmwin)
        b=Button(act,text="Remove File",width=w,command=self.removefile,bg='red',fg='white')
        b.pack(side=LEFT,padx=2,pady=2)
        b=Button(act,text="Clear All",width=w,command=self.clearfilelist,bg='brown',fg='white')
        b.pack(side=LEFT,padx=2,pady=2)    
        act.pack(side=TOP,fill=X,padx=2)
        #Add btree
        tree=Tix.ScrolledHList(pmwin,options='hlist.columns 2')
        self.phlist=tree.hlist
        self.phlist.config(separator='-',width=25, drawbranch=0, indent=10,itemtype=Tix.TEXT,browsecmd=self.selectfile,command=self.choosedata)
        self.phlist.column_width(1,chars=50)
        self.phlist.column_width(0,chars=3)
        tree.pack(side=TOP,fill=BOTH,expand=1,padx=2,pady=2)
        self.datfiles=[]
        pmwin.grid(row=1,column=0,columnspan=6,rowspan=12,sticky=W+E+N+S)
        #main parameter entry
        fp=Frame(bswin,relief=SUNKEN,bd=2)
        l=Label(fp,text='File Parameters',relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=4)
        #notebook of params for each file
        self.filparam=Pmw.NoteBook(fp,tabpos=None)
        if sys.platform == 'win32':
            self.filparam.configure(hull_background="SystemButtonFace")
        else:
            self.filparam.configure(hull_background='#d4d0c8')
        self.filparam.recolorborders()
        self.fpwids={}
        self.fplist=[]
        self.initaddfile()
        self.filparam.pack(side=TOP,padx=2,pady=2,fill=BOTH,expand=1)
        self.filparam.setnaturalsize()
        #action buttons
        box=Frame(fp)
        b=Button(box,text='Save mu(E)',width=15,command=self.savemudata,bg='darkgreen',fg='snow')
        b.pack(side=LEFT,fill=X,padx=10,pady=1)
        b=Button(box,text='Save chi(k)',width=15,command=self.savechidata,bg='brown',fg='snow')
        b.pack(side=LEFT,fill=X,padx=10,pady=1)
        b=Button(box,text='Save R',width=15,command=self.saveRdata,bg='royalblue4',fg='snow')
        b.pack(side=LEFT,fill=X,padx=5,pady=1)
        box.pack(side=BOTTOM,fill=X,padx=2,pady=4)
        fp.grid(row=1,column=6,columnspan=12,rowspan=12,sticky=W+E+N+S)        
        #plot parameters
        plp=Frame(bswin,relief=SUNKEN,bd=2)
        l=Label(plp,text='Plot Type',relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=4)
        l=Label(plp,text='Left click, single plot\nRight click, selected plots')
        l.pack(side=TOP,fill=X,padx=2,pady=4)
        box=Frame(plp)
        box2=Frame(plp)
        b=Button(box,text='Raw',width=5,bg='darkblue',fg='snow')
        self.bindplotbutton(b)
        b=Button(box,text='PreEdg',width=5,bg='darkblue',fg='snow')
        self.bindplotbutton(b)
        b=Button(box,text='Spline',width=5,bg='darkblue',fg='snow')
        self.bindplotbutton(b)
        b=Button(box2,text='mu(E)',width=5,bg='darkblue',fg='snow')
        self.bindplotbutton(b)
        b=Button(box2,text='chi(k)',width=5,bg='darkblue',fg='snow')
        self.bindplotbutton(b)
        b=Button(box2,text='R',width=5,bg='darkblue',fg='snow')
        self.bindplotbutton(b)
        box.pack(side=TOP,fill=X,padx=2,pady=4)
        box2.pack(side=TOP,fill=X,padx=2,pady=4)
        l=Label(plp,text='Plot Options',relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=4)
        #k-params
        kp=Frame(plp,relief=RIDGE,bd=2)
        kp.pack(side=TOP,fill=X,padx=2,pady=2)
        w=8
        self.plotkw=Pmw.EntryField(kp,labelpos='w',entry_width=w,label_text='k-weight: ',value='3',validate='real')
        self.plotkmin=Pmw.EntryField(kp,labelpos='w',entry_width=w,label_text='kmin: ',value='2',validate='real')
        self.plotkmax=Pmw.EntryField(kp,labelpos='w',entry_width=w,label_text='kmax: ',value='15',validate='real')
        kfields=(self.plotkw,self.plotkmin,self.plotkmax)
        for fld in kfields:
            fld.pack(side=TOP,padx=5,pady=2)
        Pmw.alignlabels(kfields)
        #R-params
        rp=Frame(plp,relief=RIDGE,bd=2)        
        rp.pack(side=TOP,fill=X,padx=2,pady=2)
        windows=('Hanning','Kaiser-Bessel','Parzen','Welch','Sine')
        self.plotwinparam=Pmw.ComboBox(rp,label_text='FT Window: ',labelpos=N,scrolledlist_items=windows,listheight=100,entryfield_entry_width=15)
        self.plotwinparam.selectitem(windows[1])
        self.plotwinparam.pack(side=TOP,padx=2,pady=3)
        self.plotdk=Pmw.EntryField(rp,labelpos='w',entry_width=w,label_text='dk: ',value='3',validate='real')
        self.plotrmin=Pmw.EntryField(rp,labelpos='w',entry_width=w,label_text='Rmin: ',value='0',validate='real')
        self.plotrmax=Pmw.EntryField(rp,labelpos='w',entry_width=w,label_text='Rmax:     ',value='6',validate='real')
        rfields=(self.plotdk,self.plotrmin,self.plotrmax)
        for fld in rfields:
            fld.pack(side=TOP,padx=5,pady=2)
        Pmw.alignlabels(rfields)
        self.plotftwin=Pmw.RadioSelect(rp,labelpos='w',buttontype='checkbutton')
        self.plotftwin.add('yes',text='Plot FT Win?')
        self.plotftwin.pack(side=TOP,padx=5,pady=1)        
        plp.grid(row=1,column=18,columnspan=6,rowspan=12,sticky=W+E+N+S)
        #Status Bar
        self.status=Label(bswin,text="",bd=2,relief=RAISED,anchor=W,fg='blue')
        self.status.grid(row=13,columnspan=24,sticky=W+E)
        setstatus(self.status,"Ready")
        self.lastsel=''
        #correlation window
        self.rsumwin=Pmw.TextDialog(root,title='Parameter Summary',command=self.killrsumwin,deactivatecommand=self.killrsumwin,scrolledtext_hscrollmode='static',scrolledtext_vscrollmode='static',text_wrap='none',scrolledtext_labelpos=N,label_text='Parameter Summary',buttons=('Remove',))
        self.rsumwin.iconname('Parameter Summary')
        self.rsumwin.tag_config('hi',foreground='red')
        self.rsumwin.withdraw()
        #error window
        self.box=Pmw.MessageDialog(root,title='File Error',defaultbutton=0,message_text='Wrong type of parameter file chosen!',
                 iconpos='n',icon_bitmap='warning')
        self.box.iconname('File Error')
        self.box.withdraw()
        
    def clickedme(self):
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        self.filparam.selectpage(remundsc(cur))
        wid=self.fpwids[cur].p
        wid.calc=1

    def callprogramabout(self):
        programabout(self.root)

    def callchangedefdirs(self): 
        global lastsavedir,lastreaddir
        s=changedefdirs(root.bswin)
        lastreaddir=s.newdir
        lastsavedir=s.newdir
        
    def closemod(self):
        getmainmenu(root.bswin)

    def showresultsum(self):
        self.rsumwin.deiconify()

    def killrsumwin(self,*args):
        self.rsumwin.withdraw()

    def printressum(self):
        #get current data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        wid=self.fpwids[cur].p
        #print results in text window
        self.rsumwin.clear()
        self.rsumwin.insert(END,"Summary of Background Parameters\n")
        self.rsumwin.insert(END,"File: "+cur+"\n\n")
        self.rsumwin.insert(END,'Number of spline knots: '+str(wid.splknot)+' \n')
        self.rsumwin.insert(END,'Step Height: '+wid.stepheight+' \n\n')
        self.rsumwin.insert(END,'E0: '+wid.enot.get()+' \n')
        self.rsumwin.insert(END,'Rbkg: '+wid.rbkg.get()+' \n')
        self.rsumwin.insert(END,'k-weight: '+wid.kwt.get()+' \n')
        self.rsumwin.insert(END,'FT Window: '+wid.winparam.get()+' \n')
        self.rsumwin.insert(END,'dk: '+wid.dk.get()+' \n')
        self.rsumwin.insert(END,'Low Clamp: '+wid.clamp1.get()+' \n')
        self.rsumwin.insert(END,'Hi Clamp: '+wid.clamp2.get()+' \n\n')
        self.rsumwin.insert(END,'Pre-edge: '+wid.pretype.getcurselection()+' \n')        
        self.rsumwin.insert(END,'From: '+wid.prea.get()+' to '+wid.preb.get()+' \n')
        self.rsumwin.insert(END,'Post-Edge: '+wid.posttype.getcurselection()+' \n')
        self.rsumwin.insert(END,'From: '+wid.norma.get()+' to '+wid.normb.get()+' \n')
        self.rsumwin.insert(END,'Spline Regions: \n')
        self.rsumwin.insert(END,'From: '+wid.splka.get()+' to '+wid.splkb.get()+' \n')
        
    def bindplotbutton(self,b):
        b.bind("<Button-1>",self.singleplot)
        b.bind("<Button-3>",self.multiplot)
        b.bind("<ButtonRelease-3>",self.returnclick)
        b.pack(side=LEFT,fill=X,padx=3,pady=1)

    def initaddfile(self):
        self.nfs=0
        fname="firsttest"
        iffc.ifeffit("read_data(file="+filepath+"test.inp, group=firsttest,label='energy xmu')")
        new=self.filparam.add(fname)
        new.p=DefFParams(new,fname)
        self.fpwids.update({fname:new})
        self.fplist.append(fname)
        self.SKIP=1
        self.defaultps()
        self.SKIP=0

    def clearfilelist(self):
        #reset all
        self.datfiles=[]
        for page in self.fplist:
            #destroy the page
            self.filparam.delete(page)
        self.fplist=[]
        self.fpwids={}
        iffc.ifeffit("erase @arrays")
        self.phlist.delete_all()
        self.initaddfile()

    def removefile(self):
        #get current selection
        cur=self.phlist.info_selection()
        if cur != ():
            cur=cur[0]            
            #remove all associated vars
            iffc.ifeffit("erase @group= "+cur)
            ind=self.datfiles.index(cur)
            self.datfiles.remove(cur)
            self.phlist.delete_entry(cur)
            self.filparam.delete(remundsc(cur))
            self.fplist.remove(remundsc(cur))            
            del self.fpwids[cur]
            #reselect
            if len(self.datfiles)==0:
                self.phlist.selection_clear()
                self.filparam.selectpage('firsttest')
            elif ind != 0:
                new=self.datfiles[ind-1]
                self.phlist.selection_set(new)
                self.selectfile()            
            else:
                new=self.datfiles[0]
                self.phlist.selection_set(new)
                self.selectfile()            

    def loadmultdatafile(self):
        global lastreaddir
        self.multifd=Tix.ExFileSelectDialog(root)
        if lastreaddir!='':
            lastreaddir=replace(lastreaddir,'/','\\')            
            self.multifd.fsbox.configure(directory=lastreaddir)
        self.multifd.fsbox.filelist.listbox.configure(selectmode=MULTIPLE)
        #setup ok button...
        self.multifd.fsbox.ok.configure(command=self.getmultilist)        
        self.multifd.popup()

    def getmultilist(self):
        global lastreaddir
        verbot=['(',')','-','#','&','$','@','!','{','}','+','=']
        multfn=self.multifd.fsbox.filelist.listbox.curselection()
        multdlist=self.multifd.fsbox.filelist.listbox.get(0,END)
        curdir=self.multifd.fsbox.dir.entry.get()
        lastreaddir=curdir
        self.multifd.popdown()
        if multfn !=():
            for sel in multfn:
                curfile=multdlist[int(sel)]
                bad=0
                for char in curfile:
                    if char in verbot: bad=1
                if bad:
                    tkMessageBox.showwarning("Open File"," WARNING!\n Filename contains characters not\n compatible with IFEFFIT ")                
                fulpath=curdir+os.sep+curfile
                #set up parmas
                curfil=trimdirext(curfile)
                #load data here
                iffc.ifeffit("read_data(file="+fulpath+", group="+curfil+",label='energy xmu')")
                new=self.filparam.add(remundsc(curfil))
                new.p=DefFParams(new,curfil)
                self.fpwids.update({curfil:new})
                self.fplist.append(remundsc(curfil))
                self.datfiles.append(curfil)
                self.phlist.add(curfil,text=' ',state=NORMAL)
                self.phlist.item_create(curfil,1,text=curfil)
                self.phlist.selection_clear()
                self.phlist.selection_set(curfil)
                #get file data
                self.defaultps()
                #call analysis routine
                self.lastsel=curfil
                #self.doallanalysis()                
                
    def loaddatafile(self):
        global lastreaddir
        infile=ask_for_file([("avg files","*.avg"),("mu files","*.mu"),("all files","*")],lastreaddir)
        root.bswin.focus_set()
        if infile !='':
            sdir=rfind(infile,os.sep)
            lastreaddir=infile[:sdir]
            #append lists/update tree
            treefile=trimdirext(infile)
            #load data here
            iffc.ifeffit("read_data(file="+infile+", group="+treefile+",label='energy xmu')")
            new=self.filparam.add(remundsc(treefile))
            new.p=DefFParams(new,treefile)            
            self.fpwids.update({treefile:new})
            self.fplist.append(remundsc(treefile))
            self.datfiles.append(treefile)
            self.phlist.add(treefile,text=' ',state=NORMAL)
            self.phlist.item_create(treefile,1,text=treefile)
            self.phlist.selection_clear()
            self.phlist.selection_set(treefile)
            #get file data
            self.defaultps()
            #call analysis routine
            self.lastsel=treefile            
            #self.doallanalysis()

    def defaultps(self):
        #emplace default values
        cur=self.phlist.info_selection()
        if self.SKIP:
            iffc.ifeffit("pre_edge(firsttest.energy,firsttest.xmu,find_e0=T)")
            return
        if cur==():
            return
        cur=cur[0]
        self.filparam.selectpage(remundsc(cur))
        #begin placing defaults
        wid=self.fpwids[cur].p
        setstatus(wid.lab,cur)
        #find e0
        iffc.ifeffit("pre_edge("+cur+".energy,"+cur+".xmu,find_e0=T)")
        entry_replace_d(wid.enot,iffc.get_scalar("e0"),3)
        wid.enot.checkentry()
        entry_replace_d(wid.prea,iffc.get_scalar("pre1"),3)
        wid.prea.checkentry()
        entry_replace_d(wid.preb,iffc.get_scalar("pre2"),3)
        wid.preb.checkentry()
        entry_replace_d(wid.norma,150.,3)
        wid.norma.checkentry()
        iffc.ifeffit("maxdelta=ceil("+cur+".energy)-e0")
        entry_replace_d(wid.normb,iffc.get_scalar("maxdelta"),3)
        wid.normb.checkentry()
        entry_replace_d(wid.splka,1.0,3)
        wid.splka.checkentry()
        wid.splka.invoke()
        entry_replace_d(wid.spleb,iffc.get_scalar("maxdelta"),3)
        wid.spleb.checkentry()
        wid.spleb.invoke()        

    def selectfile(self, *arg):
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        self.filparam.selectpage(remundsc(cur))
        if cur!=self.lastsel:
            #update status
            self.lastsel=cur
            wid=self.fpwids[cur].p
            if wid.splknot==0:
                setstatus(self.status,"File "+cur+" selected")
            else:
                setstatus(self.status,"File "+cur+" selected, spline contains "+str(wid.splknot)+" knots, edge step height="+wid.stepheight)
                self.printressum()
            #do analysis
            #self.doallanalysis()

    def menuchoosedata(self):
        cur=self.phlist.info_selection()
        if cur==():
            return
        self.choosedata(cur[0])

    def choosedata(self, *arg):
        cur=arg[0]
        print cur
        self.filparam.selectpage(remundsc(cur))
        wid=self.fpwids[cur].p
        if wid.active==0:
            #turn on
            wid.active=1
            wid.lab.configure(font=("Arial",10,"bold"))
            self.phlist.item_configure(cur,0,text='X')
        else:
            #turn off
            wid.active=0
            wid.lab.configure(font=("Arial",10))
            self.phlist.item_configure(cur,0,text=' ')
            
    def doallanalysis(self):
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        self.filparam.selectpage(remundsc(cur))
        wid=self.fpwids[cur].p
        if wid.calc==0:
            return
        wid.calc=0
        #do background fit
        #get absolute regions
        pre1=str(float(wid.enot.get())+float(wid.prea.get()))
        pre2=str(float(wid.enot.get())+float(wid.preb.get()))
        norm1=str(float(wid.enot.get())+float(wid.norma.get()))
        norm2=str(float(wid.enot.get())+float(wid.normb.get()))
        btype=wid.pretype.getcurselection()
        ctype=wid.posttype.getcurselection()
        xate0=wid.enot.get()
        iffc.put_scalar('xate0',float(xate0))
        if btype=='Linear':
            #do a linear fit to the preedge region
            iffc.ifeffit("guess("+cur+"a=0.0001,"+cur+"b=0.001)")
            iffc.ifeffit(cur+".fitlin="+cur+"a*"+cur+".energy+"+cur+"b")
            iffc.ifeffit(cur+".misfit="+cur+".xmu-"+cur+".fitlin")
            iffc.ifeffit("minimize("+cur+".misfit,x="+cur+".energy,xmin="+pre1+",xmax="+pre2+")")
            iffc.ifeffit("set("+cur+".redxmu="+cur+".xmu-"+cur+".fitlin)")
            iffc.ifeffit("set("+cur+"a="+cur+"a,"+cur+"b="+cur+"b)")
            iffc.ifeffit("set("+cur+"shp="+cur+"a*xate0+"+cur+"b)")
            #and linear/polynomial to the EXAFS
            iffc.ifeffit("guess("+cur+"bb=0.01,"+cur+"cc=0)")
            if ctype=='Linear':
                iffc.ifeffit("set("+cur+"aa=0.0000)")
                iffc.ifeffit(cur+".fitpoly="+cur+"bb*"+cur+".energy+"+cur+"cc")            
            if ctype=='Quad':
                iffc.ifeffit("guess("+cur+"aa=0.0001)")
                iffc.ifeffit(cur+".fitpoly="+cur+"aa*("+cur+".energy)**2+"+cur+"bb*"+cur+".energy+"+cur+"cc")
            iffc.ifeffit(cur+".misfitp="+cur+".redxmu-"+cur+".fitpoly")
            iffc.ifeffit("minimize("+cur+".misfitp,x="+cur+".energy,xmin="+norm1+",xmax="+norm2+")")
            #calculate step normalized
            iffc.ifeffit("set("+cur+"aa="+cur+"aa,"+cur+"bb="+cur+"bb,"+cur+"cc="+cur+"cc)")
            iffc.ifeffit(cur+".samnorm=("+cur+".xmu-"+cur+".fitlin)/"+cur+".fitpoly")            
            iffc.ifeffit(cur+".polyplot="+cur+".fitlin+"+cur+".fitpoly") 
            iffc.ifeffit("set("+cur+"shq="+cur+"aa*(xate0)**2+"+cur+"bb*xate0+"+cur+"cc+"+cur+"shp)")
            #calcualte step jump height
            iffc.ifeffit("set("+cur+"sh="+cur+"shq-"+cur+"shp)")
            wid.stepheight=str(iffc.get_scalar(cur+'sh'))
        if btype=='Gauss':
            #fit a gaussian type profile to the preedge region
            #good for multi-element detectors with signficant scatternig contributions
            iffc.ifeffit("guess("+cur+"yof=0,"+cur+"amp=1,"+cur+"xc=e0-400,"+cur+"w=250)")
            iffc.ifeffit(cur+".fitgaus="+cur+"yof+"+cur+"amp*exp(-(("+cur+".energy-"+cur+"xc)**2)/(2*"+cur+"w**2))")
            iffc.ifeffit(cur+".misfitg="+cur+".xmu-"+cur+".fitgaus")
            iffc.ifeffit("minimize("+cur+".misfitg,x="+cur+".energy,xmin="+pre1+",xmax="+pre2+")")            
            iffc.ifeffit("set("+cur+".redxmu="+cur+".xmu-"+cur+".fitgaus)")
            iffc.ifeffit("set("+cur+"yof="+cur+"yof,"+cur+"amp="+cur+"amp,"+cur+"xc="+cur+"xc,"+cur+"w="+cur+"w)")
            iffc.ifeffit("print "+cur+"yof,"+cur+"amp,"+cur+"xc,"+cur+"w")
            iffc.ifeffit("set("+cur+"shp="+cur+"yof+"+cur+"amp*exp(-((xate0-"+cur+"xc)**2)/(2*"+cur+"w**2)))")
            #and linear/polynomial to the EXAFS
            iffc.ifeffit("guess("+cur+"bb=0.01,"+cur+"cc=0)")
            if ctype=='Linear':
                iffc.ifeffit("set("+cur+"aa=0.0000)")
                iffc.ifeffit(cur+".fitpoly="+cur+"bb*"+cur+".energy+"+cur+"cc")            
            if ctype=='Quad':
                iffc.ifeffit("guess("+cur+"aa=0.0001)")
                iffc.ifeffit(cur+".fitpoly="+cur+"aa*("+cur+".energy)**2+"+cur+"bb*"+cur+".energy+"+cur+"cc")
            iffc.ifeffit(cur+".misfitp="+cur+".redxmu-"+cur+".fitpoly")
            iffc.ifeffit("minimize("+cur+".misfitp,x="+cur+".energy,xmin="+norm1+",xmax="+norm2+")")
            iffc.ifeffit("set("+cur+"aa="+cur+"aa,"+cur+"bb="+cur+"bb,"+cur+"cc="+cur+"cc)")
            #calculate step normalized
            iffc.ifeffit(cur+".samnorm=("+cur+".xmu-"+cur+".fitgaus)/"+cur+".fitpoly")            
            iffc.ifeffit(cur+".polyplot="+cur+".fitgaus+"+cur+".fitpoly") 
            iffc.ifeffit("set("+cur+"shq="+cur+"aa*(xate0)**2+"+cur+"bb*xate0+"+cur+"cc+"+cur+"shp)")
            #calcualte step jump height
            iffc.ifeffit("set("+cur+"sh="+cur+"shq-"+cur+"shp)")
            wid.stepheight=str(iffc.get_scalar(cur+'sh'))
        #do spline fit
        clampdict={'None':'','Slight':'3','Weak':'6','Medium':'12','Strong':'24','Rigid':'96'}
        lowclampcmd=clampdict.get(wid.clamp1.get())
        if lowclampcmd!='':lowclampcmd=',clamp1='+lowclampcmd
        hiclampcmd=clampdict.get(wid.clamp2.get())
        if hiclampcmd!='':hiclampcmd=',clamp2='+hiclampcmd
        nclampcmd=''
        if hiclampcmd!='' or lowclampcmd!='':nclampcmd=',nclamp=5'
        knotcmd=''
        if self.splineknots.get()!=0:knotcmd=',nknots='+str(self.splineknots.get())
        iffc.ifeffit("spline("+cur+".energy,"+cur+".xmu,e0="+wid.enot.get()+",rbkg="+
                     wid.rbkg.get()+",kmin="+wid.splka.get()+",kmax="+wid.splkb.get()+
                     ",pre1="+wid.prea.get()+",pre2="+wid.preb.get()+",norm1="+wid.norma.get()+",norm2="+wid.normb.get()+
                     ",kweight="+wid.kwt.get()+",dk1="+wid.dk.get()+",dk2="+wid.dk.get()+
                     ",kwindow="+wid.winparam.get()+lowclampcmd+hiclampcmd+nclampcmd+knotcmd+")")
        #get spline knots and report in status bar
        wid.splknot=int(iffc.get_scalar("nknots"))
        setstatus(self.status,"File "+cur+" selected, spline contains "+str(wid.splknot)+" knots, edge step height="+wid.stepheight)    
        #put parameter summary text together
        self.printressum()
        #calculate kwt chi
        iffc.ifeffit("dokwt "+cur+" "+self.plotkw.get())        
        #calcualte FT
        iffc.ifeffit("fftf(real="+cur+".chi,kweight="+self.plotkw.get()+",kmin="+\
                     self.plotkmin.get()+",kmax="+self.plotkmax.get()+""",kwindow='"""+\
                     self.plotwinparam.get()+"""',dk="""+self.plotdk.get()+")")
        #enots
        iffc.ifeffit("set("+cur+".enotx=ones(2)*e0)")
        iffc.ifeffit(cur+".enoty=linterp("+cur+".energy,"+cur+".xmu,"+cur+".enotx)")

    def shiftenergy(self):      
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        self.filparam.selectpage(remundsc(cur))
        #dialog to get energy shift
        val=tkSimpleDialog.askfloat('Energy Shift','eV to shift mu',parent=self.bswin)
        if val==None:
            return
        #apply shift
        iffc.ifeffit("set("+cur+".energy="+cur+".energy+"+str(val)+")")

    def spmulti_plot(self,new,gx,gy,xlab,ylab,title,xmin,xmax,key):
        xdat=iffc.get_array(gx)
        ydat=iffc.get_array(gy)
        if new==1: spplotter.SPPlotter(self.root,cmd="new",lt=key,xd=xdat,yd=ydat,xt=xlab,yt=ylab,
                                       title=title,xmin=xmin,xmax=xmax)
        if new==0: spplotter.SPPlotter(self.root,cmd="stack",lt=key,xd=xdat,yd=ydat,xt=xlab,yt=ylab,
                                       title=title,xmin=xmin,xmax=xmax)

    def singleplot(self,event):
        type=event.widget.cget('text')
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        self.doallanalysis()
        self.filparam.selectpage(remundsc(cur))
        wid=self.fpwids[cur].p
        new=1
        if type=='Raw':
            xdat=iffc.get_array(cur+".energy")
            ydat=iffc.get_array(cur+".xmu")
            spplotter.SPPlotter(self.root,cmd='new',lt=cur,xd=xdat,yd=ydat,xt='eV',yt='Raw mu',title=type,SAMEz=wid.enot.get())
        if type=='PreEdg':
            xdat=iffc.get_array(cur+".energy")
            ydat=iffc.get_array(cur+".xmu")
            spplotter.SPPlotter(self.root,cmd='new',lt=cur,xd=xdat,yd=ydat,xt='eV',yt='Raw mu',title=type)
            if wid.pretype.getcurselection()=='Linear':
                ydat=iffc.get_array(cur+".fitlin")
                spplotter.SPPlotter(self.root,cmd='stack',lt="Pre",xd=xdat,yd=ydat,xt='eV',yt='Raw mu',title=type)
            if wid.pretype.getcurselection()=='Gauss':
                ydat=iffc.get_array(cur+".fitgaus")
                spplotter.SPPlotter(self.root,cmd='stack',lt="Pre",xd=xdat,yd=ydat,xt='eV',yt='Raw mu',title=type)
            ydat=iffc.get_array(cur+".polyplot")
            spplotter.SPPlotter(self.root,cmd='stack',lt="Post",xd=xdat,yd=ydat,xt='eV',yt='Raw mu',title=type)
            xdat=iffc.get_array(cur+".enotx")
            ydat=iffc.get_array(cur+".enoty")
            spplotter.SPPlotter(self.root,cmd='stack',lt="enot0",xd=xdat,yd=ydat,color='orange',
                                symbol='circle',pixels=10,hideleg=1,xt='eV',yt='Raw mu',title=type,SAMEz=wid.enot.get())
        if type=='Spline':
            xdat=iffc.get_array(cur+".energy")
            ydat=iffc.get_array(cur+".xmu")
            spplotter.SPPlotter(self.root,cmd='new',lt=cur,xd=xdat,yd=ydat,xt='eV',yt='Raw mu',title=type)
            ydat=iffc.get_array(cur+".bkg")
            spplotter.SPPlotter(self.root,cmd='stack',lt="Spline",xd=xdat,yd=ydat,xt='eV',yt='Raw mu',title=type)
            xdat=iffc.get_array(cur+".enotx")
            ydat=iffc.get_array(cur+".enoty")
            spplotter.SPPlotter(self.root,cmd='stack',lt="enot0",xd=xdat,yd=ydat,color='orange',
                                xt='eV',yt='Raw mu',title=type,symbol='circle',pixels=10,hideleg=1,SAMEz=wid.enot.get())
        if type=='mu(E)':
            xdat=iffc.get_array(cur+".energy")
            ydat=iffc.get_array(cur+".samnorm")
            if self.optmuderiv.get():
                #take derivative of mu
                iffc.ifeffit("del.x=deriv("+cur+".energy)")
                iffc.ifeffit("del.y=deriv("+cur+".samnorm)")
                iffc.ifeffit("del.d=del.y/del.x")
                ydat=iffc.get_array("del.d")
            if self.optmusmooth.get():
                if self.optmuderiv.get():
                    #smooth mu deriv
                    iffc.ifeffit("del.ds=smooth(del.d)")
                    ydat=iffc.get_array("del.ds")
                else:
                    #smooth mu only
                    iffc.ifeffit("del.ds=smooth("+cur+".samnorm)")
                    ydat=iffc.get_array("del.ds")            
            spplotter.SPPlotter(self.root,cmd='new',lt=cur,xd=xdat,yd=ydat,xt='eV',yt='Norm mu',title=type,SAMEz=wid.enot.get())
        if type=='chi(k)':
            #calculate kwt chi
            iffc.ifeffit("dokwt "+cur+" "+self.plotkw.get())   
            xdat=iffc.get_array(cur+".k")
            ydat=iffc.get_array(cur+".chi_kw")
            spplotter.SPPlotter(self.root,cmd='new',lt=cur,xd=xdat,yd=ydat,xt='k',yt='k'+self.plotkw.get()+' chi(k)',title=type,xmin=self.plotkmin.get(),xmax=self.plotkmax.get())
            if 'yes' in self.plotftwin.getvalue():
                iffc.ifeffit("window(k="+cur+".k,group=win,kweight="+self.plotkw.get()+",kmin="+\
                         self.plotkmin.get()+",kmax="+self.plotkmax.get()+""",kwindow='"""+\
                         self.plotwinparam.get()+"""',dk="""+self.plotdk.get()+")")
                iffc.ifeffit("win.mwin=win.win*ceil(abs("+cur+".chi_kw))")
                wdat=iffc.get_array("win.mwin")
                spplotter.SPPlotter(self.root,cmd='stack',lt='FT Win',xd=xdat,yd=wdat,color='red',xt='k',yt='k'+self.plotkw.get()+' chi(k)',title=type,xmin=self.plotkmin.get(),xmax=self.plotkmax.get())            
        if type=='R':
            #calcualte FT
            iffc.ifeffit("fftf(real="+cur+".chi,kweight="+self.plotkw.get()+",kmin="+\
                         self.plotkmin.get()+",kmax="+self.plotkmax.get()+""",kwindow='"""+\
                         self.plotwinparam.get()+"""',dk="""+self.plotdk.get()+")")
            xdat=iffc.get_array(cur+".r")
            ydat=iffc.get_array(cur+".chir_mag")
            spplotter.SPPlotter(self.root,cmd='new',lt=cur,xd=xdat,yd=ydat,xt='R',yt='|chi(R)|',title=type,xmin=self.plotrmin.get(),xmax=self.plotrmax.get())

    def multiplot(self,event):
        event.widget.config(state=ACTIVE)
        event.widget.config(relief=SUNKEN)
        type=event.widget.cget('text')
        if type=='PreEdg' or type=='Spline':
            self.singleplot(event)
        else:
            #get current data
            latest=self.phlist.info_selection()
            if latest==():
                return
            latest=latest[0]
            new=1
            #go through file list
            for cur in self.datfiles:
                #select latest
                self.phlist.selection_clear()
                self.phlist.selection_set(cur)
                self.filparam.selectpage(remundsc(cur))
                wid=self.fpwids[cur].p
                if wid.active==1:
                    self.doallanalysis()
                    iffc.ifeffit("gmin=floor("+cur+".energy)")
                    iffc.ifeffit("gmax=ceil("+cur+".energy)")
                    xmin=str(iffc.get_scalar("gmin"))
                    xmax=str(iffc.get_scalar("gmax"))
                    if type=='Raw':
                        self.spmulti_plot(new,cur+".energy",cur+".xmu","eV","Raw mu",type,xmin,xmax,cur)
                        new=0
                    if type=='mu(E)':
                        opt=0
                        if self.optmuderiv.get():
                            #take derivative of mu
                            iffc.ifeffit("del.x=deriv("+cur+".energy)")
                            iffc.ifeffit("del.y=deriv("+cur+".samnorm)")
                            iffc.ifeffit("del.d=del.y/del.x")
                            iffc.ifeffit("del.ds=del.d")
                            opt=1
                        if self.optmusmooth.get():
                            opt=1
                            if self.optmuderiv.get():
                                #smooth mu deriv
                                iffc.ifeffit("del.ds=smooth(del.d)")
                            else:
                                #smooth mu only
                                iffc.ifeffit("del.ds=smooth("+cur+".samnorm)")
                        if opt:
                            self.spmulti_plot(new,cur+".energy","del.ds","eV","Norm mu",type,xmin,xmax,cur)
                        else:
                            self.spmulti_plot(new,cur+".energy",cur+".samnorm","eV","Norm mu",type,xmin,xmax,cur)
                        new=0
                    if type=='chi(k)':
                        #calculate kwt chi
                        iffc.ifeffit("dokwt "+cur+" "+self.plotkw.get())   
                        self.spmulti_plot(new,cur+".k",cur+".chi_kw","k","k"+self.plotkw.get()+" chi(k)",type,self.plotkmin.get(),self.plotkmax.get(),cur)
                        new=0
                    if type=='R':
                        #calcualte FT
                        iffc.ifeffit("fftf(real="+cur+".chi,kweight="+self.plotkw.get()+",kmin="+\
                                     self.plotkmin.get()+",kmax="+self.plotkmax.get()+""",kwindow='"""+\
                                     self.plotwinparam.get()+"""',dk="""+self.plotdk.get()+")")
                        self.spmulti_plot(new,cur+".r",cur+".chir_mag","R","|chi(R)|",type,self.plotrmin.get(),self.plotrmax.get(),cur)
                        new=0
            #restore old selection
            self.phlist.selection_clear()
            self.phlist.selection_set(latest)
            self.selectfile()

    def returnclick(self,event):
        event.widget.config(state=NORMAL)
        event.widget.config(relief=RAISED)

    def savemudata(self):
        global lastsavedir
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        exten=".mu"
        if self.optmuderiv.get():
            exten="_d.mu"
        nfn=ask_save_file(cur+exten,lastsavedir)
        root.bswin.focus_set()
        if nfn<>"":
            sdir=rfind(nfn,os.sep)
            lastsavedir=nfn[:sdir]
            self.doallanalysis()    
            if rfind(nfn,'.')==-1:
                nfn=nfn+".mu"
            opt=0
            if self.optmuderiv.get():
                #take derivative of mu
                iffc.ifeffit("del.x=deriv("+cur+".energy)")
                iffc.ifeffit("del.y=deriv("+cur+".samnorm)")
                iffc.ifeffit("del.d=del.y/del.x")
                iffc.ifeffit("del.ds=del.d")
                opt=1
            if self.optmusmooth.get():
                opt=1
                if self.optmuderiv.get():
                    #smooth mu deriv
                    iffc.ifeffit("del.ds=smooth(del.d)")
                else:
                    #smooth mu only
                    iffc.ifeffit("del.ds=smooth("+cur+".samnorm)")
            if opt:
                iffc.ifeffit("write_data(file="+nfn+","+cur+".energy,del.ds)")
                setstatus(self.status,"mu(E) derivative data saved to "+nfn)
            else:
                iffc.ifeffit("write_data(file="+nfn+","+cur+".energy,"+cur+".samnorm)")
                setstatus(self.status,"mu(E) data saved to "+nfn)

    def savechidata(self):
        global lastsavedir
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        nfn=ask_save_file(cur+".chi",lastsavedir)
        root.bswin.focus_set()
        if nfn!="":
            sdir=rfind(nfn,os.sep)
            lastsavedir=nfn[:sdir]            
            self.doallanalysis()            
            if rfind(nfn,'.')==-1:
                nfn=nfn+".chi"
            iffc.ifeffit("write_data(file="+nfn+","+cur+".k,"+cur+".chi)")
            setstatus(self.status,"chi(k) data saved to "+nfn)

    def saveRdata(self):
        global lastsavedir
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        nfn=ask_save_file(cur+".rsp",lastsavedir)
        root.bswin.focus_set()
        if nfn<>"":
            sdir=rfind(nfn,os.sep)
            lastsavedir=nfn[:sdir]
            self.doallanalysis()
            if rfind(nfn,'.')==-1:
                nfn=nfn+".rsp"
            iffc.ifeffit("write_data(file="+nfn+","+cur+".r,"+cur+".chir_mag,"+cur+".chir_re,"+cur+".chir_im,"+cur+".chir_phase)")
            setstatus(self.status,"=FT data saved to "+nfn)

    def setallparam(self):
        #get data
        latest=self.phlist.info_selection()
        if latest==():
            return
        latest=latest[0]
        self.filparam.selectpage(remundsc(latest))
        newwid=self.fpwids[latest].p
        for cur in self.datfiles:
            #select latest
            self.phlist.selection_clear()
            self.phlist.selection_set(cur)
            self.filparam.selectpage(remundsc(cur))
            wid=self.fpwids[cur].p
            #create database
            relate=[]
            for i in range(0,len(wid.copyable)):
                relate.append((newwid.copyable[i],wid.copyable[i]))
            for delta,gamma in relate:
                gamma.setentry(delta.get())
            wid.clamp1.selectitem(newwid.clamp1.get())
            wid.clamp2.selectitem(newwid.clamp2.get())
            wid.pretype.setvalue(newwid.pretype.getcurselection())
            wid.posttype.setvalue(newwid.posttype.getcurselection())
        #restore old selection
        self.phlist.selection_clear()
        self.phlist.selection_set(latest)                
        self.filparam.selectpage(remundsc(latest))

    def setmarkparam(self):
        #get data
        latest=self.phlist.info_selection()
        if latest==():
            return
        latest=latest[0]
        self.filparam.selectpage(remundsc(latest))
        newwid=self.fpwids[latest].p        
        for cur in self.datfiles:
            #select latest
            self.phlist.selection_clear()
            self.phlist.selection_set(cur)
            self.filparam.selectpage(remundsc(cur))
            wid=self.fpwids[cur].p
            if wid.active==1:
                #create database
                relate=[]
                for i in range(0,len(wid.copyable)):
                    relate.append((newwid.copyable[i],wid.copyable[i]))
                for delta,gamma in relate:
                    gamma.setentry(delta.get())
                wid.clamp1.selectitem(newwid.clamp1.get())
                wid.clamp2.selectitem(newwid.clamp2.get())
                wid.pretype.setvalue(newwid.pretype.getcurselection())
                wid.posttype.setvalue(newwid.posttype.getcurselection())                    
        #restore old selection
        self.phlist.selection_clear()
        self.phlist.selection_set(latest)
        self.filparam.selectpage(remundsc(latest))

    def savecurparams(self):
        global lastsavedir
        #place all paths and varibles into a parameter file
        #get file name
        nfn=ask_save_file('',lastsavedir)
        root.bswin.focus_set()
        if nfn=="":
            setstatus(self.status,"Save parameters aborted")
            return
        sdir=rfind(nfn,os.sep)
        lastsavedir=nfn[:sdir]            
        #open file
        #check for extension ending
        ext=rfind(nfn,".")
        if ext==-1:
            nfn=nfn+".prm"
        fid=open(nfn,"w")
        #get current widget
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        wid=self.fpwids[cur].p        
        #save data-file parameters
        fid.write("BSPARAMS\n")
        fid.write(wid.enot.get()+'\n')
        fid.write(wid.rbkg.get()+'\n')
        fid.write(wid.kwt.get()+'\n')
        fid.write(wid.winparam.get()+'\n')
        fid.write(wid.dk.get()+'\n')
        fid.write(wid.clamp1.get()+'\n')
        fid.write(wid.clamp2.get()+'\n')
        fid.write(wid.pretype.getcurselection()+'\n')        
        fid.write(wid.prea.get()+'\n')
        fid.write(wid.preb.get()+'\n')
        fid.write(wid.posttype.getcurselection()+'\n')
        fid.write(wid.norma.get()+'\n')
        fid.write(wid.normb.get()+'\n')
        fid.write(wid.splka.get()+'\n')
        fid.write(wid.splkb.get()+'\n')
        fid.write("END")
        fid.close()            
        setstatus(self.status,"Background parameters saved to "+nfn)     

    def loadsavedparams(self):
        global lastreaddir
        #load paths and variables from files
        #get file name
        fn=ask_for_file([("parameter files","*.prm"),("all files","*")],lastreaddir,check=0)
        root.bswin.focus_set()
        if fn=="":
            setstatus(self.status,"Load parameters aborted")
            return
        sdir=rfind(fn,os.sep)
        lastreaddir=fn[:sdir]
        #open file
        fid=open(fn,"r")
        param=fid.read()
        fid.close()
        #get current widget
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        wid=self.fpwids[cur].p           
        #parse file...
        lp=split(param,'\n')
        ind=0
        for new in lp:
            if new=='EDGEPARAMS' or new=='FPARAMS':
                #wrong parameter file
                self.box.deiconify()
                return
            if new=='BSPARAMS':
                #read data-file parameters
                #read BSub params
                wid.enot.setentry(lp[ind+1])
                wid.rbkg.setentry(lp[ind+2])
                wid.kwt.setentry(lp[ind+3])
                wid.winparam.setentry(lp[ind+4])
                wid.dk.setentry(lp[ind+5])
                wid.clamp1.setentry(lp[ind+6])
                wid.clamp2.setentry(lp[ind+7])
                wid.pretype.invoke(lp[ind+8])        
                wid.prea.setentry(lp[ind+9])
                wid.preb.setentry(lp[ind+10])
                wid.posttype.invoke(lp[ind+11])
                wid.norma.setentry(lp[ind+12])
                wid.normb.setentry(lp[ind+13])
                wid.splka.setentry(lp[ind+14])
                wid.splkb.setentry(lp[ind+15])
                wid.calc=1
                setstatus(self.status,"Parameter file read from "+fn)
            ind=ind+1
            
    def deglitchpanel(self):
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        cur=cur[0]
        wid=self.fpwids[cur].p
        #make list of forwarding parameters
        #kwt,e0,Rbkg,splkwt,kmin,kmax,clamp1,clamp2,dk,Ftwin
        fwdps=[]
        fwdps.append(self.plotkw.get())
        fwdps.append(wid.enot.get())
        fwdps.append(wid.rbkg.get())
        fwdps.append(wid.kwt.get())
        fwdps.append(wid.splka.get())
        fwdps.append(wid.splkb.get())
        fwdps.append(wid.clamp1.get())
        fwdps.append(wid.clamp2.get())
        fwdps.append(wid.dk.get())        
        fwdps.append(wid.winparam.get())
        print 'Entering deglitching panel for '+cur
        DeglitchPanel(cur,fwdps,self.root)

    def selfabscor(self):
        #get data
        cur=self.phlist.info_selection()
        if cur==():
            return
        self.cur=cur[0]
        #element list
        self.esym=[  "H" , "He", "Li", "Be", "B" , "C" , "N" , "O" , "F" , "Ne", "Na",
                "Mg", "Al", "Si", "P" , "S" , "Cl", "Ar", "K" , "Ca", "Sc", "Ti",
                "V" , "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As",
                "Se", "Br", "Kr", "Rb", "Sr", "Y" , "Zr", "Nb", "Mo", "Tc", "Ru",
                "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I" , "Xe", "Cs",
                "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy",
                "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W" , "Re", "Os", "Ir",
                "Pt", "Au", "Hd", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra",
                "Ac", "Th", "Pa", "U" ]
        #start new window
        sacwin=self.root.sacwin=Toplevel(self.root)
        self.sacwin=sacwin
        self.sacwin.title("Self Absorption Correction Panel")
        self.sacwin.protocol("WM_DELETE_WINDOW", self.closeselfabspanel)
        self.sacwin.focus_set()
        #help menu
        menubar=Pmw.MenuBar(sacwin)
        menubar.addmenu('File','',side=LEFT)
        menubar.addmenuitem('File','command',label='Open new CHI',command=self.getnewSACfile)
        menubar.addmenu('Help','',side=RIGHT)
        menubar.addmenuitem('Help','command',label='Parameters',command=self.getabshelp)
        menubar.pack(side=TOP,fill=X)
        #add current file
        self.saccurfile=Label(sacwin,text=self.cur,relief=GROOVE,bd=2,width=25,justify=CENTER,font="Arial 10")
        self.saccurfile.pack(side=TOP,pady=2,fill=X)
        #add entryfields
        entfr=Frame(sacwin)
        entfr.pack(side=TOP)
        w=15
        self.sacform=Pmw.EntryField(entfr,labelpos='w',label_text='Formula: ',value='',entry_width=w)
        self.sacthick=Pmw.EntryField(entfr,labelpos='w',label_text='Thick (microns): ',value='0',validate='real',entry_width=w)
        self.sacvol=Pmw.EntryField(entfr,labelpos='w',label_text='Unit Vol. (A**3): ',value='0',validate='real',entry_width=w)
        self.sacphi=Pmw.EntryField(entfr,labelpos='w',label_text='Phi Angle (deg): ',value='45',validate='real',entry_width=w)
        self.sacfields=(self.sacform,self.sacthick,self.sacvol,self.sacphi)
        for fld in self.sacfields:
            fld.pack(side=TOP,fill=X,padx=10,pady=2)
        Pmw.alignlabels(self.sacfields)
        #add edge pulldowns
        self.edgepos=['K','LI','LII','LIII']
        pdfr=Frame(sacwin)
        pdfr.pack(side=TOP)
        self.sacelement=Pmw.ComboBox(pdfr,labelpos='nw',label_text='Absorber',entry_width=5,scrolledlist_items=self.esym,history=0,fliparrow=1)
        self.sacedge=Pmw.ComboBox(pdfr,labelpos='nw',label_text='Edge',entry_width=7,listheight=100,scrolledlist_items=self.edgepos,history=0,fliparrow=1)
        self.sacelement.pack(side=LEFT,padx=5,pady=2)
        self.sacedge.pack(side=RIGHT,padx=5,pady=2)
        #return button controls
        b=Pmw.ButtonBox(sacwin,orient='vertical')
        b.pack(side=TOP,padx=2,pady=5,fill=X)
        w=30
        b.add('Do SA Correction',command=self.doSAcorrection,width=w,bg='darkgreen',fg='snow')
        b.add('Plot Chis',command=self.doSAchiplot,width=w,bg='darkblue',fg='snow')
        b.add('Plot R-space',command=self.doSArspaceplot,width=w,bg='darkblue',fg='snow')
        b.add('Save Correction',command=self.saveSAcorr,width=w,bg='darkorange',fg='snow')
        b.add('Return',command=self.closeselfabspanel,width=w,bg='red',fg='snow')
        #add status bar
        self.sacstatus=Label(sacwin,text="",bd=2,relief=RAISED,anchor=W,fg='blue')
        self.sacstatus.pack(side=TOP,padx=0,pady=0,fill=X)
        setstatus(self.sacstatus,"Ready")
        self.doneSAcor=0

    def doSAcorrection(self):
        setstatus(self.sacstatus,"Starting correction...")
        #get parameters
        d=float(self.sacthick.getvalue())
        phi=float(self.sacphi.getvalue())
        vol=float(self.sacvol.getvalue())
        form=self.sacform.getvalue()
        elem=self.sacelement.get(None)
        ed=self.sacedge.get(None)
        #make sure thickness is converted to angstroms
        d=d*10000
        #error check parameters
        if d<=0:
            setstatus(self.sacstatus,"ABORT: Bad Thickness")
            return
        if phi<0 or phi>90:
            setstatus(self.sacstatus,"ABORT: Bad Phi")
            return
        if vol<=0:
            setstatus(self.sacstatus,"ABORT: Bad Volume")
            return
        if form=='':
            setstatus(self.sacstatus,"ABORT: Bad Formula")
            return
        if elem not in self.esym:
            setstatus(self.sacstatus,"ABORT: Bad Absorber")
            return
        if ed not in self.edgepos:
            setstatus(self.sacstatus,"ABORT: Bad Edge")
            return
        #form edge
        edge=elem+' '+ed
        #get array from IFEFFIT
        k=iffc.get_array(self.cur+".k")
        chi=iffc.get_array(self.cur+".chi")
        #do correction
        self.sacnewchi=cbselfabs.fluor_corr(k,chi,d,phi,vol,form,edge,-1,'p','x')
        iffc.put_array(self.cur+".SACchi",self.sacnewchi)
        iffc.ifeffit("set SAC.chi="+self.cur+".SACchi")
        iffc.ifeffit("set SAC.k="+self.cur+".k")
        self.doneSAcor=1
        setstatus(self.sacstatus,"Correction completed")

    def saveSAcorr(self):
        global lastsavedir
        if self.doneSAcor==0:
            setstatus(self.sacstatus,"Do correction first!")            
            return                
        #get data
        nfn=ask_save_file(self.cur+"_SAC.chi",lastsavedir)
        root.sacwin.focus_set()
        if nfn!="":
            sdir=rfind(nfn,os.sep)
            lastsavedir=nfn[:sdir]            
            if rfind(nfn,'.')==-1:
                nfn=nfn+".chi"
            iffc.ifeffit("write_data(file="+nfn+",SAC.k,SAC.chi)")
            setstatus(self.sacstatus,"SAC chi(k) data saved")

    def getnewSACfile(self):
        #get new file for SA corrections
        global lastreaddir
        if self.doneSAcor==0:
            setstatus(self.sacstatus,"Do correction first!")            
            return                
        #get new name
        infile=ask_for_file([("chi files","*.chi"),("all files","*")],lastreaddir)
        root.sacwin.focus_set()
        if infile =='':
            setstatus(self.sacstatus,"Need Filename!")            
            return                
        sdir=rfind(infile,os.sep)
        lastreaddir=infile[:sdir]
        #update cur variable
        self.cur=trimdirext(infile)
        #load data here
        iffc.ifeffit("read_data(file="+infile+", group="+self.cur+",label='k chi')")
        #clear SAC group in IFEFFIT
        iffc.ifeffit("erase @group=SAC")
        self.doneSAcor=0
        #update NAME and status
        setstatus(self.sacstatus,"New file loaded")
        setstatus(self.saccurfile,self.cur)
        
    def doSAchiplot(self):
        if self.doneSAcor==0:
            setstatus(self.sacstatus,"Do correction first!")            
            return        
        #plot corrected and uncorrected chis with whatever k-weighting is in the BackSub screen
        #make k-weighted array for new and old chis
        iffc.ifeffit("dokwt "+self.cur+" "+self.plotkw.get())           
        iffc.ifeffit("dokwt SAC "+self.plotkw.get())                   
        #get data from IFEFFIT
        #old=iffc.get_array(self.cur+".chi_kw")
        #new=iffc.get_array("SAC.chi_kw")
        #kd=iffc.get_array("SAC.k")
        #pass data to plotter
        new=1
        type="chi(k)"
        self.spmulti_plot(new,self.cur+".k",self.cur+".chi_kw","k","k"+self.plotkw.get()+" chi(k)",type,self.plotkmin.get(),self.plotkmax.get(),"Old")
        new=0
        self.spmulti_plot(new,"SAC.k","SAC.chi_kw","k","k"+self.plotkw.get()+" chi(k)",type,self.plotkmin.get(),self.plotkmax.get(),"Corrected")
        setstatus(self.sacstatus,"Chis plotted")        

    def doSArspaceplot(self):
        if self.doneSAcor==0:
            setstatus(self.sacstatus,"Do correction first!")            
            return        
        #plot corrected and uncorrected RDFs with whatever k-weighting is in the BackSub screen
        #make k-weighted array for new and old chis

        #take FTs
        iffc.ifeffit("fftf(real="+self.cur+".chi,kweight="+self.plotkw.get()+",kmin="+\
                     self.plotkmin.get()+",kmax="+self.plotkmax.get()+""",kwindow='"""+\
                     self.plotwinparam.get()+"""',dk="""+self.plotdk.get()+")")
        iffc.ifeffit("fftf(real=SAC.chi,kweight="+self.plotkw.get()+",kmin="+\
                     self.plotkmin.get()+",kmax="+self.plotkmax.get()+""",kwindow='"""+\
                     self.plotwinparam.get()+"""',dk="""+self.plotdk.get()+")")
        #pass data to plotter
        type='R'
        new=1
        self.spmulti_plot(new,self.cur+".r",self.cur+".chir_mag","R","|chi(R)|",type,self.plotrmin.get(),self.plotrmax.get(),"Old")
        new=0
        self.spmulti_plot(new,"SAC.r","SAC.chir_mag","R","|chi(R)|",type,self.plotrmin.get(),self.plotrmax.get(),"Corrected")
        setstatus(self.sacstatus,"RDFs plotted")
        
#in changing files...  #setstatus(self.saccurfile,cur)
        
    def closeselfabspanel(self):
        #clear ifeffit memory temp vars
        #iffc.ifeffit("erase @group=glitchtemp")
        #iffc.ifeffit("erase @group=temp")
        #kill panel
        self.sacwin.destroy()

    def getabshelp(self):
        #display a text box with instructions
        text="""This option performs fluorescence self-absorption
corrections of EXAFS on samples of KNOWN compositions.
The algorithm is based on the method of Booth and
Bridges, http://xxx.lanl.gov/cond-mat/0306252.  This
article is also soon to be in print in Physica Scripta
in the proceedings of the XAFS XII conference.
The following parameters are required in order to
perform the calculation.
FORMULA:    Chemical formula of compound, i.e. 'MnO2'
            or 'YBa2Fe0.31Cu2.69O7'.  This should be
            the formula PER UNIT CELL.  That is Cu
            metal is 'Cu4' not 'Cu'.
THICKNESS:  Thickness of sample, in microns.
VOLUME:     Volume of the unit cell in cubic angstroms.
PHI:        Angle of the incident beam w.r.t. the
            surface of the sample, in degrees.
ABSORBER:   The element which is the absorbing edge in
            the experiment.
EDGE:       The X-ray edge the measurement is performed
            at."""
        tkMessageBox.showinfo('SA Correction Help',text)
        
class DeglitchPanel:
    def __init__(self,active,fwdps,root):
        self.root=root
        self.fwdps=fwdps
        self.active=active
        #start new deglitching procedure
        dg=self.root.dg=Toplevel(self.root)
        self.dg=dg
        dg.title("Deglitching Panel for "+active)
        dg.protocol("WM_DELETE_WINDOW", self.closeglitch)
        dg.focus_set()
        #help menu
        menubar=Pmw.MenuBar(dg)
        menubar.addmenu('Help','',side=RIGHT)
        menubar.addmenuitem('Help','command',label='Deglitching',command=self.gethelp)
        menubar.pack(side=TOP,fill=X)
        #setup buttons and Tix graph panels
        mainfr=Frame(dg)
        mainfr.pack(side=TOP)
        bfr=Frame(mainfr)
        bfr.pack(side=LEFT,fill='both')
        gfr=Frame(mainfr,relief=SUNKEN,bd=2)
        gfr.pack(side=RIGHT,fill='both')
        #add button controls
        #edit buttons
        f1=Frame(bfr,relief=SUNKEN,bd=2)
        f1.pack(side=TOP,padx=1,pady=1,fill=X)
        l=Label(f1,text='Editing Control',relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=2)
        self.mubut=Button(f1,text="Edit Mu",width=20,command=self.editmu,bg='darkblue',fg='snow')
        self.chibut=Button(f1,text="Edit Chi",width=20,command=self.editchi,bg='brown',fg='snow')
        self.mubut.pack(side=TOP,padx=2,pady=5)
        self.chibut.pack(side=TOP,padx=2,pady=5)
        #spline controls
        f2=Frame(bfr,relief=SUNKEN,bd=2)
        f2.pack(side=TOP,padx=1,pady=1,fill=X)
        l=Label(f2,text='Spline Control',relief=RAISED,bd=2)
        l.pack(side=TOP,fill=X,padx=2,pady=2)
        w=10
        self.plkwt=Pmw.EntryField(f2,labelpos='w',label_text='Plot k-wt: ',value='0',validate='real',entry_width=w)
        self.enot=Pmw.EntryField(f2,labelpos='w',label_text='e0: ',value='0',validate='real',entry_width=w)
        self.rbkg=Pmw.EntryField(f2,labelpos='w',label_text='Rbkg: ',value='0',validate='real',entry_width=w)
        self.kwt=Pmw.EntryField(f2,labelpos='w',label_text='k-wt: ',value='0',validate='real',entry_width=w)
        self.kmin=Pmw.EntryField(f2,labelpos='w',label_text='kmin: ',value='0',validate='real',entry_width=w)
        self.kmax=Pmw.EntryField(f2,labelpos='w',label_text='kmax: ',value='0',validate='real',entry_width=w)
        self.splfields=(self.plkwt,self.enot,self.rbkg,self.kwt,self.kmin,self.kmax)
        for fld in self.splfields:
            fld.pack(side=TOP,fill=X,padx=10,pady=2)
        Pmw.alignlabels(self.splfields)
        #return controls
        b=Pmw.ButtonBox(bfr,orient='vertical')
        b.pack(side=TOP,padx=2,pady=5,fill=X)
        b.add('Accept',command=self.acceptchanges,width=20,bg='darkgreen',fg='snow')
        b.add('Revert',command=self.getfwddata,width=20,bg='darkorange',fg='snow')
        b.add('Cancel',command=self.closeglitch,width=20,bg='red',fg='snow')
        #graph cursor positions
        fpb=Frame(bfr)
        fpb.pack(side=BOTTOM,padx=2,pady=1,fill=X)
        fpaa=Frame(bfr)
        fpaa.pack(side=BOTTOM,padx=2,pady=1,fill=X)
        fpa=Frame(bfr)
        fpa.pack(side=BOTTOM,padx=2,pady=1,fill=X)
        self.xlabmu=Label(fpa,text="X=      ",width=11,bd=2,relief=RIDGE,anchor=W,fg='red')
        self.ylabmu=Label(fpa,text="Y=      ",width=11,bd=2,relief=RIDGE,anchor=W,fg='red')
        self.xklabmu=Label(fpaa,text="Xk=      ",width=11,bd=2,relief=RIDGE,anchor=W,fg='red')
        self.yklabmu=Label(fpaa,text="Y=      ",width=11,bd=2,relief=RIDGE,anchor=W,fg='red')
        self.xlabchi=Label(fpb,text="X=      ",width=11,bd=2,relief=RIDGE,anchor=W,fg='blue')
        self.ylabchi=Label(fpb,text="Y=      ",width=11,bd=2,relief=RIDGE,anchor=W,fg='blue')
        self.xlabmu.pack(side=LEFT,fill=X)
        self.ylabmu.pack(side=LEFT,fill=X)
        self.xklabmu.pack(side=LEFT,fill=X)
        self.yklabmu.pack(side=LEFT,fill=X)
        self.xlabchi.pack(side=LEFT,fill=X)
        self.ylabchi.pack(side=LEFT,fill=X)
        #Add graph windows
        self.graphmu=Pmw.Blt.Graph(gfr,plotbackground='white',height=200)
        self.graphmu.bind(sequence="<ButtonPress>",   func=self.mouseDown)
        self.graphmu.bind(sequence="<ButtonRelease>", func=self.mouseUp  )
        self.graphmu.bind(sequence="<Motion>", func=self.coordreport)
        self.graphmu.legend_configure(hide=1)
        self.graphmu.pack(side=TOP,expand=1,fill='both')
        self.graphchi=Pmw.Blt.Graph(gfr,plotbackground='white',height=200)
        self.graphchi.bind(sequence="<ButtonPress>",   func=self.mouseDown)
        self.graphchi.bind(sequence="<ButtonRelease>", func=self.mouseUp  )
        self.graphchi.bind(sequence="<Motion>", func=self.coordreport)
        self.graphchi.legend_configure(hide=1)
        self.graphchi.pack(side=TOP,expand=1,fill='both')
        #set up plot dictionaries
        self.xgrlabref={}
        self.xgrlabref.update({self.graphmu:(self.xlabmu,self.xklabmu)})
        self.xgrlabref.update({self.graphchi:(self.xlabchi,)})
        self.ygrlabref={}
        self.ygrlabref.update({self.graphmu:(self.ylabmu,self.yklabmu)})
        self.ygrlabref.update({self.graphchi:(self.ylabchi,)})
        #zoom stack
        self.zoomstackref={}
        self.zoomstackref.update({self.graphmu:[]})
        self.zoomstackref.update({self.graphchi:[]})
        #initialize data
        self.muxd=[]
        self.muyd=[]
        self.chixd=[]
        self.chiyd=[]
        self.yarrays={}
        self.updaterefs()
        #get data and set parameters
        self.getfwddata()
        
    def coordreport(self,event):
        (x,y)=event.widget.invtransform(event.x,event.y)
        xref=self.xgrlabref.get(event.widget)
        yref=self.ygrlabref.get(event.widget)
        xlab=xref[0]
        ylab=yref[0]
        xtext="X="+str(x)
        ytext="Y="+str(y)
        xtext=xtext[:12]
        ytext=ytext[:12]
        setstatus(xlab,xtext)
        setstatus(ylab,ytext)
        if len(xref)==2:
            xlab=xref[1]
            ylab=yref[1]
            dele=x-float(self.enot.get())
            if dele>=0:
                s=Etok(dele)
            else:
                s='N/A'
            xtext="Xk="+str(s)
            ytext="Y="+str(y)
            xtext=xtext[:12]
            ytext=ytext[:12]
            setstatus(xlab,xtext)
            setstatus(ylab,ytext)
            
    def updaterefs(self):
        self.yarrays.update({self.graphmu:self.muyd})
        self.yarrays.update({self.graphchi:self.chiyd})

    def zoom(self, x0, y0, x1, y1, gtype):
        #add last to zoomstack
        stack=self.zoomstackref[gtype]
        a0=gtype.xaxis_cget("min")
        a1=gtype.xaxis_cget("max")
        b0=gtype.yaxis_cget("min")
        b1=gtype.yaxis_cget("max")        
        stack.append((a0,a1,b0,b1))
        self.zoomstackref.update({gtype:stack})
        #configure
        gtype.xaxis_configure(min=x0, max=x1)
        gtype.yaxis_configure(min=y0, max=y1)

    def mouseDrag(self,event):
        global x0, y0, x1, y1, gtype
        (x1, y1) = gtype.invtransform(event.x, event.y)             
        gtype.marker_configure("marking rectangle", 
            coords = (x0, y0, x1, y0, x1, y1, x0, y1, x0, y0))
        self.coordreport(event)
    
    def mouseUp(self,event):
        global dragging,gtype
        global x0, y0, x1, y1        
        if dragging:
            gtype.unbind(sequence="<Motion>")
            gtype.bind(sequence="<Motion>", func=self.coordreport)
            gtype.marker_delete("marking rectangle")           
            if event.num==1:
                if x0 <> x1 and y0 <> y1:   
                    # make sure the coordinates are sorted
                    if x0 > x1: x0, x1 = x1, x0
                    if y0 > y1: y0, y1 = y1, y0         
                    self.zoom(x0, y0, x1, y1, gtype) # zoom in
            else:
                self.rescaleplot(gtype) # zoom out
                           
    def mouseDown(self,event):
        global dragging, x0, y0, gtype
        dragging = 0
        gtype=event.widget
        if gtype.inside(event.x, event.y):
            dragging = 1
            (x0, y0) = gtype.invtransform(event.x, event.y)
            gtype.marker_create("line", name="marking rectangle", dashes=(2, 2))
            gtype.bind(sequence="<Motion>",  func=self.mouseDrag)        

    def rescaleplot(self,gtype):
        #get last off stack
        stack=self.zoomstackref[gtype]
        if stack==[]:
            return
        limit=stack.pop()
        gtype.xaxis_configure(min=limit[0],max=limit[1])
        gtype.yaxis_configure(min=limit[2],max=limit[3])
        self.zoomstackref.update({gtype:stack})

    def closeglitch(self):
        #clear ifeffit memory temp vars
        iffc.ifeffit("erase @group=glitchtemp")
        iffc.ifeffit("erase @group=temp")
        #kill panel
        self.dg.destroy()

    def acceptchanges(self):
        #tranfer data back to real arrays
        iffc.ifeffit("set "+self.active+".xmu=glitchtemp.xmu")
        #do spline on active
        clampdict={'None':'','Slight':'3','Weak':'6','Medium':'12','Strong':'24','Rigid':'96'}
        lowclampcmd=clampdict.get(self.fwdps[6])
        if lowclampcmd!='':lowclampcmd=',clamp1='+lowclampcmd
        hiclampcmd=clampdict.get(self.fwdps[7])
        if hiclampcmd!='':hiclampcmd=',clamp2='+hiclampcmd
        nclampcmd=''
        if hiclampcmd!='' or lowclampcmd!='':nclampcmd=',nclamp=5'
        iffc.ifeffit("spline("+self.active+".energy,"+self.active+".xmu,e0="+self.enot.get()+",rbkg="+
                     self.rbkg.get()+",kmin="+self.kmin.get()+",kmax="+self.kmax.get()+
                     ",kweight="+self.kwt.get()+",dk1="+self.fwdps[8]+",dk2="+self.fwdps[8]+
                     ",kwindow="+self.fwdps[9]+lowclampcmd+hiclampcmd+nclampcmd+")")
        #see ya
        self.closeglitch()

    def getfwddata(self):
        #retrieve list of forwarding parameters
        #kwt,e0,Rbkg,kwt,kmin,kmax....clamp1,clamp2,dk,Ftwin
        i=0
        for ent in self.splfields:
            ent.setentry(self.fwdps[i])
            i=i+1
        #move data to temp deglitching data in ifeffit
        iffc.ifeffit("set glitchtemp.energy="+self.active+".energy")
        iffc.ifeffit("set glitchtemp.xmu="+self.active+".xmu")
        #do splining
        self.dospline()
        #clear plot
        self.clearplots([1,1])
        #plot data
        self.plotmu('line')
        self.plotchi('line')

    def dospline(self):
        #do spline in ifeffit
        clampdict={'None':'','Slight':'3','Weak':'6','Medium':'12','Strong':'24','Rigid':'96'}
        lowclampcmd=clampdict.get(self.fwdps[6])
        if lowclampcmd!='':lowclampcmd=',clamp1='+lowclampcmd
        hiclampcmd=clampdict.get(self.fwdps[7])
        if hiclampcmd!='':hiclampcmd=',clamp2='+hiclampcmd
        nclampcmd=''
        if hiclampcmd!='' or lowclampcmd!='':nclampcmd=',nclamp=5'
        iffc.ifeffit("spline(glitchtemp.energy,glitchtemp.xmu,e0="+self.enot.get()+",rbkg="+
                     self.rbkg.get()+",kmin="+self.kmin.get()+",kmax="+self.kmax.get()+
                     ",kweight="+self.kwt.get()+",dk1="+self.fwdps[8]+",dk2="+self.fwdps[8]+
                     ",kwindow="+self.fwdps[9]+lowclampcmd+hiclampcmd+nclampcmd+")")

    def clearplots(self,select):
        if select[0]==1:
            glist=self.graphmu.element_names()
            if glist != ():
                for g in glist:
                    self.graphmu.element_delete(g)
        if select[1]==1:
            glist=self.graphchi.element_names()
            if glist != ():
                for g in glist:
                    self.graphchi.element_delete(g)

    def plotmu(self,type):
        #get data from ifeffit
        self.muxd=iffc.get_array("glitchtemp.energy")
        self.muyd=iffc.get_array("glitchtemp.xmu")
        self.updaterefs()
        #plot characteristics
        sym=''
        lt='mu'
        px=0
        if type=='point':
            sym='circle'
            lt='data'
            px=2
        self.graphmu.line_create(lt,xdata=tuple(self.muxd),ydata=tuple(self.muyd),symbol=sym,pixels=px)

    def plotchi(self,type):
        #get data from ifeffit
        self.chixd=iffc.get_array("glitchtemp.k")
        iffc.ifeffit("dokwt glitchtemp "+self.plkwt.get())           
        self.chiyd=iffc.get_array("glitchtemp.chi_kw")
        self.updaterefs()
        #plot characteristics
        sym=''
        lt='chi'
        px=0
        if type=='point':
            sym='circle'
            lt='data'
            px=2
        self.graphchi.line_create(lt,xdata=tuple(self.chixd),ydata=tuple(self.chiyd),symbol=sym,pixels=px)

    def GEmouseDrag(self,event):
        global idx, gtype
        u=self.yarrays[gtype]
        u[idx] = gtype.yaxis_invtransform(event.y)
        self.yarrays.update({gtype:u})
        gtype.element_configure("data", ydata=tuple(u))
    
    def GEmouseUp(self,event):
        global gtype
        gtype.element_unbind("data", "<Motion>")
                           
    def GEmouseDown(self,event):
        global idx, gtype
        gtype=event.widget
        gtype.element_bind("data", "<Motion>", self.GEmouseDrag)
        el = gtype.element_closest(event.x, event.y)
        idx  = el["index"]
        
    def editmu(self):
        #turn off chi button and switch mu function
        self.chibut.configure(state=DISABLED)
        self.mubut.configure(command=self.doneeditmu,text='Done Editing')
        #clear mu
        self.clearplots([1,0])
        #replot points
        self.plotmu('point')
        #set up graphing-mouse properties
        self.graphmu.unbind(sequence="<ButtonPress>")
        self.graphmu.unbind(sequence="<ButtonRelease>")
        self.graphmu.element_bind("data",sequence="<ButtonPress>",   func=self.GEmouseDown)
        self.graphmu.element_bind("data",sequence="<ButtonRelease>", func=self.GEmouseUp  )
                        
    def doneeditmu(self):
        #restore buttons
        self.chibut.configure(state=NORMAL)
        self.mubut.configure(command=self.editmu,text='Edit Mu')
        #restore graph-mouse props
        self.graphmu.element_unbind("data",sequence="<ButtonPress>")
        self.graphmu.element_unbind("data",sequence="<ButtonRelease>")
        self.graphmu.bind(sequence="<ButtonPress>",   func=self.mouseDown)
        self.graphmu.bind(sequence="<ButtonRelease>", func=self.mouseUp  )
        #update and move mu data to ifeffit
        self.muyd=self.yarrays[self.graphmu]
        iffc.ifeffit("erase glitchtemp.xmu")
        iffc.put_array("glitchtemp.xmu",self.muyd)
        #spline new data
        self.dospline()
        #clear plots
        self.clearplots([1,1])
        #replot
        self.plotmu('line')
        self.plotchi('line')
 
    def editchi(self):
        #turn off mu button and switch chi function
        self.mubut.configure(state=DISABLED)
        self.chibut.configure(command=self.doneeditchi,text='Done Editing')
        #clear chi
        self.clearplots([0,1])
        #replot points
        self.plotchi('point')
        #set up graphing-mouse properties
        self.graphchi.unbind(sequence="<ButtonPress>")
        self.graphchi.unbind(sequence="<ButtonRelease>")
        self.graphchi.element_bind("data",sequence="<ButtonPress>",   func=self.GEmouseDown)
        self.graphchi.element_bind("data",sequence="<ButtonRelease>", func=self.GEmouseUp  )

    def doneeditchi(self):    
        #restore buttons
        self.mubut.configure(state=NORMAL)
        self.chibut.configure(command=self.editchi,text='Edit Chi')
        #restore graph-mouse props
        self.graphchi.element_unbind("data",sequence="<ButtonPress>")
        self.graphchi.element_unbind("data",sequence="<ButtonRelease>")
        self.graphchi.bind(sequence="<ButtonPress>",   func=self.mouseDown)
        self.graphchi.bind(sequence="<ButtonRelease>", func=self.mouseUp  )
        #update chi array
        self.chiyd=self.yarrays[self.graphchi]
        #unweight chi data and create energy scale from k
        inwt=float(self.plkwt.get())
        kwts=[]
        enot=float(self.enot.get())
        escale=[]
        ydunwt=[]
        ind=0
        for k in self.chixd:
            kwts=k**inwt
            escale.append(ktoE(k)+enot)
            if k!=0:
                ydunwt.append(self.chiyd[ind]/kwts)
            else:
                ydunwt.append(0)
            ind=ind+1
        #put chi data to ifeffit
        iffc.ifeffit("erase glitchtemp.chi_new")
        iffc.put_array("glitchtemp.chi_new",ydunwt)
        #now ifeffit chi_new has kw 0 altered data
        #need to shift energy scales for chi to energy
        #find nearest mu data point just after e0
        pivot=()
        ind=0
        for e in self.muxd:
            if pivot==() and e>enot:
                pivot=(e,ind)
            ind=ind+1
        #interpolate edited data over range from e0 to end on same grid as mu
        newescale=self.muxd[pivot[1]:len(self.muxd)]
        iffc.ifeffit("erase temp.x,temp.oldx,temp.y")
        iffc.put_array("temp.x",newescale)
        iffc.put_array("temp.oldx",escale)
        iffc.ifeffit("temp.y=splint(temp.oldx,glitchtemp.chi_new,temp.x)")
        #now we have new edited data on same grid as mu from e0 to end stored in temp.y
        back=iffc.get_array("glitchtemp.bkg")
        newd=iffc.get_array("temp.y")
        #before adding... use edge_step
        edwt=iffc.get_scalar("edge_step")
        ind=pivot[1]
        for d in newd:
            self.muyd[ind]=back[ind]+d*edwt
            ind=ind+1
        #put new mu to ifeffit
        iffc.ifeffit("erase glitchtemp.xmu")
        iffc.put_array("glitchtemp.xmu",self.muyd)    
        #spline new data
        self.dospline()
        #clear plots
        self.clearplots([1,1])
        #replot
        self.plotmu('line')
        self.plotchi('line')
        
    def gethelp(self):
        #display a text box with instructions
        text="""Deglitching can be performed by editing mu or chi.
It is recomended to edit mu if possible -- otherwise some
of the edge structure will be compromised.  This will not
affect the EXAFS however.  Once the desired level of zoom
is achieved, press the edit button and move the desired
data points.  Zooming cannot be performed once the editing
has begun.  Once editing is finished, the data will be
resplined and displayed.  To go back to the original data,
click the revert button.  Changes can be ignored by clicking
cancel or loaded back to the background subtraction module
by clicking accept.  It is best to only deglitch one file
at a time."""
        tkMessageBox.showinfo('Deglitching Help',text)
        
############################################################
##
##
## Run SamView
##
##
############################################################

class RunSV:
    def __init__(self):
        svwin=root.svwin=Toplevel(root)
        svwin.title("SamView")
        svwin.protocol("WM_DELETE_WINDOW", self.closemod)
        root.iconify()
        #change focus...
        svwin.focus_set()
        spsamview.Main(svwin,root)

    def closemod(self):
        getmainmenu(root.svwin)


############################################################
##
##
## Run Least Squares Routine
##
##
############################################################

class RunLSF:
    def __init__(self):
        efwin=root.efwin=Toplevel(root)
        efwin.title("Least Squares Fitting")
        efwin.protocol("WM_DELETE_WINDOW", self.closemod)
        root.iconify()
        #change focus...
        efwin.focus_set()
        lsqfitter.EdgeFit(efwin,root)

    def closemod(self):
        getmainmenu(root.efwin)

############################################################
##
##
## Run SixPack PCA
##
##
############################################################

class RunPCA:
    def __init__(self):
        pcawin=root.pcawin=Toplevel(root)
        pcawin.title("SixPack PCA")
        pcawin.protocol("WM_DELETE_WINDOW", self.closemod)
        root.iconify()
        #change focus...
        pcawin.focus_set()
        spkpca.PCAMain(pcawin,root)

    def closemod(self):
        getmainmenu(root.pcawin)


###########################################################
##
##        
##  IFEFFIT Command Line Window
##
##
###########################################################

class RunIFEFFITCmdLine:
    def __init__(self):
        ifcl=root.ifcl=Toplevel(root)
        ifcl.title("IFEFFIT Command Line")
        ifcl.protocol("WM_DELETE_WINDOW", self.closemod)
        self.ifcl=ifcl
        self.root=root
        root.iconify()
        #change focus...
        ifcl.focus_set()
        #main widgets
        self.iftext=Pmw.ScrolledText(ifcl,hull_width=600,hull_height=300,text_wrap='none',usehullsize=1,vscrollmode='static',hscrollmode='static',text_state=DISABLED,text_bg='grey85')
        self.iftext.pack(side=TOP,expand=1,fill='both')
        self.iftext.tag_configure('input',foreground='black')
        self.iftext.tag_configure('output',foreground='blue')
        self.input=Pmw.EntryField(ifcl,labelpos='w',label_text='IFEFFIT>',label_fg='blue',command=self.sendinput)
        self.input.pack(side=TOP,expand=1,fill='both')
        iffc.ifeffit("set &screen_echo=0")

    def sendinput(self):
        #add input to text
        self.iftext.configure(text_state=NORMAL)
        self.iftext.insert(END,self.input.get()+'\n','input')
        #send command
        iffc.ifeffit(self.input.get())
        #get and print return
        result=iffc.get_echo_buffer()
        if result!=[]:
            for r in result:
                self.iftext.insert(END,str(r)+'\n','output')
                self.iftext.see(END)        
        self.iftext.configure(text_state=DISABLED)
        #clear input
        self.input.clear()

    def closemod(self):
        #reset screen echo
        iffc.ifeffit("set &screen_echo=1")
        self.ifcl.destroy()


###########################################################
##
##        
##  About SIXPACK Screen
##
##
###########################################################

class callprogramabout:
    def __init__(self):
        programabout(root)
        
###########################################################
##
##        
##  SamXAS Main Menu Screen
##
##
###########################################################
class SamXAS:
    #main window
    #Logo image
    logo=PhotoImage(file=filepath+"splogo.gif")
    px=logo.width()
    py=logo.height()
    samlogo=Canvas(root,borderwidth=2, relief=GROOVE, height=py, width=px)
    samlogo.create_image(5,5,anchor=NW, image=logo)
    iversion="""SIXPack (Sam's Interface for XAS analysis Package)\nPowered by IFEFFIT """+iffc.get_string('$&build')
    #check for update
    try:
        http=httplib.HTTP('www-ssrl.slac.stanford.edu')
        http.putrequest('GET','/~swebb/version.htm')
        http.putheader('Accept', 'text/html')
        http.putheader('Accept', 'text/plain')
        http.endheaders()
        errcode, errmsg, headers = http.getreply()
        htcontent=http.getfile().read()

        #ping counter
##        host = "fastcounter.bcentral.com"
##        url='/fastcounter?3170508+6341023'
##        try:
##            http2=httplib.HTTP("fastcounter.bcentral.com")
##            http2.putrequest('GET','/fastcounter?3170508+6341023')
##            http2.putheader('Accept', 'text/html')
##            http2.putheader('Accept', 'text/plain')
##            http2.endheaders()
##            errcode, errmsg, headers = http2.getreply()
##            htcontent2=http2.getfile().read()
##        except:
##            print "no counter"
##            pass
        #ping map counter
        try:
            http2=httplib.HTTP("clustrmaps.com")
            http2.putrequest('GET','/counter/index2.php?url=http://www-ssrl.slac.stanford.edu/~swebb/version.htm')
            http2.putheader('Accept', 'text/html')
            http2.putheader('Accept', 'text/plain')
            http2.endheaders()
            errcode, errmsg, headers = http2.getreply()
            htcontent2=http2.getfile().read()
        except:
            print "no map"
            pass

        #parse content for version number
        parse=htcontent.split('\n')
        line=parse[12]
        #strip...
        stripline=''
        for a in range(len(line)):
            if line[a] not in ['<','>','p','/']:
                stripline=stripline+line[a]
        if float(stripline)<=float(version):
            spversion='You have the latest version of SixPack'
        else:
            spversion='Version '+stripline+' of SixPack now available!'
    except:
        spversion='Cannot check current version'
    #Program Buttons
    defbutwdth=20
    butfont=("Arial 16 bold")
    butfont=("Comic Sans MS", 16, "bold")    
    lab=Label(root, text="Menu Options", font="Arial 20 bold", width=defbutwdth)
    but1=Button(root, text="SamView", font=butfont,command=RunSV, width=defbutwdth)
    but2=Button(root, text="Background Removal", font=butfont,command=BSFit, width=defbutwdth)
    but5=Button(root, text="FEFF EXAFS Fitting", font=butfont,command=AdvFit, width=defbutwdth)
    but3=Button(root, text="Least Sq. Fitting", font=butfont,command=RunLSF, width=defbutwdth)
    but4=Button(root, text="PC Analysis", font=butfont,command=RunPCA, width=defbutwdth)
    but6=Button(root, text="Make FEFF SS Paths", font=butfont,command=PT, width=defbutwdth)
    but7=Button(root, text="About SixPACK/SamXAS", font=butfont,command=callprogramabout, width=defbutwdth)
    butf=Button(root, text="Quit", font=butfont,command=root.quit, width=defbutwdth)
    #grid these in main window
    i=0
    lab.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    but1.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    but2.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    but3.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    but4.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    but5.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    but6.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    but7.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    butf.grid(row=i,column=1,sticky=W+E+N+S);i=i+1
    versstatus=Label(root,text=iversion,bd=2,relief=RAISED,anchor=W,fg='blue',justify=LEFT)
    versstatus.grid(row=i,columnspan=2,sticky=W+E);i=i+1
    versstatus2=Label(root,text=spversion,bd=2,relief=RAISED,anchor=W,fg='red')
    versstatus2.grid(row=i,columnspan=2,sticky=W+E)
    samlogo.grid(row=0,column=0,rowspan=i-1, sticky=W+E+N+S, padx=5, pady=5)

      
#start main event handler
root.mainloop()
