source: trunk/GSASII.py @ 541

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

openGL now looked for in pyGSASII first

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