source: trunk/GSASII.py @ 607

Last change on this file since 607 was 607, checked in by toby, 11 years ago

revise help to include tutorials on tree only; add kw args to all readers; cache cif for multiple passes; start on powder imports

  • Property svn:keywords set to Date Author Revision URL Id
File size: 96.3 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#GSASII
4########### SVN repository information ###################
5# $Date: 2012-05-09 13:55:25 +0000 (Wed, 09 May 2012) $
6# $Author: toby $
7# $Revision: 607 $
8# $URL: trunk/GSASII.py $
9# $Id: GSASII.py 607 2012-05-09 13:55:25Z toby $
10########### SVN repository information ###################
11
12import os
13import os.path as ospath
14import sys
15import math
16import copy
17#import cPickle
18import time
19import copy
20import glob
21import imp
22import inspect
23import numpy as np
24import scipy as sp
25import wx
26import matplotlib as mpl
27import wx.lib.inspection as wxeye
28try:
29    import OpenGL as ogl
30except ImportError:
31    print('*******************************************************')
32    print('PyOpenGL is missing from your python installation')
33    print('     - we will try to install it')
34    print('*******************************************************')
35    def install_with_easyinstall(package):
36        try: 
37            print "trying a system-wide PyOpenGl install"
38            easy_install.main(['-f',ospath.split(__file__)[0],package])
39            return
40        except:
41            pass
42        try: 
43            print "trying a user level PyOpenGl install"
44            easy_install.main(['-f',ospath.split(__file__)[0],'--user',package])
45            return
46        except:
47            print "Install of '+package+' failed. Please report this information:"
48            import traceback
49            print traceback.format_exc()
50            sys.exit()
51    from setuptools.command import easy_install
52    install_with_easyinstall('PyOpenGl')
53    print('*******************************************************')         
54    print('OpenGL has been installed. Please restart GSAS-II')
55    print('*******************************************************')         
56    sys.exit()
57
58# load the GSAS routines
59import GSASIIpath
60import GSASIIIO as G2IO
61import GSASIIgrid as G2gd
62import GSASIIplot as G2plt
63import GSASIIpwdGUI as G2pdG
64import GSASIIspc as G2spc
65import GSASIIstruct as G2str
66import GSASIImapvars as G2mv
67import GSASIIsolve as G2sol
68
69#wx inspector - use as needed
70wxInspector = False
71
72# print versions
73print "Available python module versions for GSASII:"
74print "python:     ",sys.version[:5]
75print "wxpython:   ",wx.__version__
76print "matplotlib: ",mpl.__version__
77print "numpy:      ",np.__version__
78print "scipy:      ",sp.__version__
79print "OpenGL:     ",ogl.__version__
80try:
81    import mkl
82    print "Max threads ",mkl.get_max_threads()
83except:
84    print "MKL module not present"
85__version__ = '0.1.5'
86G2gd.__version__ = __version__
87print "This is GSAS-II version:     ",__version__
88
89# useful degree trig functions
90sind = lambda x: math.sin(x*math.pi/180.)
91cosd = lambda x: math.cos(x*math.pi/180.)
92tand = lambda x: math.tan(x*math.pi/180.)
93asind = lambda x: 180.*math.asin(x)/math.pi
94acosd = lambda x: 180.*math.acos(x)/math.pi
95atan2d = lambda x,y: 180.*math.atan2(y,x)/math.pi
96
97def create(parent):
98    return GSASII(parent)
99
100[wxID_PATTERNTREE, 
101] = [wx.NewId() for _init_ctrls in range(1)]
102
103[wxID_FILECLOSE, wxID_FILEEXIT, wxID_FILEOPEN,  wxID_FILESAVE, wxID_FILESAVEAS, 
104wxID_REFINE,  wxID_MAKEPDFS, wxID_VIEWLSPARMS, wxID_SEQREFINE,
105] = [wx.NewId() for _init_coll_File_Items in range(9)]
106
107[wxID_PWDRREAD,wxID_SNGLREAD,wxID_ADDPHASE,wxID_DELETEPHASE,
108 wxID_DATADELETE,wxID_READPEAKS,wxID_PWDSUM,wxID_IMGREAD,
109 wxID_IMSUM, wxID_DATARENAME,
110] = [wx.NewId() for _init_coll_Data_Items in range(10)]
111
112[wxID_IMPORT, wxID_IMPORTPATTERN, wxID_IMPORTHKL
113#, wxID_IMPORTPHASE,
114#wxID_IMPORTCIF, wxID_IMPORTPDB, 
115] = [wx.NewId() for _init_coll_Import_Items in range(3)]
116
117[wxID_EXPORT, wxID_EXPORTPATTERN, wxID_EXPORTHKL, wxID_EXPORTPHASE,
118wxID_EXPORTCIF, wxID_EXPORTPEAKLIST, wxID_EXPORTPDF,
119] = [wx.NewId() for _init_coll_Export_Items in range(7)]
120
121class GSASII(wx.Frame):
122   
123    def _init_coll_GSASIIMenu_Menus(self, parent):
124        parent.Append(menu=self.File, title='File')
125        parent.Append(menu=self.Data, title='Data')
126        parent.Append(menu=self.Calculate, title='Calculate')
127        parent.Append(menu=self.Import, title='Import')
128        parent.Append(menu=self.Export, title='Export')
129        self.HelpMenu=G2gd.MyHelp(self,
130                                  helpType='Data tree',
131                                  morehelpitems=[('&Tutorials','Tutorials')]
132                                  )
133        parent.Append(menu=self.HelpMenu,title='&Help')
134       
135    def _init_coll_File_Items(self, parent):
136        parent.Append(help='Open a gsasii project file (*.gpx)', id=wxID_FILEOPEN,
137             kind=wx.ITEM_NORMAL,text='Open project...')
138        parent.Append(help='Save project to old file', id=wxID_FILESAVE, 
139            kind=wx.ITEM_NORMAL,text='Save project')
140        parent.Append(help='Save project to new file', id=wxID_FILESAVEAS, 
141            kind=wx.ITEM_NORMAL,text='Save As...')
142        parent.Append(help='Close project, saving is optional', id=wxID_FILECLOSE, 
143            kind=wx.ITEM_NORMAL,text='Close project')
144        parent.Append(help='Exit from gsasii', id=wxID_FILEEXIT, kind=wx.ITEM_NORMAL,
145            text='Exit')
146        self.Bind(wx.EVT_MENU, self.OnFileOpen, id=wxID_FILEOPEN)
147        self.Bind(wx.EVT_MENU, self.OnFileSave, id=wxID_FILESAVE)
148        self.Bind(wx.EVT_MENU, self.OnFileSaveas, id=wxID_FILESAVEAS)
149        self.Bind(wx.EVT_MENU, self.OnFileClose, id=wxID_FILECLOSE)
150        self.Bind(wx.EVT_MENU, self.OnFileExit, id=wxID_FILEEXIT)
151       
152    def _init_coll_Data_Items(self,parent):
153        parent.Append(help='', id=wxID_PWDRREAD, kind=wx.ITEM_NORMAL,
154            text='Read powder data...')
155        parent.Append(help='',id=wxID_IMGREAD, kind=wx.ITEM_NORMAL,
156            text='Read image data...')
157        parent.Append(help='',id=wxID_READPEAKS, kind=wx.ITEM_NORMAL,
158            text='Read Powder Pattern Peaks...')
159        parent.Append(help='', id=wxID_SNGLREAD, kind=wx.ITEM_NORMAL,
160            text='Read single crystal data...')
161        parent.Append(help='', id=wxID_PWDSUM, kind=wx.ITEM_NORMAL,
162            text='Sum powder data')
163        parent.Append(help='',id=wxID_IMSUM, kind=wx.ITEM_NORMAL,
164            text='Sum image data')
165        parent.Append(help='', id=wxID_ADDPHASE, kind=wx.ITEM_NORMAL,
166            text='Add phase')
167        parent.Append(help='', id=wxID_DELETEPHASE, kind=wx.ITEM_NORMAL,
168            text='Delete phase')
169        parent.Append(help='', id=wxID_DATARENAME, kind=wx.ITEM_NORMAL,
170            text='Rename data') 
171        parent.Append(help='', id=wxID_DATADELETE, kind=wx.ITEM_NORMAL,
172            text='Delete data')
173        self.Bind(wx.EVT_MENU, self.OnPwdrRead, id=wxID_PWDRREAD)
174        self.Bind(wx.EVT_MENU, self.OnPwdrSum, id=wxID_PWDSUM)
175        self.Bind(wx.EVT_MENU, self.OnReadPowderPeaks, id=wxID_READPEAKS)
176        self.Bind(wx.EVT_MENU, self.OnImageRead, id=wxID_IMGREAD)
177        self.Bind(wx.EVT_MENU, self.OnImageSum, id=wxID_IMSUM)
178        self.Bind(wx.EVT_MENU, self.OnSnglRead, id=wxID_SNGLREAD)
179        self.Bind(wx.EVT_MENU, self.OnAddPhase, id=wxID_ADDPHASE)
180        self.Bind(wx.EVT_MENU, self.OnDeletePhase, id=wxID_DELETEPHASE)
181        self.Bind(wx.EVT_MENU, self.OnRenameData, id=wxID_DATARENAME)
182        self.Bind(wx.EVT_MENU, self.OnDataDelete, id=wxID_DATADELETE)
183               
184    def _init_coll_Calculate_Items(self,parent):
185        self.MakePDF = parent.Append(help='Make new PDFs from selected powder patterns', 
186            id=wxID_MAKEPDFS, kind=wx.ITEM_NORMAL,text='Make new PDFs')
187        self.Bind(wx.EVT_MENU, self.OnMakePDFs, id=wxID_MAKEPDFS)
188        self.ViewLSParms = parent.Append(help='View least squares parameters', 
189            id=wxID_VIEWLSPARMS, kind=wx.ITEM_NORMAL,text='View LS parms')
190        self.Bind(wx.EVT_MENU, self.OnViewLSParms, id=wxID_VIEWLSPARMS)
191        self.Refine = parent.Append(help='', id=wxID_REFINE, kind=wx.ITEM_NORMAL,
192            text='Refine')
193        self.Refine.Enable(False)
194        self.Bind(wx.EVT_MENU, self.OnRefine, id=wxID_REFINE)
195        self.SeqRefine = parent.Append(help='', id=wxID_SEQREFINE, kind=wx.ITEM_NORMAL,
196            text='Sequental refine')
197        self.SeqRefine.Enable(False)
198        self.Bind(wx.EVT_MENU, self.OnSeqRefine, id=wxID_SEQREFINE)
199       
200    def _init_Import_routines(self,parent,prefix,readerlist,errprefix):
201        '''import all the import readers matching the prefix
202        '''
203        path2GSAS2 = os.path.dirname(os.path.realpath(__file__)) # location of this file
204        pathlist = sys.path[:]
205        if path2GSAS2 not in pathlist: pathlist.append(path2GSAS2)
206        filelist = []
207        for path in pathlist:
208            for filename in glob.iglob(os.path.join(
209                path,
210                "G2import"+prefix+"*.py")):
211                filelist.append(filename)   
212                #print 'found',filename
213        filelist = sorted(list(set(filelist))) # remove duplicates
214        for filename in filelist:
215            path,rootname = os.path.split(filename)
216            pkg = os.path.splitext(rootname)[0]
217            try:
218                fp = None
219                fp, fppath,desc = imp.find_module(pkg,[path,])
220                pkg = imp.load_module(pkg,fp,fppath,desc)
221                for clss in inspect.getmembers(pkg): # find classes defined in package
222                    if clss[0].startswith('_'): continue
223                    if inspect.isclass(clss[1]):
224                        # check if we have the required methods
225                        for m in 'Reader','ExtensionValidator','ContentsValidator':
226                            if not hasattr(clss[1],m): break
227                            if not callable(getattr(clss[1],m)): break
228                        else:
229                            reader = clss[1]() # create an import instance
230                            readerlist.append(reader)
231            except AttributeError:
232                print 'Import_'+errprefix+': Attribute Error'+str(filename)
233                pass
234            except ImportError:
235                print 'Import_'+errprefix+': Error importing file'+str(filename)
236                pass
237            finally:
238                if fp: fp.close()
239
240    def OnImportGeneric(self,reader,readerlist,label,multiple=False):
241        '''Call the requested import reader or all of the appropriate
242        import readers in response to a menu item
243        '''
244        self.lastimport = ''
245        if reader is None:
246            multiple = False
247            #print "use all formats"
248            choices = "any file (*.*)|*.*"
249            extdict = {}
250            # compile a list of allowed extensions
251            for rd in readerlist:
252                fmt = rd.formatName
253                for extn in rd.extensionlist:
254                    if not extdict.get(extn): extdict[extn] = []
255                    extdict[extn] += [fmt,]
256            for extn in sorted(extdict.keys(),cmp=lambda x,y: cmp(x.lower(), y.lower())):
257                fmt = ''
258                for f in extdict[extn]:
259                    if fmt != "": fmt += ', '
260                    fmt += f
261                choices += "|" + fmt + " file (*" + extn + ")|*" + extn
262        else:
263            readerlist = [reader,]
264            # compile a list of allowed extensions
265            choices = reader.formatName + " file ("
266            w = ""
267            for extn in reader.extensionlist:
268                if w != "": w += ";"
269                w += "*" + extn
270            choices += w + ")|" + w
271            if not reader.strictExtension:
272                choices += "|any file (*.*)|*.*"
273        # get the file
274        if multiple:
275            mode = style=wx.OPEN | wx.CHANGE_DIR | wx.MULTIPLE
276        else:
277            mode = style=wx.OPEN | wx.CHANGE_DIR
278        dlg = wx.FileDialog(
279            self, message="Choose "+label+" input file",
280            #defaultDir=os.getcwd(),
281            defaultFile="",
282            wildcard=choices, style=mode
283            )
284        try:
285            if dlg.ShowModal() == wx.ID_OK:
286                if multiple:
287                    filelist = dlg.GetPaths()
288                    if len(filelist) == 0: return []
289                else:
290                    filename = dlg.GetPath()
291                    filelist = [filename,]
292            else: # cancel was pressed
293                return []
294        finally:
295            dlg.Destroy()
296        rd_list = []
297        for filename in filelist:
298        # set what formats are compatible with this file
299            primaryReaders = []
300            secondaryReaders = []
301            for reader in readerlist:
302                flag = reader.ExtensionValidator(filename)
303                if flag is None: 
304                    secondaryReaders.append(reader)
305                elif flag:
306                    primaryReaders.append(reader)
307            if len(secondaryReaders) + len(primaryReaders) == 0:
308                self.ErrorDialog('No Format','No matching format for file '+filename)
309                return []
310
311            fp = None
312            msg = ''
313            try:
314                fp = open(filename,'r')
315                self.lastimport = filename
316                # try the file first with Readers that specify the
317                # files extension and later with ones that allow it
318                flag = False
319                for rd in primaryReaders+secondaryReaders:
320                    try:
321                        fp.seek(0)  # rewind
322                        if not rd.ContentsValidator(fp): continue # rejected on cursory check
323                        repeat = True
324                        rdbuffer = {} # create temporary storage for file reader
325                        block = 0
326                        while repeat:
327                            block += 1
328                            repeat = False
329                            fp.seek(0)  # rewind
330                            rd.objname = ospath.basename(filename)
331                            flag = rd.Reader(filename,fp,self,
332                                             buffer=rdbuffer,
333                                             blocknum=block)
334                            if flag:
335                                rd_list.append(copy.deepcopy(rd)) # success
336                                if rd.repeat: repeat = True
337                    except:
338                        import traceback
339                        print traceback.format_exc()
340                        msg += '\nError reading file '+filename+' with format '+ rd.formatName
341                        #self.ErrorDialog('Read Error',
342                        #                 'Error reading file '+filename
343                        #                 +' with format '+ rd.formatName)
344                        continue
345                    if flag: break # success reading
346                else:
347                    self.ErrorDialog('Read Error','No reader is able to read from file '+filename+msg)
348            except:
349                import traceback
350                print traceback.format_exc()
351                self.ErrorDialog('Open Error','Error on open of file '+filename)
352            finally:
353                if fp: fp.close()
354        return rd_list
355
356    def _init_Import_Phase(self,parent):
357        '''import all the G2importphase*.py files that are found in the
358        path and configure the Import Phase menus accordingly
359        '''
360        self.ImportPhaseReaderlist = []
361        self._init_Import_routines(parent,'phase',
362                                   self.ImportPhaseReaderlist,
363                                   'Phase')
364        submenu = wx.Menu()
365        item = parent.AppendMenu(wx.ID_ANY, 'Import Phase menu',
366            submenu, help='Import phase data')
367        item = submenu.Append(wx.ID_ANY,
368                              help='Import phase data based selected by extension',
369                              kind=wx.ITEM_NORMAL,text='Import Phase by extension')
370        self.Bind(wx.EVT_MENU, self.OnImportPhase, id=item.GetId())
371        for reader in self.ImportPhaseReaderlist:
372            item = submenu.Append(wx.ID_ANY,
373                help='Import specific format phase data',
374                kind=wx.ITEM_NORMAL,text='Import Phase '+reader.formatName+'...')
375            self.ImportMenuId[item.GetId()] = reader
376            self.Bind(wx.EVT_MENU, self.OnImportPhase, id=item.GetId())
377
378    def OnImportPhase(self,event):
379        # look up which format was requested
380        reqrdr = self.ImportMenuId.get(event.GetId())
381        rdlist = self.OnImportGeneric(reqrdr,
382                                  self.ImportPhaseReaderlist,
383                                  'phase')
384        if len(rdlist) == 0: return
385        # for now rdlist is only expected to have one element
386        # but this will allow multiple phases to be imported
387        self.CheckNotebook()
388        for rd in rdlist:
389            dlg = wx.TextEntryDialog( # allow editing of phase name
390                self, 'Enter the name for the new phase',
391                'Edit phase name', rd.Phase['General']['Name'],
392                style=wx.OK)
393            dlg.CenterOnParent()
394            if dlg.ShowModal() == wx.ID_OK:
395                rd.Phase['General']['Name'] = dlg.GetValue()
396            dlg.Destroy()
397            PhaseName = rd.Phase['General']['Name']
398            print 'Read phase '+str(PhaseName)+' from file '+str(self.lastimport)
399            if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
400                sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
401            else:
402                sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
403            psub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
404            self.PatternTree.SetItemPyData(psub,rd.Phase)
405            self.PatternTree.Expand(self.root) # make sure phases are seen
406            self.PatternTree.Expand(sub) 
407            self.PatternTree.Expand(psub) 
408        return # success
409       
410    def _init_Import_Sfact(self,parent):
411        '''import all the G2importsfact*.py files that are found in the
412        path and configure the Import Structure Factor menus accordingly
413        '''
414        self.ImportSfactReaderlist = []
415        self._init_Import_routines(parent,'sfact',
416                                   self.ImportSfactReaderlist,
417                                   'Struct_Factor')
418        submenu = wx.Menu()
419        item = parent.AppendMenu(wx.ID_ANY, 'Import Structure Factor menu',
420            submenu, help='Import Structure Factor data')
421        item = submenu.Append(wx.ID_ANY,
422                              help='Import Structure Factor (determine format from file extension)',
423                              kind=wx.ITEM_NORMAL,text='Import Structure Factor (fmt from extension)')
424        self.Bind(wx.EVT_MENU, self.OnImportSfact, id=item.GetId())
425        for reader in self.ImportSfactReaderlist:
426            item = submenu.Append(wx.ID_ANY,
427                help='Import specific format Structure Factor data',
428                kind=wx.ITEM_NORMAL,text='Import Structure Factor '+reader.formatName+'...')
429            self.ImportMenuId[item.GetId()] = reader
430            self.Bind(wx.EVT_MENU, self.OnImportSfact, id=item.GetId())
431
432    def OnImportSfact(self,event):
433        # look up which format was requested
434        reqrdr = self.ImportMenuId.get(event.GetId())
435        rdlist = self.OnImportGeneric(reqrdr,
436                                  self.ImportSfactReaderlist,
437                                  'Structure Factor')
438        if len(rdlist) == 0: return
439        self.CheckNotebook()
440        for rd in rdlist:
441            HistName = rd.objname
442            if len(rdlist) <= 2: 
443                dlg = wx.TextEntryDialog( # allow editing of Structure Factor name
444                    self, 'Enter the name for the new Structure Factor',
445                    'Edit Structure Factor name', HistName,
446                    style=wx.OK)
447                dlg.CenterOnParent()
448                if dlg.ShowModal() == wx.ID_OK:
449                    HistName = dlg.GetValue()
450                dlg.Destroy()
451            print 'Read structure factor table '+str(HistName)+' from file '+str(self.lastimport)
452            Id = self.PatternTree.AppendItem(parent=self.root,
453                                             text='HKLF '+HistName)
454            self.PatternTree.SetItemPyData(Id,rd.RefList)
455            Sub = self.PatternTree.AppendItem(Id,text='Instrument Parameters')
456            self.PatternTree.SetItemPyData(Sub,rd.Parameters)
457            self.PatternTree.SetItemPyData(
458                self.PatternTree.AppendItem(Id,text='HKL Plot Controls'),
459                rd.Controls)
460            self.PatternTree.SelectItem(Id)
461            self.PatternTree.Expand(Id)
462            self.Sngl = Id
463        return # success
464
465    def _init_Import_powder(self,parent):
466        '''import all the G2importpwd*.py files that are found in the
467        path and configure the Import Powder Data menus accordingly
468        '''
469        self.ImportPowderReaderlist = []
470        self._init_Import_routines(parent,'pwd',
471                                   self.ImportPowderReaderlist,
472                                   'Powder_Data')
473        submenu = wx.Menu()
474        item = parent.AppendMenu(wx.ID_ANY, 'Import Powder Data menu',
475            submenu, help='Import Powder data')
476        item = submenu.Append(wx.ID_ANY,
477                              help='Import powder data (determine format from file extension)',
478                              kind=wx.ITEM_NORMAL,text='Import powder data (fmt from extension)')
479        self.Bind(wx.EVT_MENU, self.OnImportPowder, id=item.GetId())
480        for reader in self.ImportPowderReaderlist:
481            item = submenu.Append(wx.ID_ANY,
482                help='Import specific format powder data',
483                kind=wx.ITEM_NORMAL,text='Import powder data from '+reader.formatName+' file ...')
484            self.ImportMenuId[item.GetId()] = reader
485            self.Bind(wx.EVT_MENU, self.OnImportPowder, id=item.GetId())
486           
487    def GetPowderIparm(self,rd, prevIparm):
488        '''Open and read an instrument parameter file for a data file
489        for now, just set defaults
490        '''
491        dlg = wx.MessageDialog(self,
492'''Is this laboratory Cu Ka1/Ka2 data?
493(No = 0.6A wavelength synchrotron data)
494Change wavelength in Instrument Parameters if needed''',
495                               'Data type?',
496                               wx.YES_NO | wx.ICON_QUESTION)
497        try:
498            result = dlg.ShowModal()
499        finally:
500            dlg.Destroy()
501        if result == wx.ID_YES:
502            return rd.Iparm_CuKa12
503        else:
504            return rd.Iparm_Sync06
505
506    def SetPowderInstParms(self, Iparm):
507        '''extracts values from instrument parameter file and creates
508        the contents of the instrument parameter tree entry
509        '''
510        DataType = Iparm['INS   HTYPE '].strip()[0:3]  # take 1st 3 chars
511        data = [DataType,]
512        if 'C' in DataType:
513            s = Iparm['INS  1 ICONS']
514            v = (G2IO.sfloat(s[:10]),G2IO.sfloat(s[10:20]),G2IO.sfloat(s[20:30]),G2IO.sfloat(s[55:65]),G2IO.sfloat(s[40:50])) #get lam1, lam2, zero, pola & ratio
515            if not v[1]:
516                names = ['Type','Lam','Zero','Polariz.','U','V','W','X','Y','SH/L','Azimuth'] 
517                v = (v[0],v[2],v[4])
518                codes = [0,0,0,0]
519            else:
520                names = ['Type','Lam1','Lam2','Zero','I(L2)/I(L1)','Polariz.','U','V','W','X','Y','SH/L','Azimuth']
521                codes = [0,0,0,0,0,0]
522            data.extend(v)
523            v1 = Iparm['INS  1PRCF1 '].split()                                                 
524            v = Iparm['INS  1PRCF11'].split()
525            data.extend([float(v[0]),float(v[1]),float(v[2])])                  #get GU, GV & GW - always here
526            azm = Iparm.get('INS  1DETAZM')
527            if azm is None: #not in this Iparm file
528                azm = 0.0
529            else:
530                azm = float(azm)
531            v = Iparm['INS  1PRCF12'].split()
532            if v1[0] == 3:
533                data.extend([float(v[0]),float(v[1]),float(v[2])+float(v[3],azm)])  #get LX, LY, S+H/L & azimuth
534            else:
535                data.extend([0.0,0.0,0.002,azm])                                      #OK defaults if fxn #3 not 1st in iprm file
536            codes.extend([0,0,0,0,0,0,0])
537            return [tuple(data),data,codes,names]
538
539    def OnImportPowder(self,event):
540        reqrdr = self.ImportMenuId.get(event.GetId())  # look up which format was requested
541        rdlist = self.OnImportGeneric(reqrdr,
542                                      self.ImportPowderReaderlist,
543                                      'Powder Data',multiple=True)
544        if len(rdlist) == 0: return
545        self.CheckNotebook()
546        Iparm = None
547        for rd in rdlist:
548            Iparm = self.GetPowderIparm(rd, Iparm)
549            print 'Read powder data '+str(
550                rd.idstring)+' from file '+str(
551                self.lastimport)
552            Id = self.PatternTree.AppendItem(
553                parent=self.root,
554                text='PWDR '+rd.idstring)
555            self.PatternTree.SetItemPyData(Id,[rd.powderentry,rd.powderdata])
556            self.PatternTree.SetItemPyData(
557                self.PatternTree.AppendItem(Id,text='Comments'),
558                rd.comments)
559            Tmin = min(rd.powderdata[0])
560            Tmax = max(rd.powderdata[0])
561            self.PatternTree.SetItemPyData(
562                self.PatternTree.AppendItem(Id,text='Limits'),
563                [(Tmin,Tmax),[Tmin,Tmax]])
564            self.PatternId = G2gd.GetPatternTreeItemId(self,Id,'Limits')
565            self.PatternTree.SetItemPyData(
566                self.PatternTree.AppendItem(Id,text='Background'),
567                [['chebyschev',True,3,1.0,0.0,0.0],
568                 {'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]}])
569            self.PatternTree.SetItemPyData(
570                self.PatternTree.AppendItem(Id,text='Instrument Parameters'),
571                self.SetPowderInstParms(Iparm))
572            self.PatternTree.SetItemPyData(
573                self.PatternTree.AppendItem(Id,text='Sample Parameters'),
574                rd.Sample)
575            self.PatternTree.SetItemPyData(
576                self.PatternTree.AppendItem(Id,text='Peak List')
577                ,[])
578            self.PatternTree.SetItemPyData(
579                self.PatternTree.AppendItem(Id,text='Index Peak List'),
580                [])
581            self.PatternTree.SetItemPyData(
582                self.PatternTree.AppendItem(Id,text='Unit Cells List'),
583                [])
584            self.PatternTree.SetItemPyData(
585                self.PatternTree.AppendItem(Id,text='Reflection Lists'),
586                {})
587            self.PatternTree.Expand(Id)
588        self.PatternTree.SelectItem(Id)
589        return # success
590
591    def _init_coll_Import_Items(self,parent):
592        self.ImportPattern = parent.Append(help='',id=wxID_IMPORTPATTERN, kind=wx.ITEM_NORMAL,
593            text='Import Powder Pattern...')
594        self.ImportHKL = parent.Append(help='',id=wxID_IMPORTHKL, kind=wx.ITEM_NORMAL,
595            text='Import HKLs...')
596        self.Bind(wx.EVT_MENU, self.OnImportPattern, id=wxID_IMPORTPATTERN)
597        self.Bind(wx.EVT_MENU, self.OnImportHKL, id=wxID_IMPORTHKL)
598
599    def _init_coll_Export_Items(self,parent):
600        self.ExportPattern = parent.Append(help='Select PWDR item to enable',id=wxID_EXPORTPATTERN, kind=wx.ITEM_NORMAL,
601            text='Export Powder Patterns...')
602        self.ExportPeakList = parent.Append(help='',id=wxID_EXPORTPEAKLIST, kind=wx.ITEM_NORMAL,
603            text='Export All Peak Lists...')
604        self.ExportHKL = parent.Append(help='',id=wxID_EXPORTHKL, kind=wx.ITEM_NORMAL,
605            text='Export HKLs...')
606        self.ExportPDF = parent.Append(help='Select PDF item to enable',id=wxID_EXPORTPDF, kind=wx.ITEM_NORMAL,
607            text='Export PDF...')
608        self.ExportPhase = parent.Append(help='',id=wxID_EXPORTPHASE, kind=wx.ITEM_NORMAL,
609            text='Export Phase...')
610        self.ExportCIF = parent.Append(help='',id=wxID_EXPORTCIF, kind=wx.ITEM_NORMAL,
611            text='Export CIF...')
612        self.ExportPattern.Enable(False)
613        self.ExportPeakList.Enable(True)
614        self.ExportHKL.Enable(False)
615        self.ExportPDF.Enable(False)
616        self.ExportPhase.Enable(False)
617        self.ExportCIF.Enable(False)
618        self.Bind(wx.EVT_MENU, self.OnExportPatterns, id=wxID_EXPORTPATTERN)
619        self.Bind(wx.EVT_MENU, self.OnExportPeakList, id=wxID_EXPORTPEAKLIST)
620        self.Bind(wx.EVT_MENU, self.OnExportHKL, id=wxID_EXPORTHKL)
621        self.Bind(wx.EVT_MENU, self.OnExportPDF, id=wxID_EXPORTPDF)
622        self.Bind(wx.EVT_MENU, self.OnExportPhase, id=wxID_EXPORTPHASE)
623        self.Bind(wx.EVT_MENU, self.OnExportCIF, id=wxID_EXPORTCIF)
624               
625    def _init_utils(self):
626        self.GSASIIMenu = wx.MenuBar()
627        self.File = wx.Menu(title='')
628        self.Data = wx.Menu(title='')       
629        self.Calculate = wx.Menu(title='')       
630        self.Import = wx.Menu(title='')       
631        self.Export = wx.Menu(title='')       
632
633        self._init_coll_GSASIIMenu_Menus(self.GSASIIMenu)
634        self._init_coll_File_Items(self.File)
635        self._init_coll_Data_Items(self.Data)
636        self._init_coll_Calculate_Items(self.Calculate)
637        self.ImportMenuId = {}
638        self._init_Import_Phase(self.Import)
639        self._init_Import_powder(self.Import)
640        self._init_Import_Sfact(self.Import)
641        self._init_coll_Import_Items(self.Import)
642        self._init_coll_Export_Items(self.Export)
643       
644    def _init_ctrls(self, parent):
645        wx.Frame.__init__(self, name='GSASII', parent=parent,
646            size=wx.Size(400, 250),style=wx.DEFAULT_FRAME_STYLE, title='GSAS-II data tree')
647        clientSize = wx.ClientDisplayRect()
648        Size = self.GetSize()
649        xPos = clientSize[2]-Size[0]
650        self.SetPosition(wx.Point(xPos,clientSize[1]))
651        self._init_utils()
652        self.SetMenuBar(self.GSASIIMenu)
653        self.Bind(wx.EVT_SIZE, self.OnSize)
654        self.CreateStatusBar()
655        self.mainPanel = wx.Panel(self,-1)
656       
657        self.PatternTree = wx.TreeCtrl(id=wxID_PATTERNTREE,
658            parent=self.mainPanel, pos=wx.Point(0, 0),style=wx.TR_DEFAULT_STYLE )
659        self.PatternTree.Bind(wx.EVT_TREE_SEL_CHANGED,
660            self.OnPatternTreeSelChanged, id=wxID_PATTERNTREE)
661        self.PatternTree.Bind(wx.EVT_TREE_ITEM_COLLAPSED,
662            self.OnPatternTreeItemCollapsed, id=wxID_PATTERNTREE)
663        self.PatternTree.Bind(wx.EVT_TREE_ITEM_EXPANDED,
664            self.OnPatternTreeItemExpanded, id=wxID_PATTERNTREE)
665        self.PatternTree.Bind(wx.EVT_TREE_DELETE_ITEM,
666            self.OnPatternTreeItemDelete, id=wxID_PATTERNTREE)
667        self.PatternTree.Bind(wx.EVT_TREE_KEY_DOWN,
668            self.OnPatternTreeKeyDown, id=wxID_PATTERNTREE)
669        self.root = self.PatternTree.AddRoot('Loaded Data: ')
670       
671        plotFrame = wx.Frame(None,-1,'GSASII Plots',size=wx.Size(700,600), \
672            style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX)
673        self.G2plotNB = G2plt.G2PlotNoteBook(plotFrame)
674        plotFrame.Show()
675       
676        self.dataDisplay = None
677       
678    def __init__(self, parent):
679        self._init_ctrls(parent)
680        self.Bind(wx.EVT_CLOSE, self.ExitMain)
681        # various defaults
682        self.oldFocus = None
683        self.GSASprojectfile = ''
684        self.dirname = ospath.expanduser('~')       #start in the users home directory by default; may be meaningless
685        self.undofile = ''
686        self.TreeItemDelete = False
687        self.Offset = [0.0,0.0]
688        self.delOffset = .02
689        self.refOffset = -100.0
690        self.refDelt = .01
691        self.Weight = False
692        self.IparmName = ''
693        self.IfPlot = False
694        self.PatternId = 0
695        self.PickId = 0
696        self.PeakTable = []
697        self.LimitsTable = []
698        self.HKL = []
699        self.Lines = []
700        self.itemPicked = None
701        self.dataFrame = None
702        self.Interpolate = 'nearest'
703        self.ContourColor = 'Paired'
704        self.VcovColor = 'RdYlGn'
705        self.Projection = 'equal area'
706        self.logPlot = False
707        self.qPlot = False
708        self.Contour = False
709        self.Legend = False
710        self.SinglePlot = False
711        self.plotView = 0
712        self.Image = 0
713        self.oldImagefile = ''
714        self.ImageZ = []
715        self.Integrate = 0
716        self.Pwdr = False
717        self.imageDefault = {}
718        self.Sngl = 0
719        self.ifGetRing = False
720        self.setPoly = False
721        arg = sys.argv
722        if len(arg) > 1:
723            self.GSASprojectfile = arg[1]
724            self.dirname = ospath.dirname(arg[1])
725            if self.dirname: os.chdir(self.dirname)
726            G2IO.ProjFileOpen(self)
727            self.PatternTree.Expand(self.root)
728            self.Refine.Enable(True)
729            self.SeqRefine.Enable(True)
730
731    def OnSize(self,event):
732        w,h = self.GetClientSizeTuple()
733        self.mainPanel.SetSize(wx.Size(w,h))
734        self.PatternTree.SetSize(wx.Size(w,h))
735                       
736    def OnPatternTreeSelChanged(self, event):
737        if self.TreeItemDelete:
738            self.TreeItemDelete = False
739        else:
740            pltNum = self.G2plotNB.nb.GetSelection()
741            if pltNum >= 0:                         #to avoid the startup with no plot!
742                pltPage = self.G2plotNB.nb.GetPage(pltNum)
743                pltPlot = pltPage.figure
744            item = event.GetItem()
745            G2gd.MovePatternTreeToGrid(self,item)
746            if self.oldFocus:
747                self.oldFocus.SetFocus()
748       
749    def OnPatternTreeItemCollapsed(self, event):
750        event.Skip()
751
752    def OnPatternTreeItemExpanded(self, event):
753        event.Skip()
754       
755    def OnPatternTreeItemDelete(self, event):
756        self.TreeItemDelete = True
757
758    def OnPatternTreeItemActivated(self, event):
759        event.Skip()
760       
761    def OnPatternTreeKeyDown(self,event):
762        key = event.GetKeyCode()
763        item = self.PickId
764        if type(item) is int: return # is this the toplevel in tree?
765        if key == wx.WXK_UP:
766            self.oldFocus = wx.Window.FindFocus()
767            self.PatternTree.GetPrevSibling(item)
768        elif key == wx.WXK_DOWN:
769            self.oldFocus = wx.Window.FindFocus()
770            self.PatternTree.GetNextSibling(item)
771               
772    def OnPwdrRead(self, event):
773        self.CheckNotebook()
774        dlg = wx.FileDialog(self, 'Choose files', '.', '', 
775            'GSAS fxye files (*.fxye)|*.fxye|GSAS fxy files (*.fxy)|*.fxy|Topas xye files (*.xye)|*.xye|All files (*.*)|*.*', 
776            wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR)
777        try:
778            if dlg.ShowModal() == wx.ID_OK:
779                filenames = dlg.GetPaths()
780                filenames.sort()
781                for filename in filenames:
782                    Data,Iparm,Comments,Temperature = G2IO.SelectPowderData(self, filename)              #Data: list of tuples (filename,Pos,Bank)
783                    if not Data:                                                    #if Data rejected by user - go to next one
784                        continue
785                    DataType = Iparm['INS   HTYPE ']                                #expect only 4 char string
786                    DataType = DataType.strip()[0:3]                                #just 1st 3 chars
787                    wx.BeginBusyCursor()
788                    Sample = G2pdG.SetDefaultSample()
789                    Sample['Temperature'] = Temperature
790                    try:
791                        for Item in Data:
792                            vals = Item[2].split()          #split up the BANK record
793                            Id = self.PatternTree.AppendItem(parent=self.root,text='PWDR '+ospath.basename(Item[0])+': '+vals[0]+vals[1])
794                            data = G2IO.GetPowderData(filename,Item[1],Item[2],DataType)
795                            self.PatternTree.SetItemPyData(Id,[Item,data])
796                            '''
797                            Each tree item data is a list with:
798                            Item: the (filename,Pos,Bank) tuple
799                            data: (x,y,w,yc,yb,yd) list  of np.arrays from GetPowderData
800                            '''
801                           
802                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)                           
803                            Tmin = min(data[0])
804                            Tmax = max(data[0])
805                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Limits'),[(Tmin,Tmax),[Tmin,Tmax]])
806                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',True,3,1.0,0.0,0.0],
807                                {'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]}])
808       
809                            data = [DataType,]
810                            if 'C' in DataType:
811                                s = Iparm['INS  1 ICONS']
812                                v = (G2IO.sfloat(s[:10]),G2IO.sfloat(s[10:20]),G2IO.sfloat(s[20:30]),G2IO.sfloat(s[55:65]),G2IO.sfloat(s[40:50])) #get lam1, lam2, zero, pola & ratio
813                                if not v[1]:
814                                    names = ['Type','Lam','Zero','Polariz.','U','V','W','X','Y','SH/L','Azimuth'] 
815                                    v = (v[0],v[2],v[4])
816                                    codes = [0,0,0,0]
817                                else:
818                                    names = ['Type','Lam1','Lam2','Zero','I(L2)/I(L1)','Polariz.','U','V','W','X','Y','SH/L','Azimuth']
819                                    codes = [0,0,0,0,0,0]
820                                data.extend(v)
821                                v1 = Iparm['INS  1PRCF1 '].split()                                                 
822                                v = Iparm['INS  1PRCF11'].split()
823                                data.extend([float(v[0]),float(v[1]),float(v[2])])                  #get GU, GV & GW - always here
824                                try:
825                                    azm = float(Iparm['INS  1DETAZM'])
826                                except KeyError:                                                #not in this Iparm file
827                                    azm = 0.0
828                                v = Iparm['INS  1PRCF12'].split()
829                                if v1[0] == 3:
830                                    data.extend([float(v[0]),float(v[1]),float(v[2])+float(v[3],azm)])  #get LX, LY, S+H/L & azimuth
831                                else:
832                                    data.extend([0.0,0.0,0.002,azm])                                      #OK defaults if fxn #3 not 1st in iprm file
833                                codes.extend([0,0,0,0,0,0,0])
834                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(data),data,codes,names])
835                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
836                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Peak List'),[])
837                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),[])
838                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])
839                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Reflection Lists'),{})             
840                            self.PatternId = G2gd.GetPatternTreeItemId(self,Id,'Limits')
841                    finally:
842                        wx.EndBusyCursor()
843                self.PatternTree.Expand(Id)
844                self.PatternTree.SelectItem(Id)
845   
846        finally:
847            dlg.Destroy()
848       
849    def OnReadPowderPeaks(self,event):
850        Cuka = 1.54052
851        self.CheckNotebook()
852        dlg = wx.FileDialog(self, 'Choose file with peak list', '.', '', 
853            'peak files (*.txt)|*.txt|All files (*.*)|*.*',wx.OPEN|wx.CHANGE_DIR)
854        try:
855            if dlg.ShowModal() == wx.ID_OK:
856                self.HKL = []
857                self.powderfile = dlg.GetPath()
858                comments,peaks = G2IO.GetPowderPeaks(self.powderfile)
859                Id = self.PatternTree.AppendItem(parent=self.root,text='PKS '+ospath.basename(self.powderfile))
860                data = ['PKS',Cuka,0.0]
861                names = ['Type','Lam','Zero'] 
862                codes = [0,0]
863                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(data),data,codes,names])
864                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),comments)
865                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),peaks)
866                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
867                self.PatternTree.Expand(Id)
868                self.PatternTree.SelectItem(Id)
869        finally:
870            dlg.Destroy()
871           
872    def OnImageRead(self,event):
873        self.CheckNotebook()
874        dlg = wx.FileDialog(self, 'Choose image files', '.', '',\
875        'Any image file (*.tif;*.tiff;*.mar*;*.avg;*.sum;*.img;*.G2img)\
876        |*.tif;*.tiff;*.mar*;*.avg;*.sum;*.img;*.G2img|\
877        Any detector tif (*.tif;*.tiff)|*.tif;*.tiff|\
878        MAR file (*.mar*)|*.mar*|\
879        GE Image (*.avg;*.sum)|*.avg;*.sum|\
880        ADSC Image (*.img)|*.img|\
881        GSAS-II Image (*.G2img)|*.G2img|\
882        All files (*.*)|*.*',
883        wx.OPEN | wx.MULTIPLE|wx.CHANGE_DIR)
884        try:
885            if dlg.ShowModal() == wx.ID_OK:
886                imagefiles = dlg.GetPaths()
887                imagefiles.sort()
888                for imagefile in imagefiles:
889                    Comments,Data,Npix,Image = G2IO.GetImageData(self,imagefile)
890                    if Comments:
891                        Id = self.PatternTree.AppendItem(parent=self.root,text='IMG '+ospath.basename(imagefile))
892                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)
893                        Imax = np.amax(Image)
894                        Imin = max(0.0,np.amin(Image))          #force positive
895                        if self.imageDefault:
896                            Data = copy.copy(self.imageDefault)
897                            Data['showLines'] = True
898                            Data['ring'] = []
899                            Data['rings'] = []
900                            Data['cutoff'] = 10
901                            Data['pixLimit'] = 20
902                            Data['edgemin'] = 100000000
903                            Data['calibdmin'] = 0.5
904                            Data['calibskip'] = 0
905                            Data['ellipses'] = []
906                            Data['calibrant'] = ''
907                        else:
908                            Data['type'] = 'PWDR'
909                            Data['color'] = 'Paired'
910                            Data['tilt'] = 0.0
911                            Data['rotation'] = 0.0
912                            Data['showLines'] = False
913                            Data['ring'] = []
914                            Data['rings'] = []
915                            Data['cutoff'] = 10
916                            Data['pixLimit'] = 20
917                            Data['calibdmin'] = 0.5
918                            Data['calibskip'] = 0
919                            Data['edgemin'] = 100000000
920                            Data['ellipses'] = []
921                            Data['calibrant'] = ''
922                            Data['IOtth'] = [2.0,5.0]
923                            Data['LRazimuth'] = [135,225]
924                            Data['azmthOff'] = 0.0
925                            Data['outChannels'] = 2500
926                            Data['outAzimuths'] = 1
927                            Data['centerAzm'] = False
928                            Data['fullIntegrate'] = False
929                            Data['setRings'] = False
930                            Data['background image'] = ['',1.0]                           
931                        Data['setDefault'] = False
932                        Data['range'] = [(Imin,Imax),[Imin,Imax]]
933                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Image Controls'),Data)
934                        Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
935                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Masks'),Masks)
936                        self.PatternTree.SetItemPyData(Id,[Npix,imagefile])
937                        self.PickId = Id
938                        self.Image = Id
939                self.PatternTree.SelectItem(G2gd.GetPatternTreeItemId(self,Id,'Image Controls'))             #show last one
940        finally:
941            dlg.Destroy()
942
943    # this will be removed eventually
944    def OnSnglRead(self,event):
945        self.CheckNotebook()
946        dlg = wx.FileDialog(self, 'Choose file', '.', '', 
947            'hkl files (*.hkl)|*.hkl|All files (*.*)|*.*', 
948            wx.OPEN|wx.CHANGE_DIR)
949        try:
950            if dlg.ShowModal() == wx.ID_OK:
951                filename = dlg.GetPath()
952                wx.BeginBusyCursor()
953                try:
954                    Data = {}
955                    names = ['Type','Lam']
956                    HKLref,HKLmin,HKLmax,FoMax,ifFc = G2IO.GetHKLData(filename)
957                    Id = self.PatternTree.AppendItem(parent=self.root,text='HKLF '+ospath.basename(filename))
958                    self.PatternTree.SetItemPyData(Id,HKLref)
959                    Sub = self.PatternTree.AppendItem(Id,text='Instrument Parameters')
960                    data = ['SXC',1.5428,]
961                    self.PatternTree.SetItemPyData(Sub,[tuple(data),data,names])
962                    Data['Type'] = 'Fosq'
963                    Data['ifFc'] = ifFc
964                    Data['HKLmax'] = HKLmax
965                    Data['HKLmin'] = HKLmin
966                    Data['FoMax'] = FoMax
967                    Data['Zone'] = '001'
968                    Data['Layer'] = 0
969                    Data['Scale'] = 1.0
970                    Data['log-lin'] = 'lin'                   
971                    self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='HKL Plot Controls'),Data)
972                    self.PatternTree.SelectItem(Id)
973                    self.PatternTree.Expand(Id)
974                    self.Sngl = Id
975                finally:
976                    wx.EndBusyCursor()   
977        finally:
978            dlg.Destroy()
979           
980    def CheckNotebook(self):
981        '''Make sure the data tree has the minimally expected controls
982        (BHT) correct?
983        '''
984        if not G2gd.GetPatternTreeItemId(self,self.root,'Notebook'):
985            sub = self.PatternTree.AppendItem(parent=self.root,text='Notebook')
986            self.PatternTree.SetItemPyData(sub,[''])
987        if not G2gd.GetPatternTreeItemId(self,self.root,'Controls'):
988            sub = self.PatternTree.AppendItem(parent=self.root,text='Controls')
989            self.PatternTree.SetItemPyData(sub,{})
990        if not G2gd.GetPatternTreeItemId(self,self.root,'Covariance'):
991            sub = self.PatternTree.AppendItem(parent=self.root,text='Covariance')
992            self.PatternTree.SetItemPyData(sub,{})
993        if not G2gd.GetPatternTreeItemId(self,self.root,'Constraints'):
994            sub = self.PatternTree.AppendItem(parent=self.root,text='Constraints')
995            self.PatternTree.SetItemPyData(sub,{'Hist':[],'HAP':[],'Phase':[]})
996        if not G2gd.GetPatternTreeItemId(self,self.root,'Restraints'):
997            sub = self.PatternTree.AppendItem(parent=self.root,text='Restraints')
998            self.PatternTree.SetItemPyData(sub,{})
999           
1000               
1001    class CopyDialog(wx.Dialog):
1002        def __init__(self,parent,title,text,data):
1003            wx.Dialog.__init__(self,parent,-1,title, 
1004                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
1005            self.data = data
1006            panel = wx.Panel(self)
1007            mainSizer = wx.BoxSizer(wx.VERTICAL)
1008            topLabl = wx.StaticText(panel,-1,text)
1009            mainSizer.Add((10,10),1)
1010            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
1011            mainSizer.Add((10,10),1)
1012            ncols = len(data)/40+1
1013            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=ncols,hgap=2,vgap=2)
1014            for id,item in enumerate(self.data):
1015                ckbox = wx.CheckBox(panel,id,item[1])
1016                ckbox.Bind(wx.EVT_CHECKBOX,self.OnCopyChange)                   
1017                dataGridSizer.Add(ckbox,0,wx.LEFT,10)
1018            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
1019            OkBtn = wx.Button(panel,-1,"Ok")
1020            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
1021            cancelBtn = wx.Button(panel,-1,"Cancel")
1022            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
1023            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
1024            btnSizer.Add((20,20),1)
1025            btnSizer.Add(OkBtn)
1026            btnSizer.Add((20,20),1)
1027            btnSizer.Add(cancelBtn)
1028            btnSizer.Add((20,20),1)
1029           
1030            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
1031            panel.SetSizer(mainSizer)
1032            panel.Fit()
1033            self.Fit()
1034       
1035        def OnCopyChange(self,event):
1036            id = event.GetId()
1037            self.data[id][0] = self.FindWindowById(id).GetValue()       
1038           
1039        def OnOk(self,event):
1040            parent = self.GetParent()
1041            parent.Raise()
1042            self.EndModal(wx.ID_OK)             
1043            self.Destroy()
1044           
1045        def OnCancel(self,event):
1046            parent = self.GetParent()
1047            parent.Raise()
1048            self.EndModal(wx.ID_CANCEL)             
1049            self.Destroy()
1050           
1051        def GetData(self):
1052            return self.data
1053       
1054    class SumDialog(wx.Dialog):
1055        def __init__(self,parent,title,text,dataType,data):
1056            wx.Dialog.__init__(self,parent,-1,title, 
1057                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
1058            self.data = data
1059            panel = wx.Panel(self)
1060            mainSizer = wx.BoxSizer(wx.VERTICAL)
1061            topLabl = wx.StaticText(panel,-1,text)
1062            mainSizer.Add((10,10),1)
1063            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
1064            mainSizer.Add((10,10),1)
1065            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=2,hgap=2,vgap=2)
1066            for id,item in enumerate(self.data[:-1]):
1067                name = wx.TextCtrl(panel,-1,item[1],size=wx.Size(200,20))
1068                name.SetEditable(False)
1069                scale = wx.TextCtrl(panel,id,'%.3f'%(item[0]),style=wx.TE_PROCESS_ENTER)
1070                scale.Bind(wx.EVT_TEXT_ENTER,self.OnScaleChange)
1071                scale.Bind(wx.EVT_KILL_FOCUS,self.OnScaleChange)
1072                dataGridSizer.Add(scale,0,wx.LEFT,10)
1073                dataGridSizer.Add(name,0,wx.RIGHT,10)
1074            if dataType:
1075                dataGridSizer.Add(wx.StaticText(panel,-1,'Sum result name: '+dataType),0, \
1076                    wx.LEFT|wx.TOP|wx.ALIGN_CENTER_VERTICAL,10)
1077                self.name = wx.TextCtrl(panel,-1,self.data[-1],size=wx.Size(200,20),style=wx.TE_PROCESS_ENTER)
1078                self.name.Bind(wx.EVT_TEXT_ENTER,self.OnNameChange)
1079                self.name.Bind(wx.EVT_KILL_FOCUS,self.OnNameChange)
1080                dataGridSizer.Add(self.name,0,wx.RIGHT|wx.TOP,10)
1081            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
1082            OkBtn = wx.Button(panel,-1,"Ok")
1083            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
1084            cancelBtn = wx.Button(panel,-1,"Cancel")
1085            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
1086            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
1087            btnSizer.Add((20,20),1)
1088            btnSizer.Add(OkBtn)
1089            btnSizer.Add((20,20),1)
1090            btnSizer.Add(cancelBtn)
1091            btnSizer.Add((20,20),1)
1092           
1093            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
1094            panel.SetSizer(mainSizer)
1095            panel.Fit()
1096            self.Fit()
1097
1098    class ConstraintDialog(wx.Dialog):
1099        '''Window to edit Constraint values
1100        '''
1101        def __init__(self,parent,title,text,data,separator='*'):
1102            wx.Dialog.__init__(self,parent,-1,title, 
1103                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
1104            self.data = data
1105            panel = wx.Panel(self)
1106            mainSizer = wx.BoxSizer(wx.VERTICAL)
1107            topLabl = wx.StaticText(panel,-1,text)
1108            mainSizer.Add((10,10),1)
1109            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
1110            mainSizer.Add((10,10),1)
1111            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=2,hgap=2,vgap=2)
1112            for id,item in enumerate(self.data[:-1]):
1113                lbl = item[1]
1114                if lbl[-1] != '=': lbl += ' ' + separator + ' '
1115                name = wx.StaticText(panel,-1,lbl,size=wx.Size(200,20),
1116                                     style=wx.ALIGN_RIGHT)
1117                scale = wx.TextCtrl(panel,id,'%.3f'%(item[0]),style=wx.TE_PROCESS_ENTER)
1118                scale.Bind(wx.EVT_TEXT_ENTER,self.OnScaleChange)
1119                scale.Bind(wx.EVT_KILL_FOCUS,self.OnScaleChange)
1120                dataGridSizer.Add(name,0,wx.LEFT,10)
1121                dataGridSizer.Add(scale,0,wx.RIGHT,10)
1122            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
1123            OkBtn = wx.Button(panel,-1,"Ok")
1124            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
1125            cancelBtn = wx.Button(panel,-1,"Cancel")
1126            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
1127            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
1128            btnSizer.Add((20,20),1)
1129            btnSizer.Add(OkBtn)
1130            btnSizer.Add((20,20),1)
1131            btnSizer.Add(cancelBtn)
1132            btnSizer.Add((20,20),1)
1133           
1134            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
1135            panel.SetSizer(mainSizer)
1136            panel.Fit()
1137            self.Fit()
1138            self.CenterOnParent()
1139           
1140        def OnNameChange(self,event):
1141            self.data[-1] = self.name.GetValue() 
1142           
1143        def OnScaleChange(self,event):
1144            id = event.GetId()
1145            value = self.FindWindowById(id).GetValue()
1146            try:
1147                self.data[id][0] = float(value)
1148                self.FindWindowById(id).SetValue('%.3f'%(self.data[id][0]))
1149            except ValueError:
1150                if value and '-' not in value[0]:
1151                    print 'bad input - numbers only'
1152                    self.FindWindowById(id).SetValue('0.000')
1153           
1154        def OnOk(self,event):
1155            parent = self.GetParent()
1156            parent.Raise()
1157            self.EndModal(wx.ID_OK)             
1158            #self.Destroy() -- do this later, after using GetData
1159           
1160        def OnCancel(self,event):
1161            parent = self.GetParent()
1162            parent.Raise()
1163            self.EndModal(wx.ID_CANCEL)             
1164            #self.Destroy()
1165           
1166        def GetData(self):
1167            return self.data
1168           
1169    def OnPwdrSum(self,event):
1170        TextList = []
1171        DataList = []
1172        SumList = []
1173        Names = []
1174        Inst = []
1175        SumItemList = []
1176        Comments = ['Sum equals: \n']
1177        if self.PatternTree.GetCount():
1178            item, cookie = self.PatternTree.GetFirstChild(self.root)
1179            while item:
1180                name = self.PatternTree.GetItemText(item)
1181                Names.append(name)
1182                if 'PWDR' in name:
1183                    TextList.append([0.0,name])
1184                    DataList.append(self.PatternTree.GetItemPyData(item)[1])    # (x,y,w,yc,yb,yd)
1185                    if not Inst:
1186                        Inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,item, 'Instrument Parameters'))
1187                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1188            if len(TextList) < 2:
1189                self.ErrorDialog('Not enough data to sum','There must be more than one "PWDR" pattern')
1190                return
1191            TextList.append('default_sum_name')               
1192            dlg = self.SumDialog(self,'Sum data','Enter scale for each pattern in summation','PWDR',TextList)
1193            try:
1194                if dlg.ShowModal() == wx.ID_OK:
1195                    lenX = 0
1196                    Xminmax = [0,0]
1197                    Xsum = []
1198                    Ysum = []
1199                    Vsum = []
1200                    result = dlg.GetData()
1201                    for i,item in enumerate(result[:-1]):
1202                        scale,name = item
1203                        data = DataList[i]
1204                        if scale:
1205                            Comments.append("%10.3f %s" % (scale,' * '+name))
1206                            x,y,w,yc,yb,yd = data   #numpy arrays!
1207                            v = 1./w
1208                            if lenX:
1209                                if lenX != len(x):
1210                                    self.ErrorDialog('Data length error','Data to be summed must have same number of points'+ \
1211                                        '\nExpected:'+str(lenX)+ \
1212                                        '\nFound:   '+str(len(x))+'\nfor '+name)
1213                                    return
1214                            else:
1215                                lenX = len(x)
1216                            if Xminmax[1]:
1217                                if Xminmax != [x[0],x[-1]]:
1218                                    self.ErrorDialog('Data range error','Data to be summed must span same range'+ \
1219                                        '\nExpected:'+str(Xminmax[0])+' '+str(Xminmax[1])+ \
1220                                        '\nFound:   '+str(x[0])+' '+str(x[-1])+'\nfor '+name)
1221                                    return
1222                                else:
1223                                    for j,yi in enumerate(y):
1224                                         Ysum[j] += scale*yi
1225                                         Vsum[j] += abs(scale)*v[j]
1226                            else:
1227                                Xminmax = [x[0],x[-1]]
1228                                YCsum = YBsum = YDsum = [0.0 for i in range(lenX)]
1229                                for j,yi in enumerate(y):
1230                                    Xsum.append(x[j])
1231                                    Ysum.append(scale*yi)
1232                                    Vsum.append(abs(scale*v[j]))
1233                    Wsum = 1./np.array(Vsum)
1234                    outname = 'PWDR '+result[-1]
1235                    Id = 0
1236                    if outname in Names:
1237                        dlg2 = wx.MessageDialog(self,'Overwrite data?','Duplicate data name',wx.OK|wx.CANCEL)
1238                        try:
1239                            if dlg2.ShowModal() == wx.ID_OK:
1240                                Id = G2gd.GetPatternTreeItemId(self,self.root,name)
1241                                self.PatternTree.Delete(Id)
1242                        finally:
1243                            dlg2.Destroy()
1244                    Id = self.PatternTree.AppendItem(parent=self.root,text=outname)
1245                    if Id:
1246                        Sample = G2pdG.SetDefaultSample()
1247                        self.PatternTree.SetItemPyData(Id,[[''],[np.array(Xsum),np.array(Ysum),np.array(Wsum),
1248                            np.array(YCsum),np.array(YBsum),np.array(YDsum)]])
1249                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)                   
1250                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Limits'),[tuple(Xminmax),Xminmax])
1251                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',True,3,1.0,0.0,0.0],
1252                            {'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]}])
1253                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),Inst)
1254                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
1255                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Peak List'),[])
1256                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),[])
1257                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
1258                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Reflection Lists'),{})             
1259                        self.PatternTree.SelectItem(Id)
1260                        self.PatternTree.Expand(Id)
1261                   
1262            finally:
1263                dlg.Destroy()
1264
1265    def OnImageSum(self,event):
1266        TextList = []
1267        DataList = []
1268        SumList = []
1269        Names = []
1270        Inst = []
1271        SumItemList = []
1272        Comments = ['Sum equals: \n']
1273        if self.PatternTree.GetCount():
1274            item, cookie = self.PatternTree.GetFirstChild(self.root)
1275            while item:
1276                name = self.PatternTree.GetItemText(item)
1277                Names.append(name)
1278                if 'IMG' in name:
1279                    TextList.append([0.0,name])
1280                    DataList.append(self.PatternTree.GetItemPyData(item))        #Size,Image
1281                    Data = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,item,'Image Controls'))
1282                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1283            if len(TextList) < 2:
1284                self.ErrorDialog('Not enough data to sum','There must be more than one "IMG" pattern')
1285                return
1286            TextList.append('default_sum_name')               
1287            dlg = self.SumDialog(self,'Sum data','Enter scale for each image in summation','IMG',TextList)
1288            try:
1289                if dlg.ShowModal() == wx.ID_OK:
1290                    imSize = 0
1291                    result = dlg.GetData()
1292                    First = True
1293                    Found = False
1294                    for i,item in enumerate(result[:-1]):
1295                        scale,name = item
1296                        data = DataList[i]
1297                        if scale:
1298                            Found = True                               
1299                            Comments.append("%10.3f %s" % (scale,' * '+name))
1300                            Npix,imagefile = data
1301                            image = G2IO.GetImageData(self,imagefile,imageOnly=True)
1302                            if First:
1303                                newImage = np.zeros_like(image)
1304                                First = False
1305                            if imSize:
1306                                if imSize != Npix:
1307                                    self.ErrorDialog('Image size error','Images to be summed must be same size'+ \
1308                                        '\nExpected:'+str(imSize)+ \
1309                                        '\nFound:   '+str(Npix)+'\nfor '+name)
1310                                    return
1311                                newImage = newImage+scale*image
1312                            else:
1313                                imSize = Npix
1314                                newImage = newImage+scale*image
1315                            del(image)
1316                    if not Found:
1317                        self.ErrorDialog('Image sum error','No nonzero image multipliers found')
1318                        return
1319                       
1320                    newImage = np.asfarray(newImage,dtype=np.float32)                       
1321                    outname = 'IMG '+result[-1]
1322                    Id = 0
1323                    if outname in Names:
1324                        dlg2 = wx.MessageDialog(self,'Overwrite data?','Duplicate data name',wx.OK|wx.CANCEL)
1325                        try:
1326                            if dlg2.ShowModal() == wx.ID_OK:
1327                                Id = G2gd.GetPatternTreeItemId(self,self.root,name)
1328                        finally:
1329                            dlg2.Destroy()
1330                    else:
1331                        Id = self.PatternTree.AppendItem(parent=self.root,text=outname)
1332                    if Id:
1333                        dlg = wx.FileDialog(self, 'Choose sum image filename', '.', '', 
1334                            'G2img files (*.G2img)|*.G2img', 
1335                            wx.SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1336                        if dlg.ShowModal() == wx.ID_OK:
1337                            newimagefile = dlg.GetPath()
1338                            newimagefile = G2IO.FileDlgFixExt(dlg,newimagefile)
1339                            G2IO.PutG2Image(newimagefile,Comments,Data,Npix,newImage)
1340                            Imax = np.amax(newImage)
1341                            Imin = np.amin(newImage)
1342                            newImage = []
1343                            self.PatternTree.SetItemPyData(Id,[imSize,newimagefile])
1344                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)
1345                        del(newImage)
1346                        if self.imageDefault:
1347                            Data = copy.copy(self.imageDefault)
1348                        Data['showLines'] = True
1349                        Data['ring'] = []
1350                        Data['rings'] = []
1351                        Data['cutoff'] = 10
1352                        Data['pixLimit'] = 20
1353                        Data['ellipses'] = []
1354                        Data['calibrant'] = ''
1355                        Data['range'] = [(Imin,Imax),[Imin,Imax]]
1356                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Image Controls'),Data)                                           
1357                        Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
1358                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Masks'),Masks)
1359                        self.PatternTree.SelectItem(Id)
1360                        self.PatternTree.Expand(Id)
1361                        self.PickId = G2gd.GetPatternTreeItemId(self,self.root,outname)
1362                        self.Image = self.PickId
1363            finally:
1364                dlg.Destroy()
1365                     
1366    def OnAddPhase(self,event):
1367        if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1368            sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1369        else:
1370            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1371        PhaseName = ''
1372        dlg = wx.TextEntryDialog(None,'Enter a name for this phase','Phase Name Entry','New phase',
1373            style=wx.OK)
1374        if dlg.ShowModal() == wx.ID_OK:
1375            PhaseName = dlg.GetValue()
1376        dlg.Destroy()
1377        sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1378        E,SGData = G2spc.SpcGroup('P 1')
1379        self.PatternTree.SetItemPyData(sub,G2IO.SetNewPhase(Name=PhaseName,SGData=SGData))
1380       
1381    def OnDeletePhase(self,event):
1382        #Hmm, also need to delete this phase from Reflection Lists for each PWDR histogram
1383        if self.dataFrame:
1384            self.dataFrame.Clear() 
1385        TextList = []
1386        DelList = []
1387        DelItemList = []
1388        if G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1389            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1390        else:
1391            return
1392        if sub:
1393            item, cookie = self.PatternTree.GetFirstChild(sub)
1394            while item:
1395                TextList.append(self.PatternTree.GetItemText(item))
1396                item, cookie = self.PatternTree.GetNextChild(sub, cookie)               
1397            dlg = wx.MultiChoiceDialog(self, 'Which phase to delete?', 'Delete phase', TextList, wx.CHOICEDLG_STYLE)
1398            try:
1399                if dlg.ShowModal() == wx.ID_OK:
1400                    result = dlg.GetSelections()
1401                    for i in result: DelList.append([i,TextList[i]])
1402                    item, cookie = self.PatternTree.GetFirstChild(sub)
1403                    i = 0
1404                    while item:
1405                        if [i,self.PatternTree.GetItemText(item)] in DelList: DelItemList.append(item)
1406                        item, cookie = self.PatternTree.GetNextChild(sub, cookie)
1407                        i += 1
1408                    for item in DelItemList:
1409                        name = self.PatternTree.GetItemText(item)
1410                        self.PatternTree.Delete(item)
1411                        self.G2plotNB.Delete(name)
1412                    item, cookie = self.PatternTree.GetFirstChild(self.root)
1413                    while item:
1414                        name = self.PatternTree.GetItemText(item)
1415                        if 'PWDR' in name:
1416                            Id = G2gd.GetPatternTreeItemId(self,item, 'Reflection Lists')
1417                            refList = self.PatternTree.GetItemPyData(Id)
1418                            for i,item in DelList:
1419                                del(refList[item])
1420                            self.PatternTree.SetItemPyData(Id,refList)
1421                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1422            finally:
1423                dlg.Destroy()
1424               
1425    def OnRenameData(self,event):
1426        name = self.PatternTree.GetItemText(self.PickId)     
1427        if 'PWDR' in name or 'HKLF' in name or 'IMG' in name:
1428            dataType = name[:name.index(' ')+1]                 #includes the ' '
1429            dlg = wx.TextEntryDialog(self,'Data name: '+dataType,'Change data name',
1430                defaultValue=name[name.index(' ')+1:])
1431            try:
1432                if dlg.ShowModal() == wx.ID_OK:
1433                    self.PatternTree.SetItemText(self.PickId,dataType+dlg.GetValue())
1434            finally:
1435                dlg.Destroy()
1436       
1437    def GetFileList(self,fileType,skip=None):        #potentially useful?
1438        fileList = []
1439        Source = ''
1440        id, cookie = self.PatternTree.GetFirstChild(self.root)
1441        while id:
1442            name = self.PatternTree.GetItemText(id)
1443            if fileType in name:
1444                if id == skip:
1445                    Source = name
1446                else:
1447                    fileList.append([False,name,id])
1448            id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1449        if skip:
1450            return fileList,Source
1451        else:
1452            return fileList
1453           
1454    def OnDataDelete(self, event):
1455        TextList = ['All Data']
1456        DelList = []
1457        DelItemList = []
1458        ifPWDR = False
1459        ifIMG = False
1460        ifHKLF = False
1461        ifPDF = False
1462        if self.PatternTree.GetCount():
1463            item, cookie = self.PatternTree.GetFirstChild(self.root)
1464            while item:
1465                name = self.PatternTree.GetItemText(item)
1466                if name not in ['Notebook','Controls','Covariance','Constraints','Restraints','Phases']:
1467                    if 'PWDR' in name: ifPWDR = True
1468                    if 'IMG' in name: ifIMG = True
1469                    if 'HKLF' in name: ifHKLF = True
1470                    if 'PDF' in name: ifPDF = True
1471                    TextList.append(name)
1472                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1473            if ifPWDR: TextList.insert(1,'All PWDR')
1474            if ifIMG: TextList.insert(1,'All IMG')
1475            if ifHKLF: TextList.insert(1,'All HKLF')
1476            if ifPDF: TextList.insert(1,'All PDF')               
1477            dlg = wx.MultiChoiceDialog(self, 'Which data to delete?', 'Delete data', TextList, wx.CHOICEDLG_STYLE)
1478            try:
1479                if dlg.ShowModal() == wx.ID_OK:
1480                    result = dlg.GetSelections()
1481                    for i in result: DelList.append(TextList[i])
1482                    if 'All Data' in DelList:
1483                        DelList = [item for item in TextList if item[:3] != 'All']
1484                    elif 'All PWDR' in DelList:
1485                        DelList = [item for item in TextList if item[:4] == 'PWDR']
1486                    elif 'All IMG' in DelList:
1487                        DelList = [item for item in TextList if item[:3] == 'IMG']
1488                    elif 'All HKLF' in DelList:
1489                        DelList = [item for item in TextList if item[:4] == 'HKLF']
1490                    elif 'All PDF' in DelList:
1491                        DelList = [item for item in TextList if item[:3] == 'PDF']
1492                    item, cookie = self.PatternTree.GetFirstChild(self.root)
1493                    while item:
1494                        if self.PatternTree.GetItemText(item) in DelList: DelItemList.append(item)
1495                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1496                    for item in DelItemList:
1497                        self.PatternTree.Delete(item)
1498                    G2plt.PlotPatterns(self,True)                        #so plot gets updated
1499            finally:
1500                dlg.Destroy()
1501
1502    def OnFileOpen(self, event):
1503        result = ''
1504        Id = 0
1505        if self.PatternTree.GetChildrenCount(self.root,False):
1506            if self.dataFrame:
1507                self.dataFrame.Clear() 
1508            dlg = wx.MessageDialog(self, 'Overwrite?','Project exists!',  wx.OK | wx.CANCEL)
1509            try:
1510                result = dlg.ShowModal()
1511                if result == wx.ID_OK:
1512                    self.PatternTree.DeleteChildren(self.root)
1513                    self.GSASprojectfile = ''
1514#                    self.PatternTree.DeleteChildren(self.root)
1515                    if self.HKL: self.HKL = []
1516                    if self.G2plotNB.plotList:
1517                        self.G2plotNB.clear()
1518            finally:
1519                dlg.Destroy()
1520        if result != wx.ID_CANCEL:   
1521            if self.dataDisplay: self.dataDisplay.Destroy()
1522            dlg = wx.FileDialog(self, 'Choose GSAS-II project file', '.', '', 
1523                'GSAS-II project file (*.gpx)|*.gpx',wx.OPEN|wx.CHANGE_DIR)
1524            try:
1525                if dlg.ShowModal() == wx.ID_OK:
1526                    self.GSASprojectfile = dlg.GetPath()
1527                    self.GSASprojectfile = G2IO.FileDlgFixExt(dlg,self.GSASprojectfile)
1528                    self.dirname = dlg.GetDirectory()
1529                    G2IO.ProjFileOpen(self)
1530                    self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
1531                    self.PatternTree.Expand(self.root)
1532                    self.HKL = []
1533                    item, cookie = self.PatternTree.GetFirstChild(self.root)
1534                    while item and not Id:
1535                        name = self.PatternTree.GetItemText(item)
1536                        if name[:4] in ['PWDR','HKLF','IMG ','PDF ']:
1537                            Id = item
1538                        elif name == 'Controls':
1539                            data = self.PatternTree.GetItemPyData(item)
1540                            if data:
1541                                self.Refine.Enable(True)
1542                                self.SeqRefine.Enable(True)
1543                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
1544                    if Id:
1545                        self.PatternTree.SelectItem(Id)
1546                    self.CheckNotebook()
1547            finally:
1548                dlg.Destroy()
1549
1550
1551    def OnFileClose(self, event):
1552        if self.dataFrame:
1553            self.dataFrame.Clear()
1554            self.dataFrame.SetLabel('GSAS-II data display') 
1555        dlg = wx.MessageDialog(self, 'Save current project?', ' ', wx.YES | wx.NO | wx.CANCEL)
1556        try:
1557            result = dlg.ShowModal()
1558            if result == wx.ID_OK:
1559                self.OnFileSaveMenu(event)
1560            if result != wx.ID_CANCEL:
1561                self.GSASprojectfile = ''
1562                self.PatternTree.SetItemText(self.root,'Loaded Data: ')
1563                self.PatternTree.DeleteChildren(self.root)
1564                if self.HKL: self.HKL = []
1565                if self.G2plotNB.plotList:
1566                    self.G2plotNB.clear()
1567        finally:
1568            dlg.Destroy()
1569
1570    def OnFileSave(self, event):
1571        if self.GSASprojectfile: 
1572            self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
1573            G2IO.ProjFileSave(self)
1574        else:
1575            self.OnFileSaveas(event)
1576
1577    def OnFileSaveas(self, event):
1578        dlg = wx.FileDialog(self, 'Choose GSAS-II project file name', '.', '', 
1579            'GSAS-II project file (*.gpx)|*.gpx',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1580        try:
1581            if dlg.ShowModal() == wx.ID_OK:
1582                self.GSASprojectfile = dlg.GetPath()
1583                self.GSASprojectfile = G2IO.FileDlgFixExt(dlg,self.GSASprojectfile)
1584                self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
1585                G2IO.ProjFileSave(self)
1586                self.dirname = dlg.GetDirectory()
1587        finally:
1588            dlg.Destroy()
1589
1590    def ExitMain(self, event):
1591        if self.undofile:
1592            os.remove(self.undofile)
1593        sys.exit()
1594       
1595    def OnFileExit(self, event):
1596        if self.dataFrame:
1597            self.dataFrame.Clear() 
1598            self.dataFrame.Destroy()
1599        self.Close()
1600       
1601    def OnImportPattern(self,event):
1602        dlg = wx.FileDialog(self, 'Choose nonGSAS powder file', '.', '', 
1603            '(*.*)|*.*',wx.OPEN|wx.CHANGE_DIR)
1604        try:
1605            if dlg.ShowModal() == wx.ID_OK:
1606                self.powderfile = dlg.GetPath()
1607        finally:
1608            dlg.Destroy()
1609           
1610    def OnImportHKL(self,event):
1611        dlg = wx.FileDialog(self, 'Choose structure factor file', '.', '', 
1612            '(*.*)|*.*',wx.OPEN|wx.CHANGE_DIR)
1613        try:
1614            if dlg.ShowModal() == wx.ID_OK:
1615                self.HKLfile = dlg.GetPath()
1616        finally:
1617            dlg.Destroy()
1618       
1619    def OnExportPatterns(self,event):
1620        names = ['All']
1621        exports = []
1622        item, cookie = self.PatternTree.GetFirstChild(self.root)
1623        while item:
1624            name = self.PatternTree.GetItemText(item)
1625            if 'PWDR' in name:
1626                names.append(name)
1627            item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1628        if names:
1629            dlg = wx.MultiChoiceDialog(self,'Select','Powder patterns to export',names)
1630            if dlg.ShowModal() == wx.ID_OK:
1631                sel = dlg.GetSelections()
1632                if sel[0] == 0:
1633                    exports = names[1:]
1634                else:
1635                    for x in sel:
1636                        exports.append(names[x])
1637            dlg.Destroy()
1638        if exports:
1639            dlg = wx.FileDialog(self, 'Choose output powder file name', '.', '', 
1640                'GSAS fxye file (*.fxye)|*.fxye|xye file (*.xye)|*.xye',
1641                wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1642            try:
1643                if dlg.ShowModal() == wx.ID_OK:
1644                    powderfile = dlg.GetPath()
1645                    powderfile = G2IO.FileDlgFixExt(dlg,powderfile)
1646                    if 'fxye' in powderfile:
1647                        G2IO.powderFxyeSave(self,exports,powderfile)
1648                    else:       #just xye
1649                        G2IO.powderXyeSave(self,exports,powderfile)
1650            finally:
1651                dlg.Destroy()
1652       
1653    def OnExportPeakList(self,event):
1654        dlg = wx.FileDialog(self, 'Choose output peak list file name', '.', '', 
1655            '(*.*)|*.*',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1656        try:
1657            if dlg.ShowModal() == wx.ID_OK:
1658                self.peaklistfile = dlg.GetPath()
1659                self.peaklistfile = G2IO.FileDlgFixExt(dlg,self.peaklistfile)
1660                file = open(self.peaklistfile,'w')               
1661                item, cookie = self.PatternTree.GetFirstChild(self.root)
1662                while item:
1663                    name = self.PatternTree.GetItemText(item)
1664                    if 'PWDR' in name:
1665                        item2, cookie2 = self.PatternTree.GetFirstChild(item)
1666                        while item2:
1667                            name2 = self.PatternTree.GetItemText(item2)
1668                            if name2 == 'Peak List':
1669                                peaks = self.PatternTree.GetItemPyData(item2)
1670                                file.write("%s \n" % (name+' Peak List'))               
1671                                for peak in peaks:
1672                                    file.write("%10.4f %12.2f %10.3f %10.3f \n" % \
1673                                        (peak[0],peak[2],peak[4],peak[6]))
1674                            item2, cookie2 = self.PatternTree.GetNextChild(item, cookie2)                           
1675                    item, cookie = self.PatternTree.GetNextChild(self.root, cookie)                           
1676                file.close()
1677        finally:
1678            dlg.Destroy()
1679       
1680    def OnExportHKL(self,event):
1681        event.Skip()
1682       
1683    def OnExportPDF(self,event):
1684        #need S(Q) and G(R) to be saved here - probably best from selection?
1685        names = ['All']
1686        exports = []
1687        item, cookie = self.PatternTree.GetFirstChild(self.root)
1688        while item:
1689            name = self.PatternTree.GetItemText(item)
1690            if 'PDF' in name:
1691                names.append(name)
1692            item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1693        if names:
1694            dlg = wx.MultiChoiceDialog(self,'Select','PDF patterns to export',names)
1695            if dlg.ShowModal() == wx.ID_OK:
1696                sel = dlg.GetSelections()
1697                if sel[0] == 0:
1698                    exports = names[1:]
1699                else:
1700                    for x in sel:
1701                        exports.append(names[x])
1702            dlg.Destroy()
1703        if exports:
1704            G2IO.PDFSave(self,exports)
1705       
1706    def OnExportPhase(self,event):
1707        event.Skip()
1708       
1709    def OnExportCIF(self,event):
1710        event.Skip()
1711
1712    def OnMakePDFs(self,event):
1713        tth2q = lambda t,w:4.0*math.pi*sind(t/2.0)/w
1714        TextList = ['All PWDR']
1715        PDFlist = []
1716        Names = []
1717        if self.PatternTree.GetCount():
1718            id, cookie = self.PatternTree.GetFirstChild(self.root)
1719            while id:
1720                name = self.PatternTree.GetItemText(id)
1721                Names.append(name)
1722                if 'PWDR' in name:
1723                    TextList.append(name)
1724                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1725            if len(TextList) == 1:
1726                self.ErrorDialog('Nothing to make PDFs for','There must be at least one "PWDR" pattern')
1727                return
1728            dlg = wx.MultiChoiceDialog(self,'Make PDF controls','Make PDF controls for:',TextList, wx.CHOICEDLG_STYLE)
1729            try:
1730                if dlg.ShowModal() == wx.ID_OK:
1731                    result = dlg.GetSelections()
1732                    for i in result: PDFlist.append(TextList[i])
1733                    if 0 in result:
1734                        PDFlist = [item for item in TextList if item[:4] == 'PWDR']                       
1735                    for item in PDFlist:
1736                        PWDRname = item[4:]
1737                        Id = self.PatternTree.AppendItem(parent=self.root,text='PDF '+PWDRname)
1738                        Data = {
1739                            'Sample':{'Name':item,'Mult':1.0,'Add':0.0},
1740                            'Sample Bkg.':{'Name':'','Mult':-1.0,'Add':0.0},
1741                            'Container':{'Name':'','Mult':-1.0,'Add':0.0},
1742                            'Container Bkg.':{'Name':'','Mult':-1.0,'Add':0.0},'ElList':{},
1743                            'Geometry':'Cylinder','Diam':1.0,'Pack':0.50,'Form Vol':10.0,
1744                            'DetType':'Image plate','ObliqCoeff':0.2,'Ruland':0.025,'QScaleLim':[0,100],
1745                            'Lorch':True,}
1746                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='PDF Controls'),Data)
1747                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='I(Q)'+PWDRname),[])       
1748                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='S(Q)'+PWDRname),[])       
1749                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='F(Q)'+PWDRname),[])       
1750                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='G(R)'+PWDRname),[])       
1751                self.ExportPDF.Enable(True)
1752            finally:
1753                dlg.Destroy()
1754               
1755    def GetPWDRdatafromTree(self,PWDRname):
1756        ''' Returns powder data from GSASII tree
1757        input:
1758            PWDRname = powder histogram name as obtained from GetHistogramNames
1759        return:
1760            PWDRdata = powder data dictionary with:
1761                Data - powder data arrays, Limits, Instrument Parameters, Sample Parameters           
1762        '''
1763        PWDRdata = {}
1764        PWDRdata['Data'] = self.PatternTree.GetItemPyData(PWDRname)[1]          #powder data arrays
1765        PWDRdata['Limits'] = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PWDRname,'Limits'))
1766        PWDRdata['Background'] = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PWDRname,'Background'))
1767        PWDRdata['Instrument Parameters'] = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PWDRname,'Instrument Parameters'))
1768        PWDRdata['Sample Parameters'] = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PWDRname,'Sample Parameters'))
1769        PWDRdata['Reflection Lists'] = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PWDRname,'Reflection Lists'))
1770        return PWDRdata
1771
1772    def GetHKLFdatafromTree(self,HKLFname):
1773        ''' Returns single crystal data from GSASII tree
1774        input:
1775            HKLFname = single crystal histogram name as obtained from GetHistogramNames
1776        return:
1777            HKLFdata = single crystal data list of reflections: for each reflection:
1778                HKLF = [np.array([h,k,l]),FoSq,sigFoSq,FcSq,Fcp,Fcpp,phase]
1779        '''
1780        HKLFdata = []
1781        while True:
1782            data = self.PatternTree.GetItemPyData(HKLFname)
1783            datum = data[0]
1784            if datum[0] == HKLFname:
1785                HKLFdata = datum[1:][0]
1786        return HKLFdata
1787                   
1788    def GetUsedHistogramsAndPhasesfromTree(self):
1789        ''' Returns all histograms that are found in any phase
1790        and any phase that uses a histogram
1791        return:
1792            Histograms = dictionary of histograms as {name:data,...}
1793            Phases = dictionary of phases that use histograms
1794        '''
1795        phaseData = {}
1796        if G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1797            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1798        else:
1799            print 'no phases to be refined'
1800            return
1801        if sub:
1802            item, cookie = self.PatternTree.GetFirstChild(sub)
1803            while item:
1804                phaseData[self.PatternTree.GetItemText(item)] =  self.PatternTree.GetItemPyData(item)               
1805                item, cookie = self.PatternTree.GetNextChild(sub, cookie)               
1806        Histograms = {}
1807        Phases = {}
1808        pId = 0
1809        hId = 0
1810        for phase in phaseData:
1811            Phase = phaseData[phase]
1812            if Phase['Histograms']:
1813                if phase not in Phases:
1814                    Phase['pId'] = pId
1815                    pId += 1
1816                    Phases[phase] = Phase
1817                for hist in Phase['Histograms']:
1818                    if hist not in Histograms:
1819                        item = G2gd.GetPatternTreeItemId(self,self.root,hist)
1820                        if 'PWDR' in hist[:4]: 
1821                            Histograms[hist] = self.GetPWDRdatafromTree(item)
1822                        elif 'HKLF' in hist[:4]:
1823                            Histograms[hist] = self.GetHKLFdatafromTree(item)
1824                        #future restraint, etc. histograms here           
1825                        Histograms[hist]['hId'] = hId
1826                        hId += 1
1827        return Histograms,Phases
1828       
1829    class ViewParmDialog(wx.Dialog):
1830        def __init__(self,parent,title,parmDict):
1831            wx.Dialog.__init__(self,parent,-1,title,size=(300,430),
1832                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
1833            panel = wx.Panel(self,size=(300,430))
1834            parmNames = parmDict.keys()
1835            parmNames.sort()
1836            parmText = ' p:h:Parameter       refine?              value\n'
1837            for name in parmNames:
1838                parmData = parmDict[name]
1839                try:
1840                    parmText += ' %s \t%12.4g \n'%(name.ljust(19)+'\t'+parmData[1],parmData[0])
1841                except TypeError:
1842                    pass
1843            parmTable = wx.TextCtrl(panel,-1,parmText,
1844                style=wx.TE_MULTILINE|wx.TE_READONLY,size=(290,400))
1845            mainSizer = wx.BoxSizer(wx.VERTICAL)
1846            mainSizer.Add(parmTable)
1847            panel.SetSizer(mainSizer)
1848                           
1849    def OnViewLSParms(self,event):
1850        parmDict = {}
1851        Histograms,Phases = self.GetUsedHistogramsAndPhasesfromTree()
1852        Natoms,phaseVary,phaseDict,pawleyLookup,FFtable,BLtable = G2str.GetPhaseData(Phases,Print=False)       
1853        hapVary,hapDict,controlDict = G2str.GetHistogramPhaseData(Phases,Histograms,Print=False)
1854        histVary,histDict,controlDict = G2str.GetHistogramData(Histograms,Print=False)
1855        varyList = phaseVary+hapVary+histVary
1856        parmDict.update(phaseDict)
1857        parmDict.update(hapDict)
1858        parmDict.update(histDict)
1859        for parm in parmDict:
1860            if parm.split(':')[-1] in ['Azimuth','Gonio. radius','Lam1','Lam2','Omega','Chi','Phi']:
1861                parmDict[parm] = [parmDict[parm],' ']
1862            elif parm.split(':')[-2] in ['Ax','Ay','Az','SHmodel','SHord']:
1863                parmDict[parm] = [parmDict[parm],' ']
1864            elif parm in varyList:
1865                parmDict[parm] = [parmDict[parm],'True']
1866            else:
1867                parmDict[parm] = [parmDict[parm],'False']
1868        parmDict[' Num refined'] = [len(varyList),'']
1869        dlg = self.ViewParmDialog(self,'Parameters for least squares',parmDict)
1870        try:
1871            if dlg.ShowModal() == wx.ID_OK:
1872                print 'do something with changes?? - No!'
1873        finally:
1874            dlg.Destroy()
1875       
1876    def OnRefine(self,event):
1877        self.OnFileSave(event)
1878        # check that constraints are OK here
1879        errmsg, warnmsg = G2str.CheckConstraints(self.GSASprojectfile)
1880        if errmsg:
1881            print('Error in constraints:\n'+errmsg+
1882                  '\nRefinement not possible')
1883            self.ErrorDialog('Constraint Error',
1884                             'Error in constraints:\n'+errmsg+
1885                             '\nRefinement not possible')
1886            return
1887        if warnmsg:
1888            print('Conflict between refinment flag settings and constraints:\n'+
1889                  warnmsg+'\nRefinement not possible')
1890            self.ErrorDialog('Refinement Flag Error',
1891                             'Conflict between refinment flag settings and constraints:\n'+
1892                             warnmsg+
1893                             '\nRefinement not possible')
1894            return
1895        #works - but it'd be better if it could restore plots
1896        dlg = wx.ProgressDialog('Residual','Powder profile Rwp =',101.0, 
1897            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT)
1898        screenSize = wx.ClientDisplayRect()
1899        Size = dlg.GetSize()
1900        Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x
1901        dlg.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
1902        dlg.SetSize(Size)
1903        Rwp = 100.00
1904        try:
1905            Rwp = G2str.Refine(self.GSASprojectfile,dlg)
1906        finally:
1907            dlg.Destroy()       
1908        dlg = wx.MessageDialog(self,'Load new result?','Refinement results, Rwp =%.3f'%(Rwp),wx.OK|wx.CANCEL)
1909        try:
1910            if dlg.ShowModal() == wx.ID_OK:
1911                Id = 0
1912                self.PatternTree.DeleteChildren(self.root)
1913                if self.HKL: self.HKL = []
1914                if self.G2plotNB.plotList:
1915                    self.G2plotNB.clear()
1916                G2IO.ProjFileOpen(self)
1917                item, cookie = self.PatternTree.GetFirstChild(self.root)
1918                while item and not Id:
1919                    name = self.PatternTree.GetItemText(item)
1920                    if name[:4] in ['PWDR','HKLF']:
1921                        Id = item
1922                    item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
1923                if Id:
1924                    self.PatternTree.SelectItem(Id)
1925        finally:
1926            dlg.Destroy()
1927
1928    def OnSeqRefine(self,event):
1929        Id = G2gd.GetPatternTreeItemId(self,self.root,'Sequental results')
1930        if not Id:
1931            Id = self.PatternTree.AppendItem(self.root,text='Sequental results')
1932            self.PatternTree.SetItemPyData(Id,{})           
1933        self.OnFileSave(event)
1934        # check that constraints are OK here
1935        errmsg, warnmsg = G2str.CheckConstraints(self.GSASprojectfile)
1936        if errmsg:
1937            print('Error in constraints:\n'+errmsg+
1938                  '\nRefinement not possible')
1939            self.ErrorDialog('Constraint Error',
1940                             'Error in constraints:\n'+errmsg+
1941                             '\nRefinement not possible')
1942            return
1943        if warnmsg:
1944            print('Conflict between refinment flag settings and constraints:\n'+
1945                  warnmsg+'\nRefinement not possible')
1946            self.ErrorDialog('Refinement Flag Error',
1947                             'Conflict between refinment flag settings and constraints:\n'+
1948                             warnmsg+'\nRefinement not possible')
1949            return
1950        dlg = wx.ProgressDialog('Residual for histogram 0','Powder profile Rwp =',101.0, 
1951            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT)
1952        screenSize = wx.ClientDisplayRect()
1953        Size = dlg.GetSize()
1954        Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x
1955        dlg.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
1956        dlg.SetSize(Size)
1957        try:
1958            G2str.SeqRefine(self.GSASprojectfile,dlg)
1959        finally:
1960            dlg.Destroy()       
1961        dlg = wx.MessageDialog(self,'Load new result?','Refinement results',wx.OK|wx.CANCEL)
1962        try:
1963            if dlg.ShowModal() == wx.ID_OK:
1964                Id = 0
1965                self.PatternTree.DeleteChildren(self.root)
1966                if self.HKL: self.HKL = []
1967                if self.G2plotNB.plotList:
1968                    self.G2plotNB.clear()
1969                G2IO.ProjFileOpen(self)
1970                item, cookie = self.PatternTree.GetFirstChild(self.root)
1971                while item and not Id:
1972                    name = self.PatternTree.GetItemText(item)
1973                    if name[:4] in ['PWDR','HKLF']:
1974                        Id = item
1975                    item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
1976                if Id:
1977                    self.PatternTree.SelectItem(Id)
1978        finally:
1979            dlg.Destroy()
1980       
1981    def ErrorDialog(self,title,message,parent=None, wtype=wx.OK):
1982        result = None
1983        if parent is None:
1984            dlg = wx.MessageDialog(self, message, title,  wtype)
1985        else:
1986            dlg = wx.MessageDialog(parent, message, title,  wtype)
1987            dlg.CenterOnParent() # not working on Mac
1988        try:
1989            result = dlg.ShowModal()
1990        finally:
1991            dlg.Destroy()
1992        return result
1993
1994class GSASIImain(wx.App):
1995    def OnInit(self):
1996        self.main = GSASII(None)
1997        self.main.Show()
1998        self.SetTopWindow(self.main)
1999        return True
2000
2001def main():
2002    application = GSASIImain(0)
2003    if wxInspector: wxeye.InspectionTool().Show()
2004
2005    #application.main.OnRefine(None)
2006    application.MainLoop()
2007   
2008if __name__ == '__main__':
2009    main()
Note: See TracBrowser for help on using the repository browser.