source: trunk/GSASII.py @ 523

Last change on this file since 523 was 523, checked in by toby, 10 years ago

fix plotting with as-inititalized values (oldxy & Fourier map); fix CIF import; fix command-line load; fix early Destroy in SumDialog?

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