source: trunk/GSASII.py @ 456

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

determine path to GSAS files from file; trap & reset focus for tree traversal with arrow keys; move wxinspector to after app creation

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