source: trunk/GSASII.py @ 311

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

finish new indexing refinement stuff
more on texture plotting

  • Property svn:keywords set to Date Author Revision URL Id
File size: 66.0 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#GSASII
4########### SVN repository information ###################
5# $Date: 2011-06-27 15:27:29 +0000 (Mon, 27 Jun 2011) $
6# $Author: vondreele $
7# $Revision: 311 $
8# $URL: trunk/GSASII.py $
9# $Id: GSASII.py 311 2011-06-27 15:27:29Z 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|Topas xye files (*.xye)|*.xye|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':[],
878            'Models':{},'SH Texture':{'Order':0,'Model':'cylindrical','Sample omega':[False,0.0],
879            'Sample chi':[False,0.0],'Sample phi':[False,0.0],'SH Coeff':[False,{}],
880            'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1],'PlotType':'Pole figure'}})
881       
882    def OnDeletePhase(self,event):
883        if self.dataFrame:
884            self.dataFrame.Clear() 
885        TextList = []
886        DelList = []
887        DelItemList = []
888        if G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
889            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
890        else:
891            return
892        if sub:
893            item, cookie = self.PatternTree.GetFirstChild(sub)
894            while item:
895                TextList.append(self.PatternTree.GetItemText(item))
896                item, cookie = self.PatternTree.GetNextChild(sub, cookie)               
897            dlg = wx.MultiChoiceDialog(self, 'Which phase to delete?', 'Delete phase', TextList, wx.CHOICEDLG_STYLE)
898            try:
899                if dlg.ShowModal() == wx.ID_OK:
900                    result = dlg.GetSelections()
901                    for i in result: DelList.append([i,TextList[i]])
902                    item, cookie = self.PatternTree.GetFirstChild(sub)
903                    i = 0
904                    while item:
905                        if [i,self.PatternTree.GetItemText(item)] in DelList: DelItemList.append(item)
906                        item, cookie = self.PatternTree.GetNextChild(sub, cookie)
907                        i += 1
908                    for item in DelItemList:
909                        name = self.PatternTree.GetItemText(item)
910                        self.PatternTree.Delete(item)
911                        self.G2plotNB.Delete(name)
912            finally:
913                dlg.Destroy()
914               
915    def OnRenameData(self,event):
916        name = self.PatternTree.GetItemText(self.PickId)     
917        if 'PWDR' in name or 'HKLF' in name or 'IMG' in name:
918            dataType = name[:name.index(' ')+1]                 #includes the ' '
919            dlg = wx.TextEntryDialog(self,'Data name: '+dataType,'Change data name',
920                defaultValue=name[name.index(' ')+1:])
921            try:
922                if dlg.ShowModal() == wx.ID_OK:
923                    self.PatternTree.SetItemText(self.PickId,dataType+dlg.GetValue())
924            finally:
925                dlg.Destroy()
926       
927    def GetFileList(self,fileType,skip=None):        #potentially useful?
928        fileList = []
929        Source = ''
930        id, cookie = self.PatternTree.GetFirstChild(self.root)
931        while id:
932            name = self.PatternTree.GetItemText(id)
933            if fileType in name:
934                if id == skip:
935                    Source = name
936                else:
937                    fileList.append([False,name,id])
938            id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
939        if skip:
940            return fileList,Source
941        else:
942            return fileList
943           
944    def OnDataDelete(self, event):
945        TextList = ['All Data']
946        DelList = []
947        DelItemList = []
948        ifPWDR = False
949        ifIMG = False
950        ifHKLF = False
951        ifPDF = False
952        if self.PatternTree.GetCount():
953            item, cookie = self.PatternTree.GetFirstChild(self.root)
954            while item:
955                name = self.PatternTree.GetItemText(item)
956                if 'PWDR' in name or 'HKLF' in name or 'IMG' or 'PDF' in name:
957                    if 'PWDR' in name: ifPWDR = True
958                    if 'IMG' in name: ifIMG = True
959                    if 'HKLF' in name: ifHKLF = True
960                    if 'PDF' in name: ifPDF = True
961                    TextList.append(name)
962                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
963            if ifPWDR: TextList.insert(1,'All PWDR')
964            if ifIMG: TextList.insert(1,'All IMG')
965            if ifHKLF: TextList.insert(1,'All HKLF')
966            if ifPDF: TextList.insert(1,'All PDF')               
967            dlg = wx.MultiChoiceDialog(self, 'Which data to delete?', 'Delete data', TextList, wx.CHOICEDLG_STYLE)
968            try:
969                if dlg.ShowModal() == wx.ID_OK:
970                    result = dlg.GetSelections()
971                    for i in result: DelList.append(TextList[i])
972                    if 'All Data' in DelList:
973                        DelList = [item for item in TextList if item[:3] != 'All']
974                    elif 'All PWDR' in DelList:
975                        DelList = [item for item in TextList if item[:4] == 'PWDR']
976                    elif 'All IMG' in DelList:
977                        DelList = [item for item in TextList if item[:3] == 'IMG']
978                    elif 'All HKLF' in DelList:
979                        DelList = [item for item in TextList if item[:4] == 'HKLF']
980                    elif 'All PDF' in DelList:
981                        DelList = [item for item in TextList if item[:3] == 'PDF']
982                    item, cookie = self.PatternTree.GetFirstChild(self.root)
983                    while item:
984                        if self.PatternTree.GetItemText(item) in DelList: DelItemList.append(item)
985                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
986                    for item in DelItemList:
987                        self.PatternTree.Delete(item)
988                    G2plt.PlotPatterns(self,True)                        #so plot gets updated
989            finally:
990                dlg.Destroy()
991
992    def OnFileOpen(self, event):
993        result = ''
994        Id = 0
995        if self.PatternTree.GetChildrenCount(self.root,False):
996            if self.dataFrame:
997                self.dataFrame.Clear() 
998            dlg = wx.MessageDialog(self, 'Overwrite?','Project exists!',  wx.OK | wx.CANCEL)
999            try:
1000                result = dlg.ShowModal()
1001                if result == wx.ID_OK:
1002                    self.PatternTree.DeleteChildren(self.root)
1003                    self.GSASprojectfile = ''
1004                    self.PatternTree.DeleteChildren(self.root)
1005                    if self.HKL: self.HKL = []
1006                    if self.G2plotNB.plotList:
1007                        self.G2plotNB.clear()
1008            finally:
1009                dlg.Destroy()
1010        if result != wx.ID_CANCEL:   
1011            if self.dataDisplay: self.dataDisplay.Destroy()
1012            dlg = wx.FileDialog(self, 'Choose GSAS-II project file', '.', '', 
1013                'GSAS-II project file (*.gpx)|*.gpx',wx.OPEN)
1014            if self.dirname: dlg.SetDirectory(self.dirname)
1015            try:
1016                if dlg.ShowModal() == wx.ID_OK:
1017                    self.GSASprojectfile = dlg.GetPath()
1018                    self.dirname = dlg.GetDirectory()
1019                    G2IO.ProjFileOpen(self)
1020                    self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
1021                    self.PatternTree.Expand(self.root)
1022                    self.HKL = []
1023                    item, cookie = self.PatternTree.GetFirstChild(self.root)
1024                    while item and not Id:
1025                        name = self.PatternTree.GetItemText(item)
1026                        if name[:4] in ['PWDR','HKLF','IMG ','PDF ']:
1027                            Id = item
1028                        elif name == 'Controls':
1029                            data = self.PatternTree.GetItemPyData(item)
1030                            if data != [0] and data != {}:
1031                                self.Refine.Enable(True)
1032                                self.Solve.Enable(True)         #not right but something needed here
1033                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
1034                    if Id:
1035                        self.PatternTree.SelectItem(Id)
1036            finally:
1037                dlg.Destroy()
1038
1039    def OnFileClose(self, event):
1040        if self.dataFrame:
1041            self.dataFrame.Clear()
1042            self.dataFrame.SetLabel('GSAS-II data display') 
1043        dlg = wx.MessageDialog(self, 'Save current project?', ' ', wx.YES | wx.NO | wx.CANCEL)
1044        try:
1045            result = dlg.ShowModal()
1046            if result == wx.ID_OK:
1047                self.OnFileSaveMenu(event)
1048            if result != wx.ID_CANCEL:
1049                self.GSASprojectfile = ''
1050                self.PatternTree.SetItemText(self.root,'Loaded Data: ')
1051                self.PatternTree.DeleteChildren(self.root)
1052                if self.HKL: self.HKL = []
1053                if self.G2plotNB.plotList:
1054                    self.G2plotNB.clear()
1055        finally:
1056            dlg.Destroy()
1057
1058    def OnFileSave(self, event):
1059        if self.GSASprojectfile: 
1060            self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
1061            G2IO.ProjFileSave(self)
1062        else:
1063            self.OnFileSaveas(event)
1064
1065    def OnFileSaveas(self, event):
1066        dlg = wx.FileDialog(self, 'Choose GSAS-II project file name', '.', '', 
1067            'GSAS-II project file (*.gpx)|*.gpx',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
1068        if self.dirname:
1069            dlg.SetDirectory(self.dirname)
1070        try:
1071            if dlg.ShowModal() == wx.ID_OK:
1072                self.GSASprojectfile = dlg.GetPath()
1073                self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
1074                G2IO.ProjFileSave(self)
1075                self.dirname = dlg.GetDirectory()
1076        finally:
1077            dlg.Destroy()
1078
1079    def ExitMain(self, event):
1080        if self.undofile:
1081            os.remove(self.undofile)
1082        sys.exit()
1083       
1084    def OnFileExit(self, event):
1085        if self.dataFrame:
1086            self.dataFrame.Clear() 
1087            self.dataFrame.Destroy()
1088        self.Close()
1089       
1090    def OnImportPattern(self,event):
1091        dlg = wx.FileDialog(self, 'Choose nonGSAS powder file', '.', '', 
1092            '(*.*)|*.*',wx.OPEN)
1093        if self.dirname:
1094            dlg.SetDirectory(self.dirname)
1095        try:
1096            if dlg.ShowModal() == wx.ID_OK:
1097                self.powderfile = dlg.GetPath()
1098                self.dirname = dlg.GetDirectory()
1099        finally:
1100            dlg.Destroy()
1101           
1102    def OnImportHKL(self,event):
1103        dlg = wx.FileDialog(self, 'Choose structure factor file', '.', '', 
1104            '(*.*)|*.*',wx.OPEN)
1105        if self.dirname:
1106            dlg.SetDirectory(self.dirname)
1107        try:
1108            if dlg.ShowModal() == wx.ID_OK:
1109                self.HKLfile = dlg.GetPath()
1110                self.dirname = dlg.GetDirectory()
1111        finally:
1112            dlg.Destroy()
1113       
1114    def OnImportPhase(self,event):
1115        dlg = wx.FileDialog(self, 'Choose GSAS EXP file', '.', '', 
1116            'EXP file (*.EXP)|*.EXP',wx.OPEN)
1117        if self.dirname:
1118            dlg.SetDirectory(self.dirname)
1119        try:
1120            Phase = {}
1121            if dlg.ShowModal() == wx.ID_OK:
1122                EXPfile = dlg.GetPath()
1123                self.dirname = dlg.GetDirectory()
1124                Phase = G2IO.ReadEXPPhase(self,EXPfile)
1125        finally:
1126            dlg.Destroy()
1127        if Phase:
1128            PhaseName = Phase['General']['Name']
1129            if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1130                sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1131            else:
1132                sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1133            sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1134            self.PatternTree.SetItemPyData(sub,Phase)
1135           
1136    def OnImportPDB(self,event):
1137        dlg = wx.FileDialog(self, 'Choose PDB file', '.', '', 
1138            'PDB file (*.pdb,*.ent)|*.pdb;*.ent|All files (*.*)|*.*',wx.OPEN)
1139        if self.dirname:
1140            dlg.SetDirectory(self.dirname)
1141        try:
1142            if dlg.ShowModal() == wx.ID_OK:
1143                PDBfile = dlg.GetPath()
1144                self.dirname = dlg.GetDirectory()
1145                Phase = G2IO.ReadPDBPhase(PDBfile)
1146        finally:
1147            dlg.Destroy()
1148        if Phase:
1149            PhaseName = Phase['General']['Name']
1150            if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1151                sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1152            else:
1153                sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1154            sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1155            self.PatternTree.SetItemPyData(sub,Phase)       
1156       
1157    def OnImportCIF(self,event):
1158        dlg = wx.FileDialog(self, 'Choose CIF file', '.', '', 
1159            'CIF file (*.cif)|*.cif',wx.OPEN)
1160        if self.dirname:
1161            dlg.SetDirectory(self.dirname)
1162        try:
1163            if dlg.ShowModal() == wx.ID_OK:
1164                CIFfile = dlg.GetPath()
1165                self.dirname = dlg.GetDirectory()
1166                Phase = G2IO.ReadCIFPhase(CIFfile)
1167        finally:
1168            dlg.Destroy()
1169        if Phase:
1170            PhaseName = Phase['General']['Name']
1171            if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1172                sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1173            else:
1174                sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1175            sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1176            self.PatternTree.SetItemPyData(sub,Phase)       
1177       
1178    def OnExportPatterns(self,event):
1179        names = ['All']
1180        exports = []
1181        item, cookie = self.PatternTree.GetFirstChild(self.root)
1182        while item:
1183            name = self.PatternTree.GetItemText(item)
1184            if 'PWDR' in name:
1185                names.append(name)
1186            item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1187        if names:
1188            dlg = wx.MultiChoiceDialog(self,'Select','Powder patterns to export',names)
1189            if dlg.ShowModal() == wx.ID_OK:
1190                sel = dlg.GetSelections()
1191                if sel[0] == 0:
1192                    exports = names[1:]
1193                else:
1194                    for x in sel:
1195                        exports.append(names[x])
1196            dlg.Destroy()
1197        if exports:
1198            dlg = wx.FileDialog(self, 'Choose output powder file name', '.', '', 
1199                'GSAS fxye file (*.fxye)|*.fxye|xye file (*.xye)|*.xye',
1200                wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
1201            if self.dirname:
1202                dlg.SetDirectory(self.dirname)
1203            try:
1204                if dlg.ShowModal() == wx.ID_OK:
1205                    powderfile = dlg.GetPath()
1206                    if 'fxye' in powderfile:
1207                        G2IO.powderFxyeSave(self,exports,powderfile)
1208                    else:       #just xye
1209                        G2IO.powderXyeSave(self,exports,powderfile)
1210                    self.dirname = dlg.GetDirectory()
1211            finally:
1212                dlg.Destroy()
1213       
1214    def OnExportPeakList(self,event):
1215        dlg = wx.FileDialog(self, 'Choose output peak list file name', '.', '', 
1216            '(*.*)|*.*',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
1217        if self.dirname:
1218            dlg.SetDirectory(self.dirname)
1219        try:
1220            if dlg.ShowModal() == wx.ID_OK:
1221                self.peaklistfile = dlg.GetPath()
1222                file = open(self.peaklistfile,'w')               
1223                item, cookie = self.PatternTree.GetFirstChild(self.root)
1224                while item:
1225                    name = self.PatternTree.GetItemText(item)
1226                    if 'PWDR' in name:
1227                        item2, cookie2 = self.PatternTree.GetFirstChild(item)
1228                        while item2:
1229                            name2 = self.PatternTree.GetItemText(item2)
1230                            if name2 == 'Peak List':
1231                                peaks = self.PatternTree.GetItemPyData(item2)
1232                                file.write("%s \n" % (name+' Peak List'))               
1233                                for peak in peaks:
1234                                    file.write("%10.4f %12.2f %10.3f %10.3f \n" % \
1235                                        (peak[0],peak[2],peak[4],peak[6]))
1236                            item2, cookie2 = self.PatternTree.GetNextChild(item, cookie2)                           
1237                    item, cookie = self.PatternTree.GetNextChild(self.root, cookie)                           
1238                file.close()
1239                self.dirname = dlg.GetDirectory()
1240        finally:
1241            dlg.Destroy()
1242       
1243    def OnExportHKL(self,event):
1244        event.Skip()
1245       
1246    def OnExportPDF(self,event):
1247        #need S(Q) and G(R) to be saved here - probably best from selection?
1248        names = ['All']
1249        exports = []
1250        item, cookie = self.PatternTree.GetFirstChild(self.root)
1251        while item:
1252            name = self.PatternTree.GetItemText(item)
1253            if 'PDF' in name:
1254                names.append(name)
1255            item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1256        if names:
1257            dlg = wx.MultiChoiceDialog(self,'Select','PDF patterns to export',names)
1258            if dlg.ShowModal() == wx.ID_OK:
1259                sel = dlg.GetSelections()
1260                if sel[0] == 0:
1261                    exports = names[1:]
1262                else:
1263                    for x in sel:
1264                        exports.append(names[x])
1265            dlg.Destroy()
1266        if exports:
1267            G2IO.PDFSave(self,exports)
1268       
1269    def OnExportPhase(self,event):
1270        event.Skip()
1271       
1272    def OnExportCIF(self,event):
1273        event.Skip()
1274
1275    def OnMakePDFs(self,event):
1276        tth2q = lambda t,w:4.0*math.pi*sind(t/2.0)/w
1277        TextList = ['All PWDR']
1278        PDFlist = []
1279        Names = []
1280        if self.PatternTree.GetCount():
1281            id, cookie = self.PatternTree.GetFirstChild(self.root)
1282            while id:
1283                name = self.PatternTree.GetItemText(id)
1284                Names.append(name)
1285                if 'PWDR' in name:
1286                    TextList.append(name)
1287                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1288            if len(TextList) == 1:
1289                self.ErrorDialog('Nothing to make PDFs for','There must be at least one "PWDR" pattern')
1290                return
1291            dlg = wx.MultiChoiceDialog(self,'Make PDF controls','Make PDF controls for:',TextList, wx.CHOICEDLG_STYLE)
1292            try:
1293                if dlg.ShowModal() == wx.ID_OK:
1294                    result = dlg.GetSelections()
1295                    for i in result: PDFlist.append(TextList[i])
1296                    if 0 in result:
1297                        PDFlist = [item for item in TextList if item[:4] == 'PWDR']                       
1298                    for item in PDFlist:
1299                        PWDRname = item[4:]
1300                        Id = self.PatternTree.AppendItem(parent=self.root,text='PDF '+PWDRname)
1301                        Data = {
1302                            'Sample':{'Name':item,'Mult':1.0,'Add':0.0},
1303                            'Sample Bkg.':{'Name':'','Mult':-1.0,'Add':0.0},
1304                            'Container':{'Name':'','Mult':-1.0,'Add':0.0},
1305                            'Container Bkg.':{'Name':'','Mult':-1.0,'Add':0.0},'ElList':{},
1306                            'Geometry':'Cylinder','Diam':1.0,'Pack':0.50,'Form Vol':10.0,
1307                            'DetType':'Image plate','ObliqCoeff':0.2,'Ruland':0.025,'QScaleLim':[0,100],
1308                            'Lorch':True,}
1309                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='PDF Controls'),Data)
1310                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='I(Q)'+PWDRname),[])       
1311                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='S(Q)'+PWDRname),[])       
1312                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='F(Q)'+PWDRname),[])       
1313                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='G(R)'+PWDRname),[])       
1314                self.ExportPDF.Enable(True)
1315            finally:
1316                dlg.Destroy()
1317       
1318    def OnRefine(self,event):
1319        #works - but it'd be better if it could restore plots
1320        G2str.Refine(self.GSASprojectfile)
1321        dlg = wx.MessageDialog(self,'Load new result?','Refinement results',wx.OK|wx.CANCEL)
1322        try:
1323            if dlg.ShowModal() == wx.ID_OK:
1324                self.PatternTree.DeleteChildren(self.root)
1325                if self.HKL: self.HKL = []
1326                if self.G2plotNB.plotList:
1327                    self.G2plotNB.clear()
1328                G2IO.ProjFileOpen(self)
1329        finally:
1330            dlg.Destroy()
1331       
1332    def OnSolve(self,event):
1333        #works - but it'd be better if it could restore plots
1334        G2sol.Solve(self.GSASprojectfile)
1335        dlg = wx.MessageDialog(self,'Load new result?','Structure solution results',wx.OK|wx.CANCEL)
1336        try:
1337            if dlg.ShowModal() == wx.ID_OK:
1338                self.PatternTree.DeleteChildren(self.root)
1339                if self.HKL: self.HKL = []
1340                if self.G2plotNB.plotList:
1341                    self.G2plotNB.clear()
1342                G2IO.ProjFileOpen(self)
1343        finally:
1344            dlg.Destroy()
1345       
1346    def ErrorDialog(self,title,message):
1347        dlg = wx.MessageDialog(self, message, title,  wx.OK)
1348        try:
1349            result = dlg.ShowModal()
1350        finally:
1351            dlg.Destroy()
1352
1353    def OnHelpHelp(self, event):
1354        event.Skip()
1355       
1356    def OnHelpAbout(self, event):
1357        info = wx.AboutDialogInfo()
1358        info.Name = 'GSAS-II'
1359        info.Version = __version__
1360        info.Copyright = '''
1361Robert B. Von Dreele
1362Argonne National Laboratory(C)
1363This product includes software developed
1364by the UChicago Argonne, LLC, as
1365Operator of Argonne National Laboratory.         '''
1366        info.Description = '''
1367General Structure Analysis System - II
1368        '''
1369        wx.AboutBox(info)
1370       
1371class GSASIImain(wx.App):
1372    def OnInit(self):
1373        self.main = GSASII(None)
1374        self.main.Show()
1375        self.SetTopWindow(self.main)
1376        return True
1377
1378def main():
1379    application = GSASIImain(0)
1380    application.MainLoop()
1381
1382if __name__ == '__main__':
1383    main()
Note: See TracBrowser for help on using the repository browser.