source: trunk/GSASII.py @ 443

Last change on this file since 443 was 443, checked in by vondreele, 10 years ago

make sum powder profiles numpy arrays
change name UpdateBackgroundGrid? to UpdateBackground?
min size is 1 nanometer = 10A
implement diffuse scattering model for background
iso/aniso Size & Mustrain are now Size:i/a instead of 0/1

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