source: trunk/GSASII.py @ 225

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

fixes to window positioning around task bar

File size: 58.1 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        clientSize = wx.ClientDisplayRect()
206        Size = self.GetSize()
207        xPos = clientSize[2]-Size[0]
208        self.SetPosition(wx.Point(xPos,clientSize[1]))
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,Temperature = 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],
316                        'DisplaceX':[0.0,False],'DisplaceY':[0.0,False],'Diffuse':[],
317                        'Temperature':Temperature,'Pressure':1.0,'Humidity':0.0,'Voltage':0.0,
318                        'Force':0.0}
319                    try:
320                        for Item in Data:
321                            vals = Item[2].split()          #split up the BANK record
322                            Id = self.PatternTree.AppendItem(parent=self.root,text='PWDR '+ospath.basename(Item[0])+': '+vals[0]+vals[1])
323                            data = G2IO.GetPowderData(filename,Item[1],Item[2],DataType)
324                            self.PatternTree.SetItemPyData(Id,[Item,data])
325                            '''
326                            Each tree item data is a list with:
327                            Item: the (filename,Pos,Bank) tuple
328                            data: (x,y,w,yc,yb,yd) list  of np.arrays from GetPowderData
329                            '''
330                           
331                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)                           
332                            Tmin = min(data[0])
333                            Tmax = max(data[0])
334                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Limits'),[(Tmin,Tmax),[Tmin,Tmax]])
335                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',1,3,1.0,0.0,0.0]])
336       
337                            data = [DataType,]
338                            if 'C' in DataType:
339                                s = Iparm['INS  1 ICONS']
340                                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
341                                if not v[1]:
342                                    names = ['Type','Lam','Zero','Polariz.','U','V','W','X','Y','SH/L','Azimuth'] 
343                                    v = (v[0],v[2],v[4])
344                                    codes = [0,0,0,0]
345                                else:
346                                    names = ['Type','Lam1','Lam2','Zero','I(L2)/I(L1)','Polariz.','U','V','W','X','Y','SH/L','Azimuth']
347                                    codes = [0,0,0,0,0,0]
348                                data.extend(v)
349                                v1 = Iparm['INS  1PRCF1 '].split()                                                 
350                                v = Iparm['INS  1PRCF11'].split()
351                                data.extend([float(v[0]),float(v[1]),float(v[2])])                  #get GU, GV & GW - always here
352                                v = Iparm['INS  1PRCF12'].split()
353                                if v1[0] == 3:
354                                    data.extend([float(v[0]),float(v[1]),float(v[2])+float(v[3],0.0)])  #get LX, LY, S+H/L & azimuth
355                                else:
356                                    data.extend([0.0,0.0,0.002,0.0])                                      #OK defaults if fxn #3 not 1st in iprm file
357                                codes.extend([0,0,0,0,0,0,0])
358                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(data),data,codes,names])
359                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
360                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Peak List'),[])
361                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),[])
362                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
363                            self.PatternId = G2gd.GetPatternTreeItemId(self,Id,'Limits')
364                    finally:
365                        wx.EndBusyCursor()
366                self.PatternTree.Expand(Id)
367                self.PatternTree.SelectItem(Id)
368   
369        finally:
370            dlg.Destroy()
371       
372    def OnReadPowderPeaks(self,event):
373        Cuka = 1.54052
374        self.CheckNotebook()
375        dlg = wx.FileDialog(self, 'Choose file with peak list', '.', '', 
376            'peak files (*.txt)|*.txt|All files (*.*)|*.*',wx.OPEN)
377        if self.dirname:
378            dlg.SetDirectory(self.dirname)
379        try:
380            if dlg.ShowModal() == wx.ID_OK:
381                self.HKL = []
382                self.powderfile = dlg.GetPath()
383                self.dirname = dlg.GetDirectory()
384                comments,peaks = G2IO.GetPowderPeaks(self.powderfile)
385                Id = self.PatternTree.AppendItem(parent=self.root,text='PKS '+ospath.basename(self.powderfile))
386                data = ['PKS',Cuka,0.0]
387                names = ['Type','Lam','Zero'] 
388                codes = [0,0]
389                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(data),data,codes,names])
390                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),comments)
391                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),peaks)
392                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
393                self.PatternTree.Expand(Id)
394                self.PatternTree.SelectItem(Id)
395        finally:
396            dlg.Destroy()
397           
398    def OnImageRead(self,event):
399        self.CheckNotebook()
400        dlg = wx.FileDialog(self, 'Choose image files', '.', '',\
401        'MAR345 (*.mar3450;*.mar2300)|*.mar3450;*.mar2300|ADSC Image (*.img)\
402        |*.img|Detector tif (*.tif;*.tiff)|*.tif;*.tiff|GE Image sum (*.sum)\
403        |*.sum|GE Image avg (*.avg)|*.avg|GE Image raw (*)|*|All files (*.*)|*.*',wx.OPEN | wx.MULTIPLE)
404        if self.dirname:
405            dlg.SetDirectory(self.dirname)
406        try:
407            if dlg.ShowModal() == wx.ID_OK:
408                self.dirname = dlg.GetDirectory()
409                imagefiles = dlg.GetPaths()
410                imagefiles.sort()
411                for imagefile in imagefiles:
412                    Comments,Data,Size,Image = G2IO.GetImageData(self,imagefile)
413                    if Comments:
414                        Id = self.PatternTree.AppendItem(parent=self.root,text='IMG '+ospath.basename(imagefile))
415                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)
416                        Imax = np.amax(Image)
417                        Imin = max(0.0,np.amin(Image))          #force positive
418                        if self.imageDefault:
419                            Data = copy.copy(self.imageDefault)
420                            Data['showLines'] = True
421                            Data['ring'] = []
422                            Data['rings'] = []
423                            Data['cutoff'] = 10
424                            Data['pixLimit'] = 20
425                            Data['ellipses'] = []
426                            Data['calibrant'] = ''
427                        else:
428                            Data['color'] = 'binary'
429                            Data['tilt'] = 0.0
430                            Data['rotation'] = 0.0
431                            Data['showLines'] = False
432                            Data['ring'] = []
433                            Data['rings'] = []
434                            Data['cutoff'] = 10
435                            Data['pixLimit'] = 20
436                            Data['ellipses'] = []
437                            Data['calibrant'] = ''
438                            Data['IOtth'] = [2.0,5.0]
439                            Data['LRazimuth'] = [-135,-45]
440                            Data['outChannels'] = 2500
441                            Data['outAzimuths'] = 1
442                            Data['fullIntegrate'] = False
443                            Data['setRings'] = False
444                        Data['setDefault'] = False
445                        Data['range'] = [(Imin,Imax),[Imin,Imax]]
446                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Image Controls'),Data)
447                        Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
448                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Masks'),Masks)
449                        self.PatternTree.SetItemPyData(Id,[Size,imagefile])
450                        self.PickId = Id
451                        self.Image = Id
452                self.PatternTree.SelectItem(G2gd.GetPatternTreeItemId(self,Id,'Image Controls'))             #show last one
453        finally:
454            dlg.Destroy()
455       
456    def OnSnglRead(self,event):
457        self.CheckNotebook()
458        dlg = wx.FileDialog(self, 'Choose file', '.', '', 
459            'hkl files (*.hkl)|*.hkl|All files (*.*)|*.*', 
460            wx.OPEN)
461        if self.dirname: dlg.SetDirectory(self.dirname)
462        try:
463            if dlg.ShowModal() == wx.ID_OK:
464                filename = dlg.GetPath()
465                self.dirname = dlg.GetDirectory()
466                wx.BeginBusyCursor()
467                try:
468                    Data = {}
469                    names = ['Type','Lam']
470                    HKLref,HKLmin,HKLmax,FoMax,ifFc = G2IO.GetHKLData(filename)
471                    Id = self.PatternTree.AppendItem(parent=self.root,text='HKLF '+ospath.basename(filename))
472                    self.PatternTree.SetItemPyData(Id,HKLref)
473                    Sub = self.PatternTree.AppendItem(Id,text='Instrument Parameters')
474                    data = ['SXC',1.5428,]
475                    self.PatternTree.SetItemPyData(Sub,[tuple(data),data,names])
476                    Data['Type'] = 'Fosq'
477                    Data['ifFc'] = ifFc
478                    Data['HKLmax'] = HKLmax
479                    Data['HKLmin'] = HKLmin
480                    Data['FoMax'] = FoMax
481                    Data['Zone'] = '001'
482                    Data['Layer'] = 0
483                    Data['Scale'] = 1.0
484                    Data['log-lin'] = 'lin'                   
485                    self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='HKL Plot Controls'),Data)
486                    self.PatternTree.SelectItem(Id)
487                    self.PatternTree.Expand(Id)
488                    self.Sngl = Id
489                finally:
490                    wx.EndBusyCursor()   
491        finally:
492            dlg.Destroy()
493           
494    def CheckNotebook(self):
495        if not G2gd.GetPatternTreeItemId(self,self.root,'Notebook'):
496            sub = self.PatternTree.AppendItem(parent=self.root,text='Notebook')
497            self.PatternTree.SetItemPyData(sub,[''])
498            sub = self.PatternTree.AppendItem(parent=self.root,text='Controls')
499            self.PatternTree.SetItemPyData(sub,{})
500               
501    class CopyDialog(wx.Dialog):
502        def __init__(self,parent,title,text,data):
503            wx.Dialog.__init__(self,parent,-1,title, 
504                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
505            self.data = data
506            panel = wx.Panel(self)
507            mainSizer = wx.BoxSizer(wx.VERTICAL)
508            topLabl = wx.StaticText(panel,-1,text)
509            mainSizer.Add((10,10),1)
510            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
511            mainSizer.Add((10,10),1)
512            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=1,hgap=2,vgap=2)
513            for id,item in enumerate(self.data):
514                ckbox = wx.CheckBox(panel,id,item[1])
515                ckbox.Bind(wx.EVT_CHECKBOX,self.OnCopyChange)                   
516                dataGridSizer.Add(ckbox,0,wx.LEFT,10)
517            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
518            OkBtn = wx.Button(panel,-1,"Ok")
519            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
520            cancelBtn = wx.Button(panel,-1,"Cancel")
521            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
522            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
523            btnSizer.Add((20,20),1)
524            btnSizer.Add(OkBtn)
525            btnSizer.Add((20,20),1)
526            btnSizer.Add(cancelBtn)
527            btnSizer.Add((20,20),1)
528           
529            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
530            panel.SetSizer(mainSizer)
531            panel.Fit()
532            self.Fit()
533       
534        def OnCopyChange(self,event):
535            id = event.GetId()
536            self.data[id][0] = self.FindWindowById(id).GetValue()       
537           
538        def OnOk(self,event):
539            parent = self.GetParent()
540            parent.Raise()
541            self.EndModal(wx.ID_OK)             
542            self.Destroy()
543           
544        def OnCancel(self,event):
545            parent = self.GetParent()
546            parent.Raise()
547            self.EndModal(wx.ID_CANCEL)             
548            self.Destroy()
549           
550        def GetData(self):
551                return self.data
552       
553    class SumDialog(wx.Dialog):
554        def __init__(self,parent,title,text,dataType,data):
555            wx.Dialog.__init__(self,parent,-1,title, 
556                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
557            self.data = data
558            panel = wx.Panel(self)
559            mainSizer = wx.BoxSizer(wx.VERTICAL)
560            topLabl = wx.StaticText(panel,-1,text)
561            mainSizer.Add((10,10),1)
562            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
563            mainSizer.Add((10,10),1)
564            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=2,hgap=2,vgap=2)
565            for id,item in enumerate(self.data[:-1]):
566                name = wx.TextCtrl(panel,-1,item[1],size=wx.Size(200,20))
567                name.SetEditable(False)
568                scale = wx.TextCtrl(panel,id,str(item[0]),style=wx.TE_PROCESS_ENTER)
569                scale.Bind(wx.EVT_TEXT,self.OnScaleChange)                   
570                dataGridSizer.Add(scale,0,wx.LEFT,10)
571                dataGridSizer.Add(name,0,wx.RIGHT,10)
572            dataGridSizer.Add(wx.StaticText(panel,-1,'Sum result name: '+dataType),0, \
573                wx.LEFT|wx.TOP|wx.ALIGN_CENTER_VERTICAL,10)
574            self.name = wx.TextCtrl(panel,-1,self.data[-1],size=wx.Size(200,20),style=wx.TE_PROCESS_ENTER)
575            self.name.Bind(wx.EVT_TEXT,self.OnNameChange)
576            dataGridSizer.Add(self.name,0,wx.RIGHT|wx.TOP,10)
577            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
578            OkBtn = wx.Button(panel,-1,"Ok")
579            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
580            cancelBtn = wx.Button(panel,-1,"Cancel")
581            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
582            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
583            btnSizer.Add((20,20),1)
584            btnSizer.Add(OkBtn)
585            btnSizer.Add((20,20),1)
586            btnSizer.Add(cancelBtn)
587            btnSizer.Add((20,20),1)
588           
589            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
590            panel.SetSizer(mainSizer)
591            panel.Fit()
592            self.Fit()
593           
594        def OnNameChange(self,event):
595            self.data[-1] = self.name.GetValue() 
596           
597        def OnScaleChange(self,event):
598            id = event.GetId()
599            value = self.FindWindowById(id).GetValue()
600            try:
601                self.data[id][0] = float(value)
602                self.FindWindowById(id).SetValue('%.3f'%(self.data[id][0]))
603            except ValueError:
604                if value and '-' not in value[0]:
605                    print 'bad input - numbers only'
606                    self.FindWindowById(id).SetValue('0.0')
607           
608        def OnOk(self,event):
609            parent = self.GetParent()
610            parent.Raise()
611            self.EndModal(wx.ID_OK)             
612            self.Destroy()
613           
614        def OnCancel(self,event):
615            parent = self.GetParent()
616            parent.Raise()
617            self.EndModal(wx.ID_CANCEL)             
618            self.Destroy()
619           
620        def GetData(self):
621            return self.data
622           
623    def OnPwdrSum(self,event):
624        TextList = []
625        DataList = []
626        SumList = []
627        Names = []
628        Inst = []
629        SumItemList = []
630        Comments = ['Sum equals: \n']
631        if self.PatternTree.GetCount():
632            item, cookie = self.PatternTree.GetFirstChild(self.root)
633            while item:
634                name = self.PatternTree.GetItemText(item)
635                Names.append(name)
636                if 'PWDR' in name:
637                    TextList.append([0.0,name])
638                    DataList.append(self.PatternTree.GetItemPyData(item)[1])    # (x,y,w,yc,yb,yd)
639                    if not Inst:
640                        Inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,item, 'Instrument Parameters'))
641                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
642            if len(TextList) < 2:
643                self.ErrorDialog('Not enough data to sum','There must be more than one "PWDR" pattern')
644                return
645            TextList.append('default_sum_name')               
646            dlg = self.SumDialog(self,'Sum data','Enter scale for each pattern in summation','PWDR',TextList)
647            try:
648                if dlg.ShowModal() == wx.ID_OK:
649                    lenX = 0
650                    Xminmax = [0,0]
651                    Xsum = []
652                    Ysum = []
653                    Vsum = []
654                    result = dlg.GetData()
655                    for i,item in enumerate(result[:-1]):
656                        scale,name = item
657                        data = DataList[i]
658                        if scale:
659                            Comments.append("%10.3f %s" % (scale,' * '+name))
660                            x,y,w,yc,yb,yd = data
661                            v = 1./w
662                            if lenX:
663                                if lenX != len(x):
664                                    self.ErrorDialog('Data length error','Data to be summed must have same number of points'+ \
665                                        '\nExpected:'+str(lenX)+ \
666                                        '\nFound:   '+str(len(x))+'\nfor '+name)
667                                    return
668                            else:
669                                lenX = len(x)
670                            if Xminmax[1]:
671                                if Xminmax != [x[0],x[-1]]:
672                                    self.ErrorDialog('Data range error','Data to be summed must span same range'+ \
673                                        '\nExpected:'+str(Xminmax[0])+' '+str(Xminmax[1])+ \
674                                        '\nFound:   '+str(x[0])+' '+str(x[-1])+'\nfor '+name)
675                                    return
676                                else:
677                                    for j,yi in enumerate(y):
678                                         Ysum[j] += scale*yi
679                                         Vsum[j] += abs(scale)*v[j]
680                            else:
681                                Xminmax = [x[0],x[-1]]
682                                YCsum = YBsum = YDsum = [0.0 for i in range(lenX)]
683                                for j,yi in enumerate(y):
684                                    Xsum.append(x[j])
685                                    Ysum.append(scale*yi)
686                                    Vsum.append(abs(scale*v[j]))
687                    Wsum = 1./np.array(Vsum)
688                    outname = 'PWDR '+result[-1]
689                    Id = 0
690                    if outname in Names:
691                        dlg2 = wx.MessageDialog(self,'Overwrite data?','Duplicate data name',wx.OK|wx.CANCEL)
692                        try:
693                            if dlg2.ShowModal() == wx.ID_OK:
694                                Id = G2gd.GetPatternTreeItemId(self,self.root,name)
695                        finally:
696                            dlg2.Destroy()
697                    else:
698                        Id = self.PatternTree.AppendItem(parent=self.root,text=outname)
699                    if Id:
700                        Sample = {'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],'DisplaceX':[0.0,False],
701                            'DisplaceY':[0.0,False],'Diffuse':[],'Temperature':300.,'Pressure':1.0,'Humidity':0.0,'Voltage':0.0,'Force':0.0}
702                        self.PatternTree.SetItemPyData(Id,[[''],[Xsum,Ysum,Wsum,YCsum,YBsum,YDsum]])
703                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)                   
704                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Limits'),[tuple(Xminmax),Xminmax])
705                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',1,3,1.0,0.0,0.0]])
706                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),Inst)
707                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
708                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Peak List'),[])
709                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),[])
710                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
711                        self.PatternTree.SelectItem(Id)
712                        self.PatternTree.Expand(Id)
713                   
714            finally:
715                dlg.Destroy()
716
717    def OnImageSum(self,event):
718        TextList = []
719        DataList = []
720        SumList = []
721        Names = []
722        Inst = []
723        SumItemList = []
724        Comments = ['Sum equals: \n']
725        if self.PatternTree.GetCount():
726            item, cookie = self.PatternTree.GetFirstChild(self.root)
727            while item:
728                name = self.PatternTree.GetItemText(item)
729                Names.append(name)
730                if 'IMG' in name:
731                    TextList.append([0.0,name])
732                    DataList.append(self.PatternTree.GetItemPyData(item))        #Size,Image
733                    Data = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,item,'Image Controls'))
734                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
735            if len(TextList) < 2:
736                self.ErrorDialog('Not enough data to sum','There must be more than one "IMG" pattern')
737                return
738            TextList.append('default_sum_name')               
739            dlg = self.SumDialog(self,'Sum data','Enter scale for each image in summation','IMG',TextList)
740            try:
741                if dlg.ShowModal() == wx.ID_OK:
742                    imSize = 0
743                    result = dlg.GetData()
744                    First = True
745                    Found = False
746                    for i,item in enumerate(result[:-1]):
747                        scale,name = item
748                        data = DataList[i]
749                        if scale:
750                            Found = True                               
751                            Comments.append("%10.3f %s" % (scale,' * '+name))
752                            size,imagefile = data
753                            image = G2IO.GetImageData(imagefile,imageOnly=True)
754                            if First:
755                                newImage = np.zeros_like(image)
756                                First = False
757                            if imSize:
758                                if imSize != size:
759                                    self.ErrorDialog('Image size error','Images to be summed must be same size'+ \
760                                        '\nExpected:'+str(imSize)+ \
761                                        '\nFound:   '+str(size)+'\nfor '+name)
762                                    return
763                                newImage = newImage+scale*image
764                            else:
765                                imSize = size
766                                newImage = newImage+scale*image
767                            del(image)
768                    if not Found:
769                        self.ErrorDialog('Image sum error','No nonzero image multipliers found')
770                        return
771                       
772                    newImage = np.asfarray(newImage,dtype=np.float32)                       
773                    outname = 'IMG '+result[-1]
774                    Id = 0
775                    if outname in Names:
776                        dlg2 = wx.MessageDialog(self,'Overwrite data?','Duplicate data name',wx.OK|wx.CANCEL)
777                        try:
778                            if dlg2.ShowModal() == wx.ID_OK:
779                                Id = G2gd.GetPatternTreeItemId(self,self.root,name)
780                        finally:
781                            dlg2.Destroy()
782                    else:
783                        Id = self.PatternTree.AppendItem(parent=self.root,text=outname)
784                    if Id:
785                        dlg = wx.FileDialog(self, 'Choose sum image filename', '.', '', 
786                            'G2img files (*.G2img)|*.G2img', 
787                            wx.SAVE|wx.FD_OVERWRITE_PROMPT)
788                        if self.dirname: dlg.SetDirectory(self.dirname)
789                        if dlg.ShowModal() == wx.ID_OK:
790                            self.dirname = dlg.GetDirectory()
791                            newimagefile = dlg.GetPath()
792                            G2IO.PutG2Image(newimagefile,newImage)
793                            Imax = np.amax(newImage)
794                            Imin = np.amin(newImage)
795                            newImage = []
796                            self.PatternTree.SetItemPyData(Id,[imSize,newimagefile])
797                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)
798                        del(newImage)
799                        if self.imageDefault:
800                            Data = copy.copy(self.imageDefault)
801                        Data['showLines'] = True
802                        Data['ring'] = []
803                        Data['rings'] = []
804                        Data['cutoff'] = 10
805                        Data['pixLimit'] = 20
806                        Data['ellipses'] = []
807                        Data['calibrant'] = ''
808                        Data['range'] = [(Imin,Imax),[Imin,Imax]]
809                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Image Controls'),Data)                                           
810                        Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
811                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Masks'),Masks)
812                        self.PatternTree.SelectItem(Id)
813                        self.PatternTree.Expand(Id)
814                        self.PickId = G2gd.GetPatternTreeItemId(self,self.root,outname)
815                        self.Image = self.PickId
816            finally:
817                dlg.Destroy()
818                     
819    def OnAddPhase(self,event):
820        if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
821            sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
822        else:
823            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
824        PhaseName = ''
825        dlg = wx.TextEntryDialog(None,'Enter a name for this phase','Phase Name Entry','New phase',
826            style=wx.OK)
827        if dlg.ShowModal() == wx.ID_OK:
828            PhaseName = dlg.GetValue()
829        dlg.Destroy()
830        sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
831        E,SGData = G2spc.SpcGroup('P 1')
832        self.PatternTree.SetItemPyData(sub, \
833            {'General':{'Name':PhaseName,'Type':'nuclear','SGData':SGData,
834            'Cell':[False,10.,10.,10.,90.,90.,90,1000.],
835            'Pawley dmin':1.0},'Atoms':[],'Drawing':{},'Histograms':{},'Pawley ref':[],'Models':{}})
836       
837    def OnDeletePhase(self,event):
838        if self.dataFrame:
839            self.dataFrame.Clear() 
840        TextList = []
841        DelList = []
842        DelItemList = []
843        if G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
844            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
845        else:
846            return
847        if sub:
848            item, cookie = self.PatternTree.GetFirstChild(sub)
849            while item:
850                TextList.append(self.PatternTree.GetItemText(item))
851                item, cookie = self.PatternTree.GetNextChild(sub, cookie)               
852            dlg = wx.MultiChoiceDialog(self, 'Which phase to delete?', 'Delete phase', TextList, wx.CHOICEDLG_STYLE)
853            try:
854                if dlg.ShowModal() == wx.ID_OK:
855                    result = dlg.GetSelections()
856                    for i in result: DelList.append([i,TextList[i]])
857                    item, cookie = self.PatternTree.GetFirstChild(sub)
858                    i = 0
859                    while item:
860                        if [i,self.PatternTree.GetItemText(item)] in DelList: DelItemList.append(item)
861                        item, cookie = self.PatternTree.GetNextChild(sub, cookie)
862                        i += 1
863                    for item in DelItemList:
864                        name = self.PatternTree.GetItemText(item)
865                        self.PatternTree.Delete(item)
866                        self.G2plotNB.Delete(name)
867            finally:
868                dlg.Destroy()
869               
870    def OnRenameData(self,event):
871        name = self.PatternTree.GetItemText(self.PickId)     
872        if 'PWDR' in name or 'HKLF' in name or 'IMG' in name:
873            dataType = name[:name.index(' ')+1]                 #includes the ' '
874            dlg = wx.TextEntryDialog(self,'Data name: '+dataType,'Change data name',
875                defaultValue=name[name.index(' ')+1:])
876            try:
877                if dlg.ShowModal() == wx.ID_OK:
878                    self.PatternTree.SetItemText(self.PickId,dataType+dlg.GetValue())
879            finally:
880                dlg.Destroy()
881       
882    def OnDataDelete(self, event):
883        TextList = []
884        DelList = []
885        DelItemList = []
886        if self.PatternTree.GetCount():
887            item, cookie = self.PatternTree.GetFirstChild(self.root)
888            while item:
889                name = self.PatternTree.GetItemText(item)
890                if 'PWDR' in name or 'HKLF' in name or 'IMG' in name:
891                    TextList.append(name)
892                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
893            dlg = wx.MultiChoiceDialog(self, 'Which data to delete?', 'Delete data', TextList, wx.CHOICEDLG_STYLE)
894            try:
895                if dlg.ShowModal() == wx.ID_OK:
896                    result = dlg.GetSelections()
897                    for i in result: DelList.append(TextList[i])
898                    item, cookie = self.PatternTree.GetFirstChild(self.root)
899                    while item:
900                        if self.PatternTree.GetItemText(item) in DelList: DelItemList.append(item)
901                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
902                    for item in DelItemList:
903                        self.PatternTree.Delete(item)
904                    G2plt.PlotPatterns(self,True)                        #so plot gets updated
905            finally:
906                dlg.Destroy()
907
908    def OnFileOpen(self, event):
909        result = ''
910        Id = 0
911        if self.PatternTree.GetChildrenCount(self.root,False):
912            if self.dataFrame:
913                self.dataFrame.Clear() 
914            dlg = wx.MessageDialog(self, 'Overwrite?','Project exists!',  wx.OK | wx.CANCEL)
915            try:
916                result = dlg.ShowModal()
917                if result == wx.ID_OK:
918                    self.PatternTree.DeleteChildren(self.root)
919                    self.GSASprojectfile = ''
920                    self.PatternTree.DeleteChildren(self.root)
921                    if self.HKL: self.HKL = []
922                    if self.G2plotNB.plotList:
923                        self.G2plotNB.clear()
924            finally:
925                dlg.Destroy()
926        if result != wx.ID_CANCEL:   
927            if self.dataDisplay: self.dataDisplay.Destroy()
928            dlg = wx.FileDialog(self, 'Choose GSAS-II project file', '.', '', 
929                'GSAS-II project file (*.gpx)|*.gpx',wx.OPEN)
930            if self.dirname: dlg.SetDirectory(self.dirname)
931            try:
932                if dlg.ShowModal() == wx.ID_OK:
933                    self.GSASprojectfile = dlg.GetPath()
934                    self.dirname = dlg.GetDirectory()
935                    G2IO.ProjFileOpen(self)
936                    self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
937                    self.PatternTree.Expand(self.root)
938                    self.HKL = []
939                    item, cookie = self.PatternTree.GetFirstChild(self.root)
940                    while item and not Id:
941                        name = self.PatternTree.GetItemText(item)
942                        if name[:4] in ['PWDR','HKLF','IMG']:
943                            Id = item
944                        elif name == 'Controls':
945                            data = self.PatternTree.GetItemPyData(item)
946                            if data != [0] and data != {}:
947                                self.Refine.Enable(True)
948                                self.Solve.Enable(True)         #not right but something needed here
949                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
950                    if Id:
951                        self.PatternTree.SelectItem(Id)
952            finally:
953                dlg.Destroy()
954
955    def OnFileClose(self, event):
956        if self.dataFrame:
957            self.dataFrame.Clear()
958            self.dataFrame.SetLabel('GSAS-II data display') 
959        dlg = wx.MessageDialog(self, 'Save current project?', ' ', wx.YES | wx.NO | wx.CANCEL)
960        try:
961            result = dlg.ShowModal()
962            if result == wx.ID_OK:
963                self.OnFileSaveMenu(event)
964            if result != wx.ID_CANCEL:
965                self.GSASprojectfile = ''
966                self.PatternTree.SetItemText(self.root,'Loaded Data: ')
967                self.PatternTree.DeleteChildren(self.root)
968                if self.HKL: self.HKL = []
969                if self.G2plotNB.plotList:
970                    self.G2plotNB.clear()
971        finally:
972            dlg.Destroy()
973
974    def OnFileSave(self, event):
975        if self.GSASprojectfile: 
976            self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
977            G2IO.ProjFileSave(self)
978        else:
979            self.OnFileSaveas(event)
980
981    def OnFileSaveas(self, event):
982        dlg = wx.FileDialog(self, 'Choose GSAS-II project file name', '.', '', 
983            'GSAS-II project file (*.gpx)|*.gpx',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
984        if self.dirname:
985            dlg.SetDirectory(self.dirname)
986        try:
987            if dlg.ShowModal() == wx.ID_OK:
988                self.GSASprojectfile = dlg.GetPath()
989                self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
990                G2IO.ProjFileSave(self)
991                self.dirname = dlg.GetDirectory()
992        finally:
993            dlg.Destroy()
994
995    def ExitMain(self, event):
996        if self.undofile:
997            os.remove(self.undofile)
998        sys.exit()
999       
1000    def OnFileExit(self, event):
1001        if self.dataFrame:
1002            self.dataFrame.Clear() 
1003            self.dataFrame.Destroy()
1004        self.Close()
1005       
1006    def OnImportPattern(self,event):
1007            dlg = wx.FileDialog(self, 'Choose nonGSAS powder file', '.', '', 
1008                '(*.*)|*.*',wx.OPEN)
1009            if self.dirname:
1010                dlg.SetDirectory(self.dirname)
1011            try:
1012                if dlg.ShowModal() == wx.ID_OK:
1013                    self.powderfile = dlg.GetPath()
1014                    self.dirname = dlg.GetDirectory()
1015            finally:
1016                dlg.Destroy()
1017               
1018    def OnImportHKL(self,event):
1019            dlg = wx.FileDialog(self, 'Choose structure factor file', '.', '', 
1020                '(*.*)|*.*',wx.OPEN)
1021            if self.dirname:
1022                dlg.SetDirectory(self.dirname)
1023            try:
1024                if dlg.ShowModal() == wx.ID_OK:
1025                    self.HKLfile = dlg.GetPath()
1026                    self.dirname = dlg.GetDirectory()
1027            finally:
1028                dlg.Destroy()
1029       
1030    def OnImportPhase(self,event):
1031            dlg = wx.FileDialog(self, 'Choose GSAS EXP file', '.', '', 
1032                'EXP file (*.EXP)|*.EXP',wx.OPEN)
1033            if self.dirname:
1034                dlg.SetDirectory(self.dirname)
1035            try:
1036                Phase = {}
1037                if dlg.ShowModal() == wx.ID_OK:
1038                    EXPfile = dlg.GetPath()
1039                    self.dirname = dlg.GetDirectory()
1040                    Phase = G2IO.ReadEXPPhase(self,EXPfile)
1041            finally:
1042                dlg.Destroy()
1043            if Phase:
1044                PhaseName = Phase['General']['Name']
1045                if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1046                    sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1047                else:
1048                    sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1049                sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1050                self.PatternTree.SetItemPyData(sub,Phase)
1051               
1052    def OnImportPDB(self,event):
1053            dlg = wx.FileDialog(self, 'Choose PDB file', '.', '', 
1054                'PDB file (*.pdb,*.ent)|*.pdb;*.ent|All files (*.*)|*.*',wx.OPEN)
1055            if self.dirname:
1056                dlg.SetDirectory(self.dirname)
1057            try:
1058                if dlg.ShowModal() == wx.ID_OK:
1059                    PDBfile = dlg.GetPath()
1060                    self.dirname = dlg.GetDirectory()
1061                    Phase = G2IO.ReadPDBPhase(PDBfile)
1062            finally:
1063                dlg.Destroy()
1064            if Phase:
1065                PhaseName = Phase['General']['Name']
1066                if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1067                    sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1068                else:
1069                    sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1070                sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1071                self.PatternTree.SetItemPyData(sub,Phase)       
1072       
1073    def OnImportCIF(self,event):
1074            dlg = wx.FileDialog(self, 'Choose CIF file', '.', '', 
1075                'CIF file (*.cif)|*.cif',wx.OPEN)
1076            if self.dirname:
1077                dlg.SetDirectory(self.dirname)
1078            try:
1079                if dlg.ShowModal() == wx.ID_OK:
1080                    CIFfile = dlg.GetPath()
1081                    self.dirname = dlg.GetDirectory()
1082                    Phase = G2IO.ReadCIFPhase(CIFfile)
1083            finally:
1084                dlg.Destroy()
1085            if Phase:
1086                PhaseName = Phase['General']['Name']
1087                if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1088                    sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1089                else:
1090                    sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1091                sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1092                self.PatternTree.SetItemPyData(sub,Phase)       
1093       
1094    def OnExportPattern(self,event):
1095        dlg = wx.FileDialog(self, 'Choose output powder file name', '.', '', 
1096            'GSAS fxye file (*.fxye)|*.fxye|xye file (*.xye)|*.xye',
1097            wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
1098        if self.dirname:
1099            dlg.SetDirectory(self.dirname)
1100        try:
1101            if dlg.ShowModal() == wx.ID_OK:
1102                powderfile = dlg.GetPath()
1103                if 'fxye' in powderfile:
1104                    G2IO.powderFxyeSave(self,powderfile)
1105                else:       #just xye
1106                    G2IO.powderXyeSave(self,powderfile)
1107                self.dirname = dlg.GetDirectory()
1108        finally:
1109            dlg.Destroy()
1110       
1111    def OnExportPeakList(self,event):
1112        dlg = wx.FileDialog(self, 'Choose output peak list file name', '.', '', 
1113            '(*.*)|*.*',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
1114        if self.dirname:
1115            dlg.SetDirectory(self.dirname)
1116        try:
1117            if dlg.ShowModal() == wx.ID_OK:
1118                self.peaklistfile = dlg.GetPath()
1119                file = open(self.peaklistfile,'w')               
1120                item, cookie = self.PatternTree.GetFirstChild(self.root)
1121                while item:
1122                    name = self.PatternTree.GetItemText(item)
1123                    if 'PWDR' in name:
1124                        item2, cookie2 = self.PatternTree.GetFirstChild(item)
1125                        while item2:
1126                            name2 = self.PatternTree.GetItemText(item2)
1127                            if name2 == 'Peak List':
1128                                peaks = self.PatternTree.GetItemPyData(item2)
1129                                file.write("%s \n" % (name+' Peak List'))               
1130                                for peak in peaks:
1131                                    file.write("%10.4f %12.2f %10.3f %10.3f \n" % \
1132                                        (peak[0],peak[2],peak[4],peak[6]))
1133                            item2, cookie2 = self.PatternTree.GetNextChild(item, cookie2)                           
1134                    item, cookie = self.PatternTree.GetNextChild(self.root, cookie)                           
1135                file.close()
1136                self.dirname = dlg.GetDirectory()
1137        finally:
1138            dlg.Destroy()
1139       
1140    def OnExportHKL(self,event):
1141        event.Skip()
1142       
1143    def OnExportPhase(self,event):
1144        event.Skip()
1145       
1146    def OnExportCIF(self,event):
1147        event.Skip()
1148       
1149    def OnRefine(self,event):
1150        #works - but it'd be better if it could restore plots
1151        G2str.Refine(self.GSASprojectfile)
1152        dlg = wx.MessageDialog(self,'Load new result?','Refinement results',wx.OK|wx.CANCEL)
1153        try:
1154            if dlg.ShowModal() == wx.ID_OK:
1155                self.PatternTree.DeleteChildren(self.root)
1156                if self.HKL: self.HKL = []
1157                if self.G2plotNB.plotList:
1158                    self.G2plotNB.clear()
1159                G2IO.ProjFileOpen(self)
1160        finally:
1161            dlg.Destroy()
1162       
1163    def OnSolve(self,event):
1164        #works - but it'd be better if it could restore plots
1165        G2sol.Solve(self.GSASprojectfile)
1166        dlg = wx.MessageDialog(self,'Load new result?','Structure solution results',wx.OK|wx.CANCEL)
1167        try:
1168            if dlg.ShowModal() == wx.ID_OK:
1169                self.PatternTree.DeleteChildren(self.root)
1170                if self.HKL: self.HKL = []
1171                if self.G2plotNB.plotList:
1172                    self.G2plotNB.clear()
1173                G2IO.ProjFileOpen(self)
1174        finally:
1175            dlg.Destroy()
1176       
1177    def ErrorDialog(self,title,message):
1178        dlg = wx.MessageDialog(self, message, title,  wx.OK)
1179        try:
1180            result = dlg.ShowModal()
1181        finally:
1182            dlg.Destroy()
1183
1184    def OnHelpHelp(self, event):
1185        event.Skip()
1186       
1187    def OnHelpAbout(self, event):
1188        info = wx.AboutDialogInfo()
1189        info.Name = 'GSAS-II'
1190        info.Version = __version__
1191        info.Copyright = '''
1192Robert B. Von Dreele
1193Argonne National Laboratory(C)
1194This product includes software developed
1195by the UChicago Argonne, LLC, as
1196Operator of Argonne National Laboratory.         '''
1197        info.Description = '''
1198General Structure Analysis System - II
1199        '''
1200        wx.AboutBox(info)
1201       
1202class GSASIImain(wx.App):
1203    def OnInit(self):
1204        self.main = GSASII(None)
1205        self.main.Show()
1206        self.SetTopWindow(self.main)
1207        return True
1208
1209def main():
1210    application = GSASIImain(0)
1211    application.MainLoop()
1212
1213if __name__ == '__main__':
1214    main()
Note: See TracBrowser for help on using the repository browser.