source: trunk/GSASII.py @ 493

Last change on this file since 493 was 493, checked in by vondreele, 10 years ago

clean up help stuff - get OK respons from resize & now scrolls down a bit so text at top is seen.

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