source: trunk/GSASII.py @ 81

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

split out image stuff into GSASIIimage.py

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