source: trunk/GSASII.py @ 163

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

new versions

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