source: trunk/GSASII.py @ 250

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

GSASIIgrid.py - improve Comments listing
GSASII.py - add qPlot option
GSASIIpwdGUI.py - remove a couple of prints
GSASIIplot.py - add q & log(Y) plotting

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