source: trunk/GSASII.py @ 271

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

make g77 versions of fortran for binwin2.7 - faster than gfortran!
fix to histogram2d.for
GSASII.py - allow 2D offset in multiplots, fix for large file lists
GSASIIimgGUI.py - more stuff in save/load controls
GSASIIplot.py - 2D offset in multiplots, fix bad behavior in structure drawings
GSASIIpwd.py - more mods to PDF calcs

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