source: trunk/GSASII.py @ 186

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

add "solve" to menu
Pawley fixes

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