source: trunk/GSASII.py @ 536

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

add more text to help file
refactor image GUI stuff
add centerAzm option - azimuth ranges are for bin center vs edge

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