source: trunk/GSASII.py @ 336

Last change on this file since 336 was 336, checked in by toby, 11 years ago

Make MKL optional

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