source: trunk/GSASII.py @ 249

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

Modify export powder & delete data to allow global selections
make sure azimuth goes with pattern
refactor powderXyeSave & powderFxyeSave

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