source: MPbranch/GSASIImain.py @ 612

Last change on this file since 612 was 507, checked in by toby, 13 years ago

fix function calc to allow for out of sequence finish of 'threads'; other minor fixes

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