source: trunk/GSASII.py @ 182

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