source: trunk/GSASII.py @ 406

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

implement background subtraction during image integration
implement copy for instrument parms & background
continue constraint GUI development
make sure proper updates in refinement/seq refinement

  • Property svn:keywords set to Date Author Revision URL Id
File size: 77.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#GSASII
4########### SVN repository information ###################
5# $Date: 2011-11-02 18:11:04 +0000 (Wed, 02 Nov 2011) $
6# $Author: vondreele $
7# $Revision: 406 $
8# $URL: trunk/GSASII.py $
9# $Id: GSASII.py 406 2011-11-02 18:11:04Z vondreele $
10########### SVN repository information ###################
11
12import os
13import os.path as ospath
14import sys
15import math
16import cPickle
17import time
18import copy
19import numpy as np
20import scipy as sp
21import wx
22import matplotlib as mpl
23
24# load the GSAS routines
25import GSASIIpath
26import GSASIIIO as G2IO
27import GSASIIgrid as G2gd
28import GSASIIplot as G2plt
29import GSASIIpwdGUI as G2pdG
30import GSASIIspc as G2spc
31import GSASIIstruct as G2str
32import GSASIImapvars as G2mv
33import GSASIIsolve as G2sol
34import OpenGL as ogl
35
36# print versions
37print "Available python module versions for GSASII:"
38print "python:     ",sys.version[:5]
39print "wxpython:   ",wx.__version__
40print "matplotlib: ",mpl.__version__
41print "numpy:      ",np.__version__
42print "scipy:      ",sp.__version__
43print "OpenGL:     ",ogl.__version__
44try:
45    import mkl
46    print "Max threads ",mkl.get_max_threads()
47except:
48    print "MKL module not present"
49__version__ = '0.1.5'
50
51# useful degree trig functions
52sind = lambda x: math.sin(x*math.pi/180.)
53cosd = lambda x: math.cos(x*math.pi/180.)
54tand = lambda x: math.tan(x*math.pi/180.)
55asind = lambda x: 180.*math.asin(x)/math.pi
56acosd = lambda x: 180.*math.acos(x)/math.pi
57atan2d = lambda x,y: 180.*math.atan2(y,x)/math.pi
58
59def create(parent):
60    return GSASII(parent)
61
62[wxID_PATTERNTREE, 
63] = [wx.NewId() for _init_ctrls in range(1)]
64
65[wxID_FILECLOSE, wxID_FILEEXIT, wxID_FILEOPEN,  wxID_FILESAVE, wxID_FILESAVEAS, 
66wxID_REFINE, wxID_SOLVE, wxID_MAKEPDFS, wxID_VIEWLSPARMS, wxID_SEQREFINE,
67] = [wx.NewId() for _init_coll_File_Items in range(10)]
68
69[wxID_PWDRREAD,wxID_SNGLREAD,wxID_ADDPHASE,wxID_DELETEPHASE,
70 wxID_DATADELETE,wxID_READPEAKS,wxID_PWDSUM,wxID_IMGREAD,
71 wxID_IMSUM, wxID_DATARENAME,
72] = [wx.NewId() for _init_coll_Data_Items in range(10)]
73
74[wxID_IMPORT, wxID_IMPORTPATTERN, wxID_IMPORTHKL, wxID_IMPORTPHASE,
75wxID_IMPORTCIF, wxID_IMPORTPDB, 
76] = [wx.NewId() for _init_coll_Import_Items in range(6)]
77
78[wxID_EXPORT, wxID_EXPORTPATTERN, wxID_EXPORTHKL, wxID_EXPORTPHASE,
79wxID_EXPORTCIF, wxID_EXPORTPEAKLIST, wxID_EXPORTPDF,
80] = [wx.NewId() for _init_coll_Export_Items in range(7)]
81
82[wxID_HELPABOUT, wxID_HELPHELP, 
83] = [wx.NewId() for _init_coll_Help_Items in range(2)]
84
85class GSASII(wx.Frame):
86   
87    def _init_coll_GSASIIMenu_Menus(self, parent):
88        parent.Append(menu=self.File, title='File')
89        parent.Append(menu=self.Data, title='Data')
90        parent.Append(menu=self.Calculate, title='Calculate')
91        parent.Append(menu=self.Import, title='Import')
92        parent.Append(menu=self.Export, title='Export')
93        parent.Append(menu=self.Help, title='Help')
94
95    def _init_coll_File_Items(self, parent):
96        parent.Append(help='Open a gsasii project file (*.gpx)', id=wxID_FILEOPEN,
97             kind=wx.ITEM_NORMAL,text='Open project...')
98        parent.Append(help='Save project to old file', id=wxID_FILESAVE, 
99            kind=wx.ITEM_NORMAL,text='Save project')
100        parent.Append(help='Save project to new file', id=wxID_FILESAVEAS, 
101            kind=wx.ITEM_NORMAL,text='Save As...')
102        parent.Append(help='Close project, saving is optional', id=wxID_FILECLOSE, 
103            kind=wx.ITEM_NORMAL,text='Close project')
104        parent.Append(help='Exit from gsasii', id=wxID_FILEEXIT, kind=wx.ITEM_NORMAL,
105            text='Exit')
106        self.Bind(wx.EVT_MENU, self.OnFileOpen, id=wxID_FILEOPEN)
107        self.Bind(wx.EVT_MENU, self.OnFileSave, id=wxID_FILESAVE)
108        self.Bind(wx.EVT_MENU, self.OnFileSaveas, id=wxID_FILESAVEAS)
109        self.Bind(wx.EVT_MENU, self.OnFileClose, id=wxID_FILECLOSE)
110        self.Bind(wx.EVT_MENU, self.OnFileExit, id=wxID_FILEEXIT)
111       
112    def _init_coll_Data_Items(self,parent):
113        parent.Append(help='', id=wxID_PWDRREAD, kind=wx.ITEM_NORMAL,
114            text='Read powder data...')
115        parent.Append(help='',id=wxID_IMGREAD, kind=wx.ITEM_NORMAL,
116            text='Read image data...')
117        parent.Append(help='',id=wxID_READPEAKS, kind=wx.ITEM_NORMAL,
118            text='Read Powder Pattern Peaks...')
119        parent.Append(help='', id=wxID_SNGLREAD, kind=wx.ITEM_NORMAL,
120            text='Read single crystal data...')
121        parent.Append(help='', id=wxID_PWDSUM, kind=wx.ITEM_NORMAL,
122            text='Sum powder data')
123        parent.Append(help='',id=wxID_IMSUM, kind=wx.ITEM_NORMAL,
124            text='Sum image data')
125        parent.Append(help='', id=wxID_ADDPHASE, kind=wx.ITEM_NORMAL,
126            text='Add phase')
127        parent.Append(help='', id=wxID_DELETEPHASE, kind=wx.ITEM_NORMAL,
128            text='Delete phase')
129        parent.Append(help='', id=wxID_DATARENAME, kind=wx.ITEM_NORMAL,
130            text='Rename data') 
131        parent.Append(help='', id=wxID_DATADELETE, kind=wx.ITEM_NORMAL,
132            text='Delete data')
133        self.Bind(wx.EVT_MENU, self.OnPwdrRead, id=wxID_PWDRREAD)
134        self.Bind(wx.EVT_MENU, self.OnPwdrSum, id=wxID_PWDSUM)
135        self.Bind(wx.EVT_MENU, self.OnReadPowderPeaks, id=wxID_READPEAKS)
136        self.Bind(wx.EVT_MENU, self.OnImageRead, id=wxID_IMGREAD)
137        self.Bind(wx.EVT_MENU, self.OnImageSum, id=wxID_IMSUM)
138        self.Bind(wx.EVT_MENU, self.OnSnglRead, id=wxID_SNGLREAD)
139        self.Bind(wx.EVT_MENU, self.OnAddPhase, id=wxID_ADDPHASE)
140        self.Bind(wx.EVT_MENU, self.OnDeletePhase, id=wxID_DELETEPHASE)
141        self.Bind(wx.EVT_MENU, self.OnRenameData, id=wxID_DATARENAME)
142        self.Bind(wx.EVT_MENU, self.OnDataDelete, id=wxID_DATADELETE)
143               
144    def _init_coll_Calculate_Items(self,parent):
145        self.MakePDF = parent.Append(help='Make new PDFs from selected powder patterns', 
146            id=wxID_MAKEPDFS, kind=wx.ITEM_NORMAL,text='Make new PDFs')
147        self.Bind(wx.EVT_MENU, self.OnMakePDFs, id=wxID_MAKEPDFS)
148        self.ViewLSParms = parent.Append(help='View least squares parameters', 
149            id=wxID_VIEWLSPARMS, kind=wx.ITEM_NORMAL,text='View LS parms')
150        self.Bind(wx.EVT_MENU, self.OnViewLSParms, id=wxID_VIEWLSPARMS)
151        self.Refine = parent.Append(help='', id=wxID_REFINE, kind=wx.ITEM_NORMAL,
152            text='Refine')
153        self.Refine.Enable(False)
154        self.Bind(wx.EVT_MENU, self.OnRefine, id=wxID_REFINE)
155        self.SeqRefine = parent.Append(help='', id=wxID_SEQREFINE, kind=wx.ITEM_NORMAL,
156            text='Sequental refine')
157        self.SeqRefine.Enable(False)
158        self.Bind(wx.EVT_MENU, self.OnSeqRefine, id=wxID_SEQREFINE)
159        self.Solve = parent.Append(help='', id=wxID_SOLVE, kind=wx.ITEM_NORMAL,
160            text='Solve')
161        self.Solve.Enable(False)
162        self.Bind(wx.EVT_MENU, self.OnSolve, id=wxID_SOLVE)
163       
164    def _init_coll_Import_Items(self,parent):
165        self.ImportPhase = parent.Append(help='Import phase data from GSAS EXP file',
166            id=wxID_IMPORTPHASE, kind=wx.ITEM_NORMAL,text='Import GSAS EXP Phase...')
167        self.ImportPDB = parent.Append(help='Import phase data from PDB file',
168            id=wxID_IMPORTPDB, kind=wx.ITEM_NORMAL,text='Import PDB Phase...')
169        self.ImportCIF = parent.Append(help='Import phase data from cif file',id=wxID_IMPORTCIF, kind=wx.ITEM_NORMAL,
170            text='Import CIF Phase...')
171        self.ImportPattern = parent.Append(help='',id=wxID_IMPORTPATTERN, kind=wx.ITEM_NORMAL,
172            text='Import Powder Pattern...')
173        self.ImportHKL = parent.Append(help='',id=wxID_IMPORTHKL, kind=wx.ITEM_NORMAL,
174            text='Import HKLs...')
175        self.Bind(wx.EVT_MENU, self.OnImportPhase, id=wxID_IMPORTPHASE)
176        self.Bind(wx.EVT_MENU, self.OnImportPDB, id=wxID_IMPORTPDB)
177        self.Bind(wx.EVT_MENU, self.OnImportCIF, id=wxID_IMPORTCIF)
178        self.Bind(wx.EVT_MENU, self.OnImportPattern, id=wxID_IMPORTPATTERN)
179        self.Bind(wx.EVT_MENU, self.OnImportHKL, id=wxID_IMPORTHKL)
180
181    def _init_coll_Export_Items(self,parent):
182        self.ExportPattern = parent.Append(help='Select PWDR item to enable',id=wxID_EXPORTPATTERN, kind=wx.ITEM_NORMAL,
183            text='Export Powder Patterns...')
184        self.ExportPeakList = parent.Append(help='',id=wxID_EXPORTPEAKLIST, kind=wx.ITEM_NORMAL,
185            text='Export All Peak Lists...')
186        self.ExportHKL = parent.Append(help='',id=wxID_EXPORTHKL, kind=wx.ITEM_NORMAL,
187            text='Export HKLs...')
188        self.ExportPDF = parent.Append(help='Select PDF item to enable',id=wxID_EXPORTPDF, kind=wx.ITEM_NORMAL,
189            text='Export PDF...')
190        self.ExportPhase = parent.Append(help='',id=wxID_EXPORTPHASE, kind=wx.ITEM_NORMAL,
191            text='Export Phase...')
192        self.ExportCIF = parent.Append(help='',id=wxID_EXPORTCIF, kind=wx.ITEM_NORMAL,
193            text='Export CIF...')
194        self.ExportPattern.Enable(False)
195        self.ExportPeakList.Enable(True)
196        self.ExportHKL.Enable(False)
197        self.ExportPDF.Enable(False)
198        self.ExportPhase.Enable(False)
199        self.ExportCIF.Enable(False)
200        self.Bind(wx.EVT_MENU, self.OnExportPatterns, id=wxID_EXPORTPATTERN)
201        self.Bind(wx.EVT_MENU, self.OnExportPeakList, id=wxID_EXPORTPEAKLIST)
202        self.Bind(wx.EVT_MENU, self.OnExportHKL, id=wxID_EXPORTHKL)
203        self.Bind(wx.EVT_MENU, self.OnExportPDF, id=wxID_EXPORTPDF)
204        self.Bind(wx.EVT_MENU, self.OnExportPhase, id=wxID_EXPORTPHASE)
205        self.Bind(wx.EVT_MENU, self.OnExportCIF, id=wxID_EXPORTCIF)
206               
207    def _init_coll_Help_Items(self, parent):
208        parent.Append(help='', id=wxID_HELPHELP, kind=wx.ITEM_NORMAL,
209            text='Help')
210        parent.Append(help='', id=wxID_HELPABOUT, kind=wx.ITEM_NORMAL,
211            text='About')
212        self.Bind(wx.EVT_MENU, self.OnHelpHelp, id=wxID_HELPHELP)
213        self.Bind(wx.EVT_MENU, self.OnHelpAbout, id=wxID_HELPABOUT)
214
215    def _init_utils(self):
216        self.GSASIIMenu = wx.MenuBar()
217        self.File = wx.Menu(title='')
218        self.Data = wx.Menu(title='')       
219        self.Calculate = wx.Menu(title='')       
220        self.Import = wx.Menu(title='')       
221        self.Export = wx.Menu(title='')       
222        self.Help = wx.Menu(title='')
223
224        self._init_coll_GSASIIMenu_Menus(self.GSASIIMenu)
225        self._init_coll_File_Items(self.File)
226        self._init_coll_Data_Items(self.Data)
227        self._init_coll_Calculate_Items(self.Calculate)
228        self._init_coll_Import_Items(self.Import)
229        self._init_coll_Export_Items(self.Export)
230        self._init_coll_Help_Items(self.Help)
231       
232    def _init_ctrls(self, parent):
233        wx.Frame.__init__(self, name='GSASII', parent=parent,
234            size=wx.Size(300, 250),style=wx.DEFAULT_FRAME_STYLE, title='GSAS-II data tree')
235        clientSize = wx.ClientDisplayRect()
236        Size = self.GetSize()
237        xPos = clientSize[2]-Size[0]
238        self.SetPosition(wx.Point(xPos,clientSize[1]))
239        self._init_utils()
240        self.SetMenuBar(self.GSASIIMenu)
241        self.Bind(wx.EVT_SIZE, self.OnSize)
242        self.CreateStatusBar()
243        self.mainPanel = wx.Panel(self,-1)
244       
245        self.PatternTree = wx.TreeCtrl(id=wxID_PATTERNTREE,
246            parent=self.mainPanel, pos=wx.Point(0, 0),style=wx.TR_DEFAULT_STYLE )
247        self.PatternTree.Bind(wx.EVT_TREE_SEL_CHANGED,
248            self.OnPatternTreeSelChanged, id=wxID_PATTERNTREE)
249        self.PatternTree.Bind(wx.EVT_TREE_ITEM_COLLAPSED,
250            self.OnPatternTreeItemCollapsed, id=wxID_PATTERNTREE)
251        self.PatternTree.Bind(wx.EVT_TREE_ITEM_EXPANDED,
252            self.OnPatternTreeItemExpanded, id=wxID_PATTERNTREE)
253        self.PatternTree.Bind(wx.EVT_TREE_DELETE_ITEM,
254            self.OnPatternTreeItemDelete, id=wxID_PATTERNTREE)
255        self.root = self.PatternTree.AddRoot('Loaded Data: ')
256       
257        plotFrame = wx.Frame(None,-1,'GSASII Plots',size=wx.Size(700,600), \
258            style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX)
259        self.G2plotNB = G2plt.G2PlotNoteBook(plotFrame)
260        plotFrame.Show()
261       
262        self.dataDisplay = None
263       
264    def __init__(self, parent):
265        self._init_ctrls(parent)
266        self.Bind(wx.EVT_CLOSE, self.ExitMain)
267        # various defaults
268        self.GSASprojectfile = ''
269        self.dirname = ''
270        self.undofile = ''
271        self.TreeItemDelete = False
272        self.Offset = [0.0,0.0]
273        self.Weight = False
274        self.IparmName = ''
275        self.IfPlot = False
276        self.PatternId = 0
277        self.PickId = 0
278        self.PeakTable = []
279        self.LimitsTable = []
280        self.HKL = []
281        self.Lines = []
282        self.itemPicked = None
283        self.dataFrame = None
284        self.Interpolate = 'nearest'
285        self.ContourColor = 'Paired'
286        self.VcovColor = 'RdYlGn'
287        self.Projection = 'equal area'
288        self.logPlot = False
289        self.qPlot = False
290        self.Contour = False
291        self.Legend = False
292        self.SinglePlot = False
293        self.plotView = 0
294        self.Image = 0
295        self.oldImagefile = ''
296        self.Integrate = 0
297        self.Pwdr = False
298        self.imageDefault = {}
299        self.Sngl = 0
300        self.ifGetRing = False
301        self.setPoly = False
302        arg = sys.argv
303        if len(arg) > 1:
304            self.GSASprojectfile = arg[1]
305            self.dirname = ospath.dirname(arg[1])
306            G2IO.ProjFileOpen(self)
307            self.PatternTree.Expand(self.root)
308            self.Refine.Enable(True)
309            self.SeqRefine.Enable(True)
310            self.Solve.Enable(True)
311
312    def OnSize(self,event):
313        w,h = self.GetClientSizeTuple()
314        self.mainPanel.SetSize(wx.Size(w,h))
315        self.PatternTree.SetSize(wx.Size(w,h))
316                       
317    def OnPatternTreeSelChanged(self, event):
318        if self.TreeItemDelete:
319            self.TreeItemDelete = False
320        else:
321            pltNum = self.G2plotNB.nb.GetSelection()
322            if pltNum >= 0:                         #to avoid the startup with no plot!
323                pltPage = self.G2plotNB.nb.GetPage(pltNum)
324                pltPlot = pltPage.figure
325            item = event.GetItem()
326            G2gd.MovePatternTreeToGrid(self,item)
327       
328    def OnPatternTreeItemCollapsed(self, event):
329        event.Skip()
330
331    def OnPatternTreeItemExpanded(self, event):
332        event.Skip()
333       
334    def OnPatternTreeItemDelete(self, event):
335        self.TreeItemDelete = True
336
337    def OnPatternTreeItemActivated(self, event):
338        event.Skip()
339               
340    def OnPwdrRead(self, event):
341        self.CheckNotebook()
342        dlg = wx.FileDialog(self, 'Choose files', '.', '', 
343            'GSAS fxye files (*.fxye)|*.fxye|GSAS fxy files (*.fxy)|*.fxy|Topas xye files (*.xye)|*.xye|All files (*.*)|*.*', 
344            wx.OPEN | wx.MULTIPLE)
345        if self.dirname: dlg.SetDirectory(self.dirname)
346        try:
347            if dlg.ShowModal() == wx.ID_OK:
348                filenames = dlg.GetPaths()
349                filenames.sort()
350                self.dirname = dlg.GetDirectory()
351                for filename in filenames:
352                    Data,Iparm,Comments,Temperature = G2IO.SelectPowderData(self, filename)              #Data: list of tuples (filename,Pos,Bank)
353                    if not Data:                                                    #if Data rejected by user - go to next one
354                        continue
355                    DataType = Iparm['INS   HTYPE ']                                #expect only 4 char string
356                    DataType = DataType.strip()[0:3]                                #just 1st 3 chars
357                    wx.BeginBusyCursor()
358                    Sample = G2pdG.SetDefaultSample()
359                    Sample['Temperature'] = Temperature
360                    try:
361                        for Item in Data:
362                            vals = Item[2].split()          #split up the BANK record
363                            Id = self.PatternTree.AppendItem(parent=self.root,text='PWDR '+ospath.basename(Item[0])+': '+vals[0]+vals[1])
364                            data = G2IO.GetPowderData(filename,Item[1],Item[2],DataType)
365                            self.PatternTree.SetItemPyData(Id,[Item,data])
366                            '''
367                            Each tree item data is a list with:
368                            Item: the (filename,Pos,Bank) tuple
369                            data: (x,y,w,yc,yb,yd) list  of np.arrays from GetPowderData
370                            '''
371                           
372                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)                           
373                            Tmin = min(data[0])
374                            Tmax = max(data[0])
375                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Limits'),[(Tmin,Tmax),[Tmin,Tmax]])
376                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',1,3,1.0,0.0,0.0]])
377       
378                            data = [DataType,]
379                            if 'C' in DataType:
380                                s = Iparm['INS  1 ICONS']
381                                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
382                                if not v[1]:
383                                    names = ['Type','Lam','Zero','Polariz.','U','V','W','X','Y','SH/L','Azimuth'] 
384                                    v = (v[0],v[2],v[4])
385                                    codes = [0,0,0,0]
386                                else:
387                                    names = ['Type','Lam1','Lam2','Zero','I(L2)/I(L1)','Polariz.','U','V','W','X','Y','SH/L','Azimuth']
388                                    codes = [0,0,0,0,0,0]
389                                data.extend(v)
390                                v1 = Iparm['INS  1PRCF1 '].split()                                                 
391                                v = Iparm['INS  1PRCF11'].split()
392                                data.extend([float(v[0]),float(v[1]),float(v[2])])                  #get GU, GV & GW - always here
393                                try:
394                                    azm = float(Iparm['INS  1DETAZM'])
395                                except KeyError:                                                #not in this Iparm file
396                                    azm = 0.0
397                                v = Iparm['INS  1PRCF12'].split()
398                                if v1[0] == 3:
399                                    data.extend([float(v[0]),float(v[1]),float(v[2])+float(v[3],azm)])  #get LX, LY, S+H/L & azimuth
400                                else:
401                                    data.extend([0.0,0.0,0.002,azm])                                      #OK defaults if fxn #3 not 1st in iprm file
402                                codes.extend([0,0,0,0,0,0,0])
403                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(data),data,codes,names])
404                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
405                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Peak List'),[])
406                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),[])
407                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])
408                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Reflection Lists'),{})             
409                            self.PatternId = G2gd.GetPatternTreeItemId(self,Id,'Limits')
410                    finally:
411                        wx.EndBusyCursor()
412                self.PatternTree.Expand(Id)
413                self.PatternTree.SelectItem(Id)
414   
415        finally:
416            dlg.Destroy()
417       
418    def OnReadPowderPeaks(self,event):
419        Cuka = 1.54052
420        self.CheckNotebook()
421        dlg = wx.FileDialog(self, 'Choose file with peak list', '.', '', 
422            'peak files (*.txt)|*.txt|All files (*.*)|*.*',wx.OPEN)
423        if self.dirname:
424            dlg.SetDirectory(self.dirname)
425        try:
426            if dlg.ShowModal() == wx.ID_OK:
427                self.HKL = []
428                self.powderfile = dlg.GetPath()
429                self.dirname = dlg.GetDirectory()
430                comments,peaks = G2IO.GetPowderPeaks(self.powderfile)
431                Id = self.PatternTree.AppendItem(parent=self.root,text='PKS '+ospath.basename(self.powderfile))
432                data = ['PKS',Cuka,0.0]
433                names = ['Type','Lam','Zero'] 
434                codes = [0,0]
435                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(data),data,codes,names])
436                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),comments)
437                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),peaks)
438                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
439                self.PatternTree.Expand(Id)
440                self.PatternTree.SelectItem(Id)
441        finally:
442            dlg.Destroy()
443           
444    def OnImageRead(self,event):
445        self.CheckNotebook()
446        dlg = wx.FileDialog(self, 'Choose image files', '.', '',\
447        'Any image file (*.tif;*.tiff;*.mar*;*.avg;*.sum;*.img;*.G2img)\
448        |*.tif;*.tiff;*.mar*;*.avg;*.sum;*.img;*.G2img|\
449        Any detector tif (*.tif;*.tiff)|*.tif;*.tiff|\
450        MAR file (*.mar*)|*.mar*|\
451        GE Image (*.avg;*.sum)|*.avg;*.sum|\
452        ADSC Image (*.img)|*.img|\
453        GSAS-II Image (*.G2img)|*.G2img|\
454        All files (*.*)|*.*',
455        wx.OPEN | wx.MULTIPLE)
456        if self.dirname:
457            dlg.SetDirectory(self.dirname)
458        try:
459            if dlg.ShowModal() == wx.ID_OK:
460                self.dirname = dlg.GetDirectory()
461                imagefiles = dlg.GetPaths()
462                imagefiles.sort()
463                for imagefile in imagefiles:
464                    Comments,Data,Npix,Image = G2IO.GetImageData(self,imagefile)
465                    if Comments:
466                        Id = self.PatternTree.AppendItem(parent=self.root,text='IMG '+ospath.basename(imagefile))
467                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)
468                        Imax = np.amax(Image)
469                        Imin = max(0.0,np.amin(Image))          #force positive
470                        if self.imageDefault:
471                            Data = copy.copy(self.imageDefault)
472                            Data['showLines'] = True
473                            Data['ring'] = []
474                            Data['rings'] = []
475                            Data['cutoff'] = 10
476                            Data['pixLimit'] = 20
477                            Data['edgemin'] = 100000000
478                            Data['calibdmin'] = 0.5
479                            Data['calibskip'] = 0
480                            Data['ellipses'] = []
481                            Data['calibrant'] = ''
482                        else:
483                            Data['type'] = 'PWDR'
484                            Data['color'] = 'binary'
485                            Data['tilt'] = 0.0
486                            Data['rotation'] = 0.0
487                            Data['showLines'] = False
488                            Data['ring'] = []
489                            Data['rings'] = []
490                            Data['cutoff'] = 10
491                            Data['pixLimit'] = 20
492                            Data['calibdmin'] = 0.5
493                            Data['calibskip'] = 0
494                            Data['edgemin'] = 100000000
495                            Data['ellipses'] = []
496                            Data['calibrant'] = ''
497                            Data['IOtth'] = [2.0,5.0]
498                            Data['LRazimuth'] = [-135,-45]
499                            Data['azmthOff'] = 0.0
500                            Data['outChannels'] = 2500
501                            Data['outAzimuths'] = 1
502                            Data['fullIntegrate'] = False
503                            Data['setRings'] = False
504                            Data['background image'] = ['',1.0]                           
505                        Data['setDefault'] = False
506                        Data['range'] = [(Imin,Imax),[Imin,Imax]]
507                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Image Controls'),Data)
508                        Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
509                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Masks'),Masks)
510                        self.PatternTree.SetItemPyData(Id,[Npix,imagefile])
511                        self.PickId = Id
512                        self.Image = Id
513                self.PatternTree.SelectItem(G2gd.GetPatternTreeItemId(self,Id,'Image Controls'))             #show last one
514        finally:
515            dlg.Destroy()
516       
517    def OnSnglRead(self,event):
518        self.CheckNotebook()
519        dlg = wx.FileDialog(self, 'Choose file', '.', '', 
520            'hkl files (*.hkl)|*.hkl|All files (*.*)|*.*', 
521            wx.OPEN)
522        if self.dirname: dlg.SetDirectory(self.dirname)
523        try:
524            if dlg.ShowModal() == wx.ID_OK:
525                filename = dlg.GetPath()
526                self.dirname = dlg.GetDirectory()
527                wx.BeginBusyCursor()
528                try:
529                    Data = {}
530                    names = ['Type','Lam']
531                    HKLref,HKLmin,HKLmax,FoMax,ifFc = G2IO.GetHKLData(filename)
532                    Id = self.PatternTree.AppendItem(parent=self.root,text='HKLF '+ospath.basename(filename))
533                    self.PatternTree.SetItemPyData(Id,HKLref)
534                    Sub = self.PatternTree.AppendItem(Id,text='Instrument Parameters')
535                    data = ['SXC',1.5428,]
536                    self.PatternTree.SetItemPyData(Sub,[tuple(data),data,names])
537                    Data['Type'] = 'Fosq'
538                    Data['ifFc'] = ifFc
539                    Data['HKLmax'] = HKLmax
540                    Data['HKLmin'] = HKLmin
541                    Data['FoMax'] = FoMax
542                    Data['Zone'] = '001'
543                    Data['Layer'] = 0
544                    Data['Scale'] = 1.0
545                    Data['log-lin'] = 'lin'                   
546                    self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='HKL Plot Controls'),Data)
547                    self.PatternTree.SelectItem(Id)
548                    self.PatternTree.Expand(Id)
549                    self.Sngl = Id
550                finally:
551                    wx.EndBusyCursor()   
552        finally:
553            dlg.Destroy()
554           
555    def CheckNotebook(self):
556        if not G2gd.GetPatternTreeItemId(self,self.root,'Notebook'):
557            sub = self.PatternTree.AppendItem(parent=self.root,text='Notebook')
558            self.PatternTree.SetItemPyData(sub,[''])
559        if not G2gd.GetPatternTreeItemId(self,self.root,'Controls'):
560            sub = self.PatternTree.AppendItem(parent=self.root,text='Controls')
561            self.PatternTree.SetItemPyData(sub,{})
562        if not G2gd.GetPatternTreeItemId(self,self.root,'Covariance'):
563            sub = self.PatternTree.AppendItem(parent=self.root,text='Covariance')
564            self.PatternTree.SetItemPyData(sub,{})
565        if not G2gd.GetPatternTreeItemId(self,self.root,'Constraints'):
566            sub = self.PatternTree.AppendItem(parent=self.root,text='Constraints')
567            self.PatternTree.SetItemPyData(sub,{'Hist':[],'HAP':[],'Phase':[]})
568        if not G2gd.GetPatternTreeItemId(self,self.root,'Restraints'):
569            sub = self.PatternTree.AppendItem(parent=self.root,text='Restraints')
570            self.PatternTree.SetItemPyData(sub,{})
571           
572               
573    class CopyDialog(wx.Dialog):
574        def __init__(self,parent,title,text,data):
575            wx.Dialog.__init__(self,parent,-1,title, 
576                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
577            self.data = data
578            panel = wx.Panel(self)
579            mainSizer = wx.BoxSizer(wx.VERTICAL)
580            topLabl = wx.StaticText(panel,-1,text)
581            mainSizer.Add((10,10),1)
582            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
583            mainSizer.Add((10,10),1)
584            ncols = len(data)/40+1
585            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=ncols,hgap=2,vgap=2)
586            for id,item in enumerate(self.data):
587                ckbox = wx.CheckBox(panel,id,item[1])
588                ckbox.Bind(wx.EVT_CHECKBOX,self.OnCopyChange)                   
589                dataGridSizer.Add(ckbox,0,wx.LEFT,10)
590            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
591            OkBtn = wx.Button(panel,-1,"Ok")
592            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
593            cancelBtn = wx.Button(panel,-1,"Cancel")
594            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
595            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
596            btnSizer.Add((20,20),1)
597            btnSizer.Add(OkBtn)
598            btnSizer.Add((20,20),1)
599            btnSizer.Add(cancelBtn)
600            btnSizer.Add((20,20),1)
601           
602            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
603            panel.SetSizer(mainSizer)
604            panel.Fit()
605            self.Fit()
606       
607        def OnCopyChange(self,event):
608            id = event.GetId()
609            self.data[id][0] = self.FindWindowById(id).GetValue()       
610           
611        def OnOk(self,event):
612            parent = self.GetParent()
613            parent.Raise()
614            self.EndModal(wx.ID_OK)             
615            self.Destroy()
616           
617        def OnCancel(self,event):
618            parent = self.GetParent()
619            parent.Raise()
620            self.EndModal(wx.ID_CANCEL)             
621            self.Destroy()
622           
623        def GetData(self):
624            return self.data
625       
626    class SumDialog(wx.Dialog):
627        def __init__(self,parent,title,text,dataType,data):
628            wx.Dialog.__init__(self,parent,-1,title, 
629                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
630            self.data = data
631            panel = wx.Panel(self)
632            mainSizer = wx.BoxSizer(wx.VERTICAL)
633            topLabl = wx.StaticText(panel,-1,text)
634            mainSizer.Add((10,10),1)
635            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
636            mainSizer.Add((10,10),1)
637            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=2,hgap=2,vgap=2)
638            for id,item in enumerate(self.data[:-1]):
639                name = wx.TextCtrl(panel,-1,item[1],size=wx.Size(200,20))
640                name.SetEditable(False)
641                scale = wx.TextCtrl(panel,id,str(item[0]),style=wx.TE_PROCESS_ENTER)
642                scale.Bind(wx.EVT_TEXT_ENTER,self.OnScaleChange)
643                scale.Bind(wx.EVT_KILL_FOCUS,self.OnScaleChange)
644                dataGridSizer.Add(scale,0,wx.LEFT,10)
645                dataGridSizer.Add(name,0,wx.RIGHT,10)
646            if dataType:
647                dataGridSizer.Add(wx.StaticText(panel,-1,'Sum result name: '+dataType),0, \
648                    wx.LEFT|wx.TOP|wx.ALIGN_CENTER_VERTICAL,10)
649                self.name = wx.TextCtrl(panel,-1,self.data[-1],size=wx.Size(200,20),style=wx.TE_PROCESS_ENTER)
650                self.name.Bind(wx.EVT_TEXT_ENTER,self.OnNameChange)
651                self.name.Bind(wx.EVT_KILL_FOCUS,self.OnNameChange)
652                dataGridSizer.Add(self.name,0,wx.RIGHT|wx.TOP,10)
653            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
654            OkBtn = wx.Button(panel,-1,"Ok")
655            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
656            cancelBtn = wx.Button(panel,-1,"Cancel")
657            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
658            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
659            btnSizer.Add((20,20),1)
660            btnSizer.Add(OkBtn)
661            btnSizer.Add((20,20),1)
662            btnSizer.Add(cancelBtn)
663            btnSizer.Add((20,20),1)
664           
665            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
666            panel.SetSizer(mainSizer)
667            panel.Fit()
668            self.Fit()
669           
670        def OnNameChange(self,event):
671            self.data[-1] = self.name.GetValue() 
672           
673        def OnScaleChange(self,event):
674            id = event.GetId()
675            value = self.FindWindowById(id).GetValue()
676            try:
677                self.data[id][0] = float(value)
678                self.FindWindowById(id).SetValue('%.3f'%(self.data[id][0]))
679            except ValueError:
680                if value and '-' not in value[0]:
681                    print 'bad input - numbers only'
682                    self.FindWindowById(id).SetValue('0.0')
683           
684        def OnOk(self,event):
685            parent = self.GetParent()
686            parent.Raise()
687            self.EndModal(wx.ID_OK)             
688            self.Destroy()
689           
690        def OnCancel(self,event):
691            parent = self.GetParent()
692            parent.Raise()
693            self.EndModal(wx.ID_CANCEL)             
694            self.Destroy()
695           
696        def GetData(self):
697            return self.data
698           
699    def OnPwdrSum(self,event):
700        TextList = []
701        DataList = []
702        SumList = []
703        Names = []
704        Inst = []
705        SumItemList = []
706        Comments = ['Sum equals: \n']
707        if self.PatternTree.GetCount():
708            item, cookie = self.PatternTree.GetFirstChild(self.root)
709            while item:
710                name = self.PatternTree.GetItemText(item)
711                Names.append(name)
712                if 'PWDR' in name:
713                    TextList.append([0.0,name])
714                    DataList.append(self.PatternTree.GetItemPyData(item)[1])    # (x,y,w,yc,yb,yd)
715                    if not Inst:
716                        Inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,item, 'Instrument Parameters'))
717                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
718            if len(TextList) < 2:
719                self.ErrorDialog('Not enough data to sum','There must be more than one "PWDR" pattern')
720                return
721            TextList.append('default_sum_name')               
722            dlg = self.SumDialog(self,'Sum data','Enter scale for each pattern in summation','PWDR',TextList)
723            try:
724                if dlg.ShowModal() == wx.ID_OK:
725                    lenX = 0
726                    Xminmax = [0,0]
727                    Xsum = []
728                    Ysum = []
729                    Vsum = []
730                    result = dlg.GetData()
731                    for i,item in enumerate(result[:-1]):
732                        scale,name = item
733                        data = DataList[i]
734                        if scale:
735                            Comments.append("%10.3f %s" % (scale,' * '+name))
736                            x,y,w,yc,yb,yd = data
737                            v = 1./w
738                            if lenX:
739                                if lenX != len(x):
740                                    self.ErrorDialog('Data length error','Data to be summed must have same number of points'+ \
741                                        '\nExpected:'+str(lenX)+ \
742                                        '\nFound:   '+str(len(x))+'\nfor '+name)
743                                    return
744                            else:
745                                lenX = len(x)
746                            if Xminmax[1]:
747                                if Xminmax != [x[0],x[-1]]:
748                                    self.ErrorDialog('Data range error','Data to be summed must span same range'+ \
749                                        '\nExpected:'+str(Xminmax[0])+' '+str(Xminmax[1])+ \
750                                        '\nFound:   '+str(x[0])+' '+str(x[-1])+'\nfor '+name)
751                                    return
752                                else:
753                                    for j,yi in enumerate(y):
754                                         Ysum[j] += scale*yi
755                                         Vsum[j] += abs(scale)*v[j]
756                            else:
757                                Xminmax = [x[0],x[-1]]
758                                YCsum = YBsum = YDsum = [0.0 for i in range(lenX)]
759                                for j,yi in enumerate(y):
760                                    Xsum.append(x[j])
761                                    Ysum.append(scale*yi)
762                                    Vsum.append(abs(scale*v[j]))
763                    Wsum = 1./np.array(Vsum)
764                    outname = 'PWDR '+result[-1]
765                    Id = 0
766                    if outname in Names:
767                        dlg2 = wx.MessageDialog(self,'Overwrite data?','Duplicate data name',wx.OK|wx.CANCEL)
768                        try:
769                            if dlg2.ShowModal() == wx.ID_OK:
770                                Id = G2gd.GetPatternTreeItemId(self,self.root,name)
771                                self.PatternTree.Delete(Id)
772                        finally:
773                            dlg2.Destroy()
774                    Id = self.PatternTree.AppendItem(parent=self.root,text=outname)
775                    if Id:
776                        Sample = G2pdG.SetDefaultSample()
777                        self.PatternTree.SetItemPyData(Id,[[''],[Xsum,Ysum,Wsum,YCsum,YBsum,YDsum]])
778                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)                   
779                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Limits'),[tuple(Xminmax),Xminmax])
780                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',1,3,1.0,0.0,0.0]])
781                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),Inst)
782                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
783                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Peak List'),[])
784                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),[])
785                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
786                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Reflection Lists'),{})             
787                        self.PatternTree.SelectItem(Id)
788                        self.PatternTree.Expand(Id)
789                   
790            finally:
791                dlg.Destroy()
792
793    def OnImageSum(self,event):
794        TextList = []
795        DataList = []
796        SumList = []
797        Names = []
798        Inst = []
799        SumItemList = []
800        Comments = ['Sum equals: \n']
801        if self.PatternTree.GetCount():
802            item, cookie = self.PatternTree.GetFirstChild(self.root)
803            while item:
804                name = self.PatternTree.GetItemText(item)
805                Names.append(name)
806                if 'IMG' in name:
807                    TextList.append([0.0,name])
808                    DataList.append(self.PatternTree.GetItemPyData(item))        #Size,Image
809                    Data = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,item,'Image Controls'))
810                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
811            if len(TextList) < 2:
812                self.ErrorDialog('Not enough data to sum','There must be more than one "IMG" pattern')
813                return
814            TextList.append('default_sum_name')               
815            dlg = self.SumDialog(self,'Sum data','Enter scale for each image in summation','IMG',TextList)
816            try:
817                if dlg.ShowModal() == wx.ID_OK:
818                    imSize = 0
819                    result = dlg.GetData()
820                    First = True
821                    Found = False
822                    for i,item in enumerate(result[:-1]):
823                        scale,name = item
824                        data = DataList[i]
825                        if scale:
826                            Found = True                               
827                            Comments.append("%10.3f %s" % (scale,' * '+name))
828                            Npix,imagefile = data
829                            image = G2IO.GetImageData(self,imagefile,imageOnly=True)
830                            if First:
831                                newImage = np.zeros_like(image)
832                                First = False
833                            if imSize:
834                                if imSize != Npix:
835                                    self.ErrorDialog('Image size error','Images to be summed must be same size'+ \
836                                        '\nExpected:'+str(imSize)+ \
837                                        '\nFound:   '+str(Npix)+'\nfor '+name)
838                                    return
839                                newImage = newImage+scale*image
840                            else:
841                                imSize = Npix
842                                newImage = newImage+scale*image
843                            del(image)
844                    if not Found:
845                        self.ErrorDialog('Image sum error','No nonzero image multipliers found')
846                        return
847                       
848                    newImage = np.asfarray(newImage,dtype=np.float32)                       
849                    outname = 'IMG '+result[-1]
850                    Id = 0
851                    if outname in Names:
852                        dlg2 = wx.MessageDialog(self,'Overwrite data?','Duplicate data name',wx.OK|wx.CANCEL)
853                        try:
854                            if dlg2.ShowModal() == wx.ID_OK:
855                                Id = G2gd.GetPatternTreeItemId(self,self.root,name)
856                        finally:
857                            dlg2.Destroy()
858                    else:
859                        Id = self.PatternTree.AppendItem(parent=self.root,text=outname)
860                    if Id:
861                        dlg = wx.FileDialog(self, 'Choose sum image filename', '.', '', 
862                            'G2img files (*.G2img)|*.G2img', 
863                            wx.SAVE|wx.FD_OVERWRITE_PROMPT)
864                        if self.dirname: dlg.SetDirectory(self.dirname)
865                        if dlg.ShowModal() == wx.ID_OK:
866                            self.dirname = dlg.GetDirectory()
867                            newimagefile = dlg.GetPath()
868                            G2IO.PutG2Image(newimagefile,Comments,Data,Npix,newImage)
869                            Imax = np.amax(newImage)
870                            Imin = np.amin(newImage)
871                            newImage = []
872                            self.PatternTree.SetItemPyData(Id,[imSize,newimagefile])
873                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)
874                        del(newImage)
875                        if self.imageDefault:
876                            Data = copy.copy(self.imageDefault)
877                        Data['showLines'] = True
878                        Data['ring'] = []
879                        Data['rings'] = []
880                        Data['cutoff'] = 10
881                        Data['pixLimit'] = 20
882                        Data['ellipses'] = []
883                        Data['calibrant'] = ''
884                        Data['range'] = [(Imin,Imax),[Imin,Imax]]
885                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Image Controls'),Data)                                           
886                        Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
887                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Masks'),Masks)
888                        self.PatternTree.SelectItem(Id)
889                        self.PatternTree.Expand(Id)
890                        self.PickId = G2gd.GetPatternTreeItemId(self,self.root,outname)
891                        self.Image = self.PickId
892            finally:
893                dlg.Destroy()
894                     
895    def OnAddPhase(self,event):
896        if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
897            sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
898        else:
899            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
900        PhaseName = ''
901        dlg = wx.TextEntryDialog(None,'Enter a name for this phase','Phase Name Entry','New phase',
902            style=wx.OK)
903        if dlg.ShowModal() == wx.ID_OK:
904            PhaseName = dlg.GetValue()
905        dlg.Destroy()
906        sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
907        E,SGData = G2spc.SpcGroup('P 1')
908        self.PatternTree.SetItemPyData(sub, {
909            'General':{
910                'Name':PhaseName,
911                'Type':'nuclear',
912                'SGData':SGData,
913                'Cell':[False,10.,10.,10.,90.,90.,90,1000.],
914                'Pawley dmin':1.0,
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 = 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        dlg.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
1512        try:
1513            G2str.Refine(self.GSASprojectfile,dlg)
1514        finally:
1515            dlg.Destroy()       
1516        dlg = wx.MessageDialog(self,'Load new result?','Refinement results',wx.OK|wx.CANCEL)
1517        try:
1518            if dlg.ShowModal() == wx.ID_OK:
1519                Id = 0
1520                self.PatternTree.DeleteChildren(self.root)
1521                if self.HKL: self.HKL = []
1522                if self.G2plotNB.plotList:
1523                    self.G2plotNB.clear()
1524                G2IO.ProjFileOpen(self)
1525                item, cookie = self.PatternTree.GetFirstChild(self.root)
1526                while item and not Id:
1527                    name = self.PatternTree.GetItemText(item)
1528                    if name[:4] in ['PWDR','HKLF']:
1529                        Id = item
1530                    item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
1531                if Id:
1532                    self.PatternTree.SelectItem(Id)
1533        finally:
1534            dlg.Destroy()
1535
1536    def OnSeqRefine(self,event):
1537        Id = G2gd.GetPatternTreeItemId(self,self.root,'Sequental results')
1538        if not Id:
1539            Id = self.PatternTree.AppendItem(self.root,text='Sequental results')
1540            self.PatternTree.SetItemPyData(Id,{})           
1541        self.OnFileSave(event)
1542        dlg = wx.ProgressDialog('Residual for histogram 0','Powder profile Rwp =',101.0, 
1543            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT)
1544        screenSize = wx.ClientDisplayRect()
1545        Size = dlg.GetSize()
1546        dlg.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
1547        try:
1548            G2str.SeqRefine(self.GSASprojectfile,dlg)
1549        finally:
1550            dlg.Destroy()       
1551        dlg = wx.MessageDialog(self,'Load new result?','Refinement results',wx.OK|wx.CANCEL)
1552        try:
1553            if dlg.ShowModal() == wx.ID_OK:
1554                Id = 0
1555                self.PatternTree.DeleteChildren(self.root)
1556                if self.HKL: self.HKL = []
1557                if self.G2plotNB.plotList:
1558                    self.G2plotNB.clear()
1559                G2IO.ProjFileOpen(self)
1560                item, cookie = self.PatternTree.GetFirstChild(self.root)
1561                while item and not Id:
1562                    name = self.PatternTree.GetItemText(item)
1563                    if name[:4] in ['PWDR','HKLF']:
1564                        Id = item
1565                    item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
1566                if Id:
1567                    self.PatternTree.SelectItem(Id)
1568        finally:
1569            dlg.Destroy()
1570       
1571    def OnSolve(self,event):
1572        #works - but it'd be better if it could restore plots
1573        G2sol.Solve(self.GSASprojectfile)
1574        dlg = wx.MessageDialog(self,'Load new result?','Structure solution results',wx.OK|wx.CANCEL)
1575        try:
1576            if dlg.ShowModal() == wx.ID_OK:
1577                self.PatternTree.DeleteChildren(self.root)
1578                if self.HKL: self.HKL = []
1579                if self.G2plotNB.plotList:
1580                    self.G2plotNB.clear()
1581                G2IO.ProjFileOpen(self)
1582        finally:
1583            dlg.Destroy()
1584       
1585    def ErrorDialog(self,title,message):
1586        dlg = wx.MessageDialog(self, message, title,  wx.OK)
1587        try:
1588            result = dlg.ShowModal()
1589        finally:
1590            dlg.Destroy()
1591
1592    def OnHelpHelp(self, event):
1593        event.Skip()
1594       
1595    def OnHelpAbout(self, event):
1596        info = wx.AboutDialogInfo()
1597        info.Name = 'GSAS-II'
1598        info.Version = __version__
1599        info.Copyright = '''
1600Robert B. Von Dreele
1601Argonne National Laboratory(C)
1602This product includes software developed
1603by the UChicago Argonne, LLC, as
1604Operator of Argonne National Laboratory.         '''
1605        info.Description = '''
1606General Structure Analysis System - II
1607        '''
1608        wx.AboutBox(info)
1609       
1610class GSASIImain(wx.App):
1611    def OnInit(self):
1612        self.main = GSASII(None)
1613        self.main.Show()
1614        self.SetTopWindow(self.main)
1615        return True
1616
1617def main():
1618    application = GSASIImain(0)
1619    application.MainLoop()
1620
1621if __name__ == '__main__':
1622    main()
Note: See TracBrowser for help on using the repository browser.