source: trunk/GSASII.py @ 526

Last change on this file since 526 was 526, checked in by vondreele, 13 years ago

make SetNewPhase? routine in GSASIIIO.py to initialize phase info
begin Fourier map search routine
fix atom plotting if no map

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