Changeset 2082 for trunk/autoint.py


Ignore:
Timestamp:
Dec 4, 2015 10:50:58 PM (6 years ago)
Author:
toby
Message:

provide autoint interpolation table; merge into std GSAS-II version

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoint.py

    r2065 r2082  
    11import os
    2 import wx
     2import sys
    33import copy
    44import glob
    55import re
     6import bisect
     7import numpy as np
     8import wx
     9import wx.lib.mixins.listctrl  as  listmix
    610import GSASIIpath
    711import GSASIIIO as G2IO
     
    913import GSASIIgrid as G2gd
    1014import GSASIIimgGUI as G2imG
    11 '''
    12 Define a class to be used for Andrey's AutoIntegration process
    13 '''
    14 
     15import GSASIIpy3 as G2py3
     16
     17print 'loading autoint'
     18
     19def ReadMask(filename):
     20    'Read a mask (.immask) file'
     21    File = open(filename,'r')
     22    save = {}
     23    S = File.readline()
     24    while S:
     25        if S[0] == '#':
     26            S = File.readline()
     27            continue
     28        [key,val] = S[:-1].split(':')
     29        if key in ['Points','Rings','Arcs','Polygons','Frames','Thresholds']:
     30            save[key] = eval(val)
     31        S = File.readline()
     32    File.close()
     33    G2imG.CleanupMasks(save)
     34    return save
     35
     36def ReadControls(filename):
     37    'read an image controls (.imctrl) file'
     38    cntlList = ['wavelength','distance','tilt','invert_x','invert_y','type',
     39            'fullIntegrate','outChannels','outAzimuths','LRazimuth','IOtth','azmthOff','DetDepth',
     40            'calibskip','pixLimit','cutoff','calibdmin','chisq','Flat Bkg',
     41            'PolaVal','SampleAbs','dark image','background image']
     42    File = open(filename,'r')
     43    save = {}
     44    S = File.readline()
     45    while S:
     46        if S[0] == '#':
     47            S = File.readline()
     48            continue
     49        [key,val] = S[:-1].split(':')
     50        if key in ['type','calibrant','binType','SampleShape',]:    #strings
     51            save[key] = val
     52        elif key in ['rotation']:
     53            save[key] = float(val)
     54        elif key in ['center',]:
     55            if ',' in val:
     56                save[key] = eval(val)
     57            else:
     58                vals = val.strip('[] ').split()
     59                save[key] = [float(vals[0]),float(vals[1])]
     60        elif key in cntlList:
     61            save[key] = eval(val)
     62        S = File.readline()
     63    File.close()
     64    return save
     65
     66def Read_imctrl(imctrl_file):
     67    '''Read an image control file and record control parms into a dict, with some simple
     68    type conversions
     69    '''
     70    file_opt = options = {}
     71    save = {'filename':imctrl_file}
     72    immask_file = os.path.splitext(imctrl_file)[0]+'.immask'
     73    if os.path.exists(immask_file):
     74        save['maskfile'] = immask_file
     75    else:
     76        save['maskfile'] = '(none)'
     77    cntlList = ['wavelength','distance','tilt','invert_x','invert_y','type',
     78                        'fullIntegrate','outChannels','outAzimuths','LRazimuth','IOtth','azmthOff','DetDepth',
     79                        'calibskip','pixLimit','cutoff','calibdmin','chisq','Flat Bkg',
     80                        'PolaVal','SampleAbs','dark image','background image']
     81    File = open(imctrl_file,'r')
     82    fullIntegrate = False
     83    try:
     84        S = File.readline()
     85        while S:
     86            if S[0] == '#':
     87                S = File.readline()
     88                continue
     89            [key,val] = S[:-1].split(':')
     90            if key in ['type','calibrant','binType','SampleShape',]:    #strings
     91                save[key] = val
     92            elif key == 'rotation':
     93                save[key] = float(val)
     94            elif key == 'fullIntegrate':
     95                fullIntegrate = eval(val)
     96            elif key == 'LRazimuth':
     97                save['LRazimuth_min'],save['LRazimuth_max'] = eval(val)[0:2]
     98            elif key == 'IOtth':
     99                save['IOtth_min'],save['IOtth_max'] = eval(val)[0:2]
     100            elif key == 'center':
     101                if ',' in val:
     102                    vals = eval(val)
     103                else:
     104                    vals = val.strip('[] ').split()
     105                    vals = [float(vals[0]),float(vals[1])]
     106                save['center_x'],save['center_y'] = vals[0:2]
     107            elif key in cntlList:
     108                save[key] = eval(val)
     109            S = File.readline()
     110    finally:
     111        File.close()
     112        if fullIntegrate: save['LRazimuth_min'],save['LRazimuth_max'] = 0,0
     113    return save
     114   
    15115class AutoIntFrame(wx.Frame):
    16116    '''Creates a wx.Frame window for the Image AutoIntegration.
     
    48148            if newImage in imageFileList: continue # already read
    49149            for imgId in G2IO.ReadImages(G2frame,newImage):
    50                 # update controls from master
    51150                controlsDict = G2frame.PatternTree.GetItemPyData(
    52151                    G2gd.GetPatternTreeItemId(G2frame,imgId, 'Image Controls'))
    53                 controlsDict.update(self.ImageControls)
    54                 # update masks from master
    55152                ImageMasks = G2frame.PatternTree.GetItemPyData(
    56153                    G2gd.GetPatternTreeItemId(G2frame,imgId, 'Masks'))
     154                if self.params['Mode'] == 'table':
     155                    dist = controlsDict['distance']
     156                    interpDict,imgctrl,immask = self.Evaluator(dist) # interpolated calibration values
     157                    self.ImageControls = ReadControls(imgctrl)
     158                    self.ImageControls.update(interpDict)
     159                    self.ImageControls['showLines'] = True
     160                    self.ImageControls['ring'] = []
     161                    self.ImageControls['rings'] = []
     162                    self.ImageControls['ellipses'] = []
     163                    self.ImageControls['setDefault'] = False
     164                    for i in 'range','size','GonioAngles':
     165                        if i in self.ImageControls:
     166                            del self.ImageControls[i]
     167                    # load copy of Image Masks
     168                    if immask:
     169                        self.ImageMasks = ReadMask(immask)
     170                        del self.Thresholds['Thresholds']
     171                    else:
     172                        self.ImageMasks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Frames':[]}
     173                # update controls from master
     174                controlsDict.update(self.ImageControls)
     175                # update masks from master w/o Thresholds
    57176                ImageMasks.update(self.ImageMasks)
    58177        # now integrate the images that have not already been processed before
     
    117236        # show current IMG base
    118237        self.ControlBaseLbl.SetLabel(G2frame.PatternTree.GetItemText(G2frame.Image))
    119         if self.params['Mode'] == 'file':
    120             'get file info'
    121             GSASIIpath.IPyBreak()
    122         else:
     238        if self.params['Mode'] != 'table':
    123239            # load copy of Image Controls from current image and clean up
    124240            # items that should not be copied
     
    179295            is started. When Pause is pressed, the loop is stopped.
    180296            '''
    181             #print self.params # for debug
    182 
    183             # check inputs before starting
    184             err = ''
     297            # check inputs for errors before starting
     298            #err = ''
    185299            #if not any([self.params[fmt] for fmt in self.fmtlist]):
    186300            #    err += '\nPlease select at least one output format\n'
    187             if (self.params['Mode'] == 'file' and not
    188                     os.path.exists(self.params['IMGfile'])):
    189                 err += '\nThe image controls file could not be found\n'
    190             if (self.params['Mode'] == 'file' and
    191                 not self.params['IgnoreMask']
    192                 ) and not os.path.exists(self.params['MaskFile']):
    193                 err += '\nThe mask file could not be found\n'
    194             if err:
    195                 G2G.G2MessageBox(self,err)
    196                 return
     301            #if err:
     302            #    G2G.G2MessageBox(self,err)
     303            #    return
    197304            # change button label
    198305            if btnstart.GetLabel() != 'Pause':
     
    244351                    dlg.Destroy()
    245352                return
    246             if btn1 == event.GetEventObject():
    247                 ext = '.imctrl'
    248                 title = 'Image control'
    249             else:
    250                 ext = '.immask'
    251                 title = 'Image masks'               
    252             dlg = wx.FileDialog(
    253                 self, 'Select name for '+title+' file to read',
    254                 '.', '',
    255                 title+'file (*'+ext+')|*'+ext,
    256                 wx.OPEN|wx.CHANGE_DIR)
    257             dlg.CenterOnParent()
    258             try:
    259                 if dlg.ShowModal() == wx.ID_OK:
    260                     filename = dlg.GetPath()
    261                     # make sure extension is correct
    262                     #filename = os.path.splitext(filename)[0]+ext
    263                     if btn1 == event.GetEventObject():
    264                         fInp1.SetValue(filename)
    265                     else:
    266                         fInp2.SetValue(filename)
    267                 else:
    268                     filename = None
    269             finally:
    270                 dlg.Destroy()
    271353               
    272354        def OnRadioSelect(event):
    273             '''Respond to a radiobutton selection and enable or
    274             disable widgets accordingly. Also gets called when the
    275             "Don't Use" flag for Mask use is called.
     355            '''Respond to a radiobutton selection and when in table
     356            mode, get parameters from user.
    276357            '''
    277             lbl1.Disable()
    278             fInp1.Disable()
    279             btn1.Disable()
    280             lbl2.Disable()
    281             fInp2.Disable()
    282             ign2.Disable()
    283             btn2.Disable()
     358            self.Evaluator = None
    284359            if r2.GetValue():
    285                 self.params['Mode'] = 'file'
    286                 fInp1.Enable()
    287                 btn1.Enable()
    288                 lbl1.Enable()
    289                 ign2.Enable()
    290                 if not self.params['IgnoreMask']:
    291                     fInp2.Enable()
    292                     btn2.Enable()
    293                     lbl2.Enable()
     360                self.params['Mode'] = 'table'
     361                try:
     362                    dlg = IntegParmTable(self.G2frame) # create the dialog
     363                    if dlg.ShowModal() == wx.ID_OK:
     364                        self.Evaluator = DefineEvaluator(dlg)
     365                    else:
     366                        r1.SetValue(True)
     367                finally:
     368                    dlg.Destroy()
    294369            else:
    295370                self.params['Mode'] = 'active'
     
    298373        ##################################################
    299374        self.G2frame = G2frame
     375        self.Evaluator = None
    300376        self.params = {}
    301377        self.Reset = False
     
    337413        lblsizr.Add(r1)
    338414        r1.SetValue(True)
    339         r2 = wx.RadioButton(mnpnl, wx.ID_ANY, "Use from file(s)")
     415        r2 = wx.RadioButton(mnpnl, wx.ID_ANY, "Use from table")
    340416        lblsizr.Add(r2)
    341417        r2.Bind(wx.EVT_RADIOBUTTON, OnRadioSelect)
    342         r2.Disable()         # deactivate this until implemented
    343         # Image controls file
    344         sizer = wx.BoxSizer(wx.HORIZONTAL)
    345         sizer.Add((20,-1))
    346         lbl1 = wx.StaticText(mnpnl, wx.ID_ANY,'IMG control file: ')
    347         sizer.Add(lbl1)
    348         fInp1 = G2G.ValidatedTxtCtrl(mnpnl,self.params,'IMGfile',
    349                                        notBlank=False,size=(300,-1))
    350         sizer.Add(fInp1)
    351         btn1 = wx.Button(mnpnl,  wx.ID_ANY, "Browse")
    352         btn1.Bind(wx.EVT_BUTTON, OnBrowse)
    353         sizer.Add(btn1)
    354         lblsizr.Add(sizer)
    355         # Masks input file
    356         sizer = wx.BoxSizer(wx.HORIZONTAL)
    357         sizer.Add((20,-1))
    358         lbl2 = wx.StaticText(mnpnl, wx.ID_ANY,'Mask file: ')
    359         sizer.Add(lbl2)
    360         fInp2 = G2G.ValidatedTxtCtrl(mnpnl,self.params,'MaskFile',
    361                                        notBlank=False,size=(300,-1))
    362         sizer.Add(fInp2)
    363         ign2 = G2G.G2CheckBox(mnpnl,"Don't use",self.params,'IgnoreMask',
    364                               OnChange=OnRadioSelect)
    365         sizer.Add(ign2)
    366         btn2 = wx.Button(mnpnl,  wx.ID_ANY, "Browse")
    367         btn2.Bind(wx.EVT_BUTTON, OnBrowse)
    368         sizer.Add(btn2)
    369         lblsizr.Add(sizer)
    370418        mnsizer.Add(lblsizr)
    371419
     
    420468        mnsizer.Fit(self)
    421469        self.CenterOnParent()
    422         self.Show() 
     470        self.Show()
     471
     472def DefineEvaluator(dlg):
     473    '''Creates a function that provides interpolated values for a given distance value
     474    '''
     475    def Evaluator(dist):
     476        '''Interpolate image parameters for a supplied distance value
     477
     478        :param float dist: distance to use for interpolation
     479        :returns: a list with 3 items:
     480
     481          * a dict with parameter values,
     482          * the closest imctrl and
     483          * the closest maskfile (or None)
     484        '''           
     485        x = np.array([float(i) for i in parms[0]])
     486        closest = abs(x-dist).argmin()
     487        closeX = x[closest]
     488        D = {'distance':dist}
     489        imctfile = IMfileList[closest]
     490        if parms[-1][closest].lower() != '(none)':
     491            maskfile = parms[-1][closest]
     492        else:
     493            maskfile = None
     494        for c in range(1,cols-1):
     495            lbl = ParmList[c]
     496            if lbl in nonInterpVars:
     497                D[lbl] = float(parms[c][closest])
     498            else:
     499                y = np.array([float(i) for i in parms[c]])
     500                D[lbl] = np.interp(dist,x,y)
     501        # full integration when angular range is 0
     502        D['fullIntegrate'] = (D['LRazimuth_min'] == D['LRazimuth_max'])
     503        # conversion for paired values
     504        for a,b in ('center_x','center_y'),('LRazimuth_min','LRazimuth_max'),('IOtth_min','IOtth_max'):
     505            r = a.split('_')[0]
     506            D[r] = [D[a],D[b]]
     507            del D[a]
     508            del D[b]
     509        return D,imctfile,maskfile
     510    # save local copies of values needed in Evaluator
     511    parms = dlg.ReadImageParmTable()
     512    IMfileList = dlg.IMfileList
     513    cols = dlg.list.GetColumnCount()
     514    ParmList = dlg.ParmList
     515    nonInterpVars = dlg.nonInterpVars
     516    return Evaluator
     517
     518class IntegParmTable(wx.Dialog):
     519    '''Creates a dialog window with a table of integration parameters.
     520    :meth:`ShowModal` will return wx.ID_OK if the process has been successful.
     521    In this case, :func:`DefineEvaluator` should be called to obtain a function that
     522    creates a dictionary with interpolated parameter values.
     523    '''
     524    ParmList = ('distance','center_x','center_y','wavelength','tilt','rotation','DetDepth',
     525            'LRazimuth_min','LRazimuth_max','IOtth_min','IOtth_max','outChannels',
     526            'maskfile',
     527            )
     528    nonInterpVars = ('tilt','rotation','LRazimuth_min','LRazimuth_max','IOtth_min','IOtth_max',
     529                     'outChannels')  # values in this list are taken from nearest rather than interpolated
     530    HeaderList = ('Det Dist','X cntr','Y cntr','wavelength','tilt','rotation','DetDepth',
     531            'Azimuth min','Azimuth max','2Th min','2Th max','Int. pts',
     532            'Mask File',
     533            )
     534    def __init__(self,G2frame):
     535        self.G2frame = G2frame
     536        self.parms = [] # list of values by column
     537        self.IMfileList = [] # list of .imctrl file names for each entry in table
     538        wx.Dialog.__init__(self,G2frame,style=wx.RESIZE_BORDER|wx.DEFAULT_DIALOG_STYLE)
     539        files = []
     540        try:
     541            dlg = wx.FileDialog(self, 'Select image control files or previous table',
     542                                style=wx.OPEN| wx.MULTIPLE,
     543                                wildcard='image control files (.imctrl)|*.imctrl|Integration table (*.imtbl)|*.imtbl')
     544            if dlg.ShowModal() == wx.ID_OK:
     545                files = dlg.GetPaths()
     546                self.parms,self.IMfileList = self.ReadFiles(files)
     547        finally:
     548            dlg.Destroy()
     549        if not files:
     550            wx.CallAfter(self.EndModal,wx.ID_CANCEL)
     551            return
     552        mainSizer = wx.BoxSizer(wx.VERTICAL)
     553        self.list = ImgIntLstCtrl(self, wx.ID_ANY,
     554                      style=wx.LC_REPORT
     555                          | wx.BORDER_SUNKEN
     556                         #| wx.BORDER_NONE
     557                         )
     558        mainSizer.Add(self.list,1,wx.EXPAND,1)
     559        btnsizer = wx.BoxSizer(wx.HORIZONTAL)
     560        btn = wx.Button(self, wx.ID_OK)
     561        btnsizer.Add(btn)
     562        btn = wx.Button(self, wx.ID_ANY,'Save')
     563        btn.Bind(wx.EVT_BUTTON,self._onSave)
     564        btnsizer.Add(btn)
     565        btn = wx.Button(self, wx.ID_CLOSE,'Quit')
     566        btn.Bind(wx.EVT_BUTTON,self._onClose)
     567        btnsizer.Add(btn)
     568        mainSizer.Add(btnsizer, 0, wx.ALIGN_CENTER|wx.ALL, 5)   
     569        self.SetSizer(mainSizer)
     570        self.list.FillList(self.parms)
     571        mainSizer.Layout()
     572        mainSizer.Fit(self)
     573       
     574    def ReadFiles(self,files):
     575        '''Reads a list of .imctrl files or a single .imtbl file
     576        '''
     577        tmpDict = {}
     578        if not files: return
     579        # option 1, a dump from a previous save
     580        if os.path.splitext(files[0])[1] == '.imtbl':
     581            fp = open(files[0],'r')
     582            S = fp.readline()
     583            while S:
     584                if S[0] != '#':
     585                    [key,val] = S[:-1].split(':')
     586                    tmpDict[key] = eval(val)
     587                S = fp.readline()
     588            fp.close()
     589            # delete entries
     590            m1 = [i for i,f in enumerate(tmpDict['filenames']) if not os.path.exists(f)]
     591            if m1:
     592                print('\nimctrl file not found:')
     593                for i in m1: print('\t#'+str(i)+': '+tmpDict['filenames'][i])
     594            m2 = [i for i,f in enumerate(tmpDict['maskfile']) if not (os.path.exists(f) or f.startswith('('))]
     595            if m2:
     596                print('\nmask file not found')
     597                for i in m2: print('\t#'+str(i)+': '+tmpDict['maskfile'][i])
     598            m3 = [i for i,d in enumerate(tmpDict['distance']) if d < 0]
     599            if m3:
     600                print('\nDropping entries due to negative distance: '+str(m3))
     601            m = sorted(set(m1 + m2 + m3))
     602            m.reverse()
     603            for c in m:
     604                for key in tmpDict:
     605                    del tmpDict[key][c]
     606            fileList = tmpDict.get('filenames','[]')
     607            parms = []
     608            for key in self.ParmList:
     609                try:
     610                    float(tmpDict[key][0])
     611                    parms.append([str(G2py3.FormatSigFigs(val,sigfigs=5)) for val in tmpDict[key]])
     612                except ValueError:
     613                    parms.append(tmpDict[key])
     614            return parms,fileList
     615        # option 2, read in a list of files
     616        for file in files: # read all files; place in dict by distance
     617            imgDict = Read_imctrl(file)
     618            tmpDict[imgDict.get('distance')] = imgDict
     619        parms = [[] for key in self.ParmList]
     620        fileList = []
     621        for d in sorted(tmpDict):
     622            fileList.append(tmpDict[d].get('filename'))
     623            if d is None: continue
     624            if d < 0: continue
     625            for i,key in enumerate(self.ParmList):
     626                val = tmpDict[d].get(key)
     627                try:
     628                    val = str(G2py3.FormatSigFigs(val,sigfigs=5))
     629                except:
     630                    val = str(val)
     631                parms[i].append(val)
     632        return parms,fileList
     633   
     634    def ReadImageParmTable(self):
     635        '''Reads possibly edited values from the ListCtrl table and returns a list
     636        of values for each column.
     637        '''
     638        rows = self.list.GetItemCount()
     639        cols = self.list.GetColumnCount()
     640        parms = []
     641        for c in range(cols):
     642            lbl = self.ParmList[c]
     643            parms.append([])
     644            for r in range(rows):
     645                parms[c].append(self.list.GetItem(r,c).GetText())
     646        return parms
     647
     648    def _onClose(self,event):
     649        'Called when Cancel button is pressed'
     650        self.EndModal(wx.ID_CANCEL)
     651       
     652    def _onSave(self,event):
     653        'Called when save button is pressed; creates a .imtbl file'
     654        fil = ''
     655        if self.G2frame.GSASprojectfile:
     656            fil = os.path.splitext(self.G2frame.GSASprojectfile)[0]+'.imtbl'
     657        dir,f = os.path.split(fil)
     658        try:
     659            dlg = wx.FileDialog(self, 'Save table data as',
     660                        defaultDir=dir, defaultFile=f, style=wx.SAVE)
     661            if dlg.ShowModal() != wx.ID_OK: return
     662            fil = dlg.GetPath()
     663            fil = os.path.splitext(fil)[0]+'.imtbl'
     664        finally:
     665            dlg.Destroy()       
     666        parms = self.ReadImageParmTable()
     667        print('Writing image parameter table as '+fil)
     668        fp = open(fil,'w')
     669        for c in range(len(parms)-1):
     670            lbl = self.ParmList[c]
     671            fp.write(lbl+': '+str([eval(i) for i in parms[c]])+'\n')
     672        lbl = self.ParmList[c+1]
     673        fp.write(lbl+': '+str(parms[c+1])+'\n')
     674        lbl = 'filenames'
     675        fp.write(lbl+': '+str(self.IMfileList)+'\n')
     676        fp.close()
     677   
     678class ImgIntLstCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin,listmix.TextEditMixin):
     679    '''Creates a custom ListCtrl for editing Image Integration parameters
     680    '''
     681    def __init__(self, parent, ID, pos=wx.DefaultPosition,
     682                 size=(1000,200), style=0):
     683        self.parent=parent
     684        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
     685        listmix.ListCtrlAutoWidthMixin.__init__(self)
     686        listmix.TextEditMixin.__init__(self)
     687        self.Bind(wx.EVT_LEFT_DCLICK, self.OnDouble)
     688        #self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
     689    def FillList(self,parms):
     690        'Places the current parms into the table'
     691        self.ClearAll()
     692        self.rowlen = len(self.parent.ParmList)
     693        for i,lbl in enumerate(self.parent.HeaderList):
     694            self.InsertColumn(i, lbl)
     695        for r,d in enumerate(parms[0]):
     696            if float(d) < 0: continue
     697            index = self.InsertStringItem(sys.maxint, d)
     698            for j in range(1,len(parms)):
     699                self.SetStringItem(index, j, parms[j][r])
     700        for i,lbl in enumerate(self.parent.ParmList):
     701            self.SetColumnWidth(i, wx.LIST_AUTOSIZE)
     702
     703    def OnDouble(self,evt):
     704        'respond to a double-click'
     705        self.CloseEditor()
     706        fil = '(none)'
     707        try:
     708            dlg = wx.FileDialog(G2frame, 'Select mask or control file to add (Press cancel if none)',
     709                                style=wx.OPEN,
     710                                wildcard='Add GSAS-II mask file (.immask)|*.immask|add image control file (.imctrl)|*.imctrl')
     711            if dlg.ShowModal() == wx.ID_OK:
     712                fil = dlg.GetPath()
     713        finally:
     714            dlg.Destroy()
     715        if os.path.splitext(fil)[1] != '.imctrl':
     716            self.SetStringItem(self.curRow, self.rowlen-1, fil)
     717            self.SetColumnWidth(self.rowlen-1, wx.LIST_AUTOSIZE)
     718        else:
     719            # insert or overwrite an instrument parameter set
     720            if not os.path.exists(fil):
     721                print('Does not exist: '+fil)
     722                return
     723            imgDict = Read_imctrl(fil)
     724            dist = imgDict['distance']
     725            parms = self.parent.ReadImageParmTable()
     726            x = np.array([float(i) for i in parms[0]])
     727            closest = abs(x-dist).argmin()
     728            closeX = x[closest]
     729            # fix IMfileList
     730            for c,lbl in enumerate(self.parent.ParmList):
     731                try:
     732                    vali = G2py3.FormatSigFigs(float(imgDict[lbl]),sigfigs=5)
     733                except ValueError:
     734                    vali = imgDict[lbl]
     735                if abs(closeX-dist) < 1.: # distance is within 1 mm, replace
     736                    parms[c][closest] = vali
     737                elif dist > closeX: # insert after
     738                    parms[c].insert(closest+1,vali)
     739                else:
     740                    parms[c].insert(closest,vali)
     741            if abs(closeX-dist) < 1.: # distance is within 1 mm, replace
     742                self.parent.IMfileList[closest] = fil
     743            elif dist > closeX: # insert after
     744                self.parent.IMfileList.insert(closest+1,fil)
     745            else:
     746                self.parent.IMfileList.insert(closest,fil)
     747            self.FillList(parms)
    423748
    424749if __name__ == '__main__':
Note: See TracChangeset for help on using the changeset viewer.