source: trunk/GSASII.py @ 289

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