source: trunk/GSASII.py @ 395

Last change on this file since 395 was 395, checked in by vondreele, 12 years ago

Add goniometer omega, chi & phi to sample data
put SH texture in General
fix phase delete to remove it from reflection lists as well
continue development of constraints/restraints GUI
fixes to texture computations, GUI & least squares refinement

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