source: trunk/GSASII.py @ 451

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