source: trunk/GSASII.py @ 237

Last change on this file since 237 was 237, checked in by vondreele, 11 years ago

add new data types SXAS & REFL

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