source: trunk/GSASII.py @ 537

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

some refactoring/rearrangement in GSASIIgrid.py
fixes to powderFxyeSave
move Fourier & map search math to GSASIImath.py
implement plot of map peaks & their move to atom list
begin charge flipping GUI

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