source: MPbranch/GSASIImain.py @ 498

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