source: trunk/GSASII.py @ 465

Last change on this file since 465 was 465, checked in by vondreele, 10 years ago

a bit more on directories

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