source: trunk/GSASII.py @ 164

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

more parameters

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