source: trunk/GSASII.py @ 492

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

delete obsolete/commented out code from import phase

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