source: trunk/GSASII.py @ 441

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

rename p:h:Size:0 & 1 to p:h:Size:i & a for isotropic/anisotropic parms, ditto for mustrain
keeps these separate from the generalized/ellipsoidal parms.
GSASIIstruct.Refine now returns Rwp - put on the "Save results" dialog.

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