source: trunk/GSASII.py @ 229

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

add svn keywords & self.logPlot

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