source: trunk/GSASII.py @ 373

Last change on this file since 373 was 373, checked in by vondreele, 11 years ago

new covariance item in tree
new covariance matrix plotting
save cov matrix in file

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