source: trunk/GSASII.py @ 171

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

GSASIIIO.py:
read phase from cif file
fix esd output for powder data
prints space group info when pdb phase read in
GSASIIplot.py:
allow with 'u' & 'd' to vary max value in contour plot
select atom on drawing with Alt-LB
GSASIIpwdGUI.py:
Fix "UnDo?" in peak fitting
GSASII.py:
As above

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