source: trunk/GSASII.py @ 612

Last change on this file since 612 was 612, checked in by vondreele, 12 years ago

complete combined x/n exercise & fix bugs uncovered in process
made version 0.2.0
moved tutorials in help menu to be 2nd
fixed problem with drawing after f-map generated
fixed some plot errors
reverse sign on macrostrain

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