source: trunk/GSASII.py @ 327

Last change on this file since 327 was 327, checked in by vondreele, 12 years ago

fix to path name for atomdata.dat
fix to texture display - can't have colorbars!
put in bit to show #threads used

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