source: trunk/GSASII.py @ 295

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