source: trunk/GSASII.py @ 135

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

remove "GSASII" and "menu" from all names originally put in by Boaconstructor & not needed!!

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