source: trunk/GSASII.py @ 264

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

begin implementation of pdf generation - work in progress
modify image to have azimuth=0 as vertical "up"
add textctrls for max and min image intensity
fix to some lattice parameter defaults for some Laue groups

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