source: trunk/GSASII.py @ 292

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

allow more than one phase for calibration
fix temperature reading from 11BM header

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