source: trunk/GSASII.py @ 193

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

various fixes, but still bugs.
GSASII.py - add more sample parameters
GSASIIgrid.py - add save/load image controls; turn image plot back on
GSASIIimgGUI.py - load/save image controls
GSASIIIO.py - find 'Temp' in comments & load value as Temperature
GSASIIlattice.py - change 'laue' to 'SGLaue'
GSASIIphsGUI.py - change mustrain GUI
GSASIIplot.py - fix point picking in powder plots, add mustrain surface plotting
GSASIIspc.py - add conversion of isotropic to generalized mustrain converter (doesn't work yet)

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