source: trunk/GSASII.py @ 335

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

Add delete Pawley list; scratch "leBail" from things
mods to texture display stuff
refactor instrument parameters GUI as sizer based - no grid table
some mods to peak fit output

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