source: trunk/GSASII.py @ 369

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

remove wx from GSASIIstruct.py

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