source: trunk/GSASII.py @ 267

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

removed azm rotation - didn't work
fix azimuthal polarization

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