source: trunk/GSASII.py @ 87

Last change on this file since 87 was 87, checked in by vondreel, 12 years ago

"Spots" in Masks is really "Points"
Start of "points" for masks

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