source: trunk/GSASII.py @ 240

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

reworked menu of image file types in FileDialog?
allow nonsquare image sizes
implement fit2D tiff files
refactor tiff image input

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