source: trunk/GSASII.py @ 94

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

move all fortran to fsource
add gray for readonly textctrl
do polygon insert, show in imageGUI and make mask
fix to ReadPDBphase to use correct crystal to cartesian transformation matrix

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