source: trunk/GSASIIpwdGUI.py @ 1107

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

make reflist np.array
fix bug - hfx+'Type' needs to be in parmDict

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 116.2 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASIIpwdGUI - powder data display routines
3########### SVN repository information ###################
4# $Date: 2013-10-15 20:01:21 +0000 (Tue, 15 Oct 2013) $
5# $Author: vondreele $
6# $Revision: 1107 $
7# $URL: trunk/GSASIIpwdGUI.py $
8# $Id: GSASIIpwdGUI.py 1107 2013-10-15 20:01:21Z vondreele $
9########### SVN repository information ###################
10'''
11*GSASIIpwdGUI: Powder Pattern GUI routines*
12-------------------------------------------
13
14Used to define GUI controls for the routines that interact
15with the powder histogram (PWDR) data tree items.
16
17'''
18import sys
19import os.path
20import wx
21import wx.grid as wg
22import numpy as np
23import numpy.ma as ma
24import math
25import time
26import copy
27import random as ran
28import cPickle
29import GSASIIpath
30GSASIIpath.SetVersionNumber("$Revision: 1107 $")
31import GSASIImath as G2mth
32import GSASIIpwd as G2pwd
33import GSASIIIO as G2IO
34import GSASIIlattice as G2lat
35import GSASIIspc as G2spc
36import GSASIIindex as G2indx
37import GSASIIplot as G2plt
38import GSASIIgrid as G2gd
39import GSASIIElemGUI as G2elemGUI
40import GSASIIElem as G2elem
41VERY_LIGHT_GREY = wx.Colour(235,235,235)
42# trig functions in degrees
43sind = lambda x: math.sin(x*math.pi/180.)
44tand = lambda x: math.tan(x*math.pi/180.)
45cosd = lambda x: math.cos(x*math.pi/180.)
46asind = lambda x: 180.*math.asin(x)/math.pi
47   
48def IsHistogramInAnyPhase(G2frame,histoName):
49    'Needs a doc string'
50    phases = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases')
51    if phases:
52        item, cookie = G2frame.PatternTree.GetFirstChild(phases)
53        while item:
54            data = G2frame.PatternTree.GetItemPyData(item)
55            histoList = data['Histograms'].keys()
56            if histoName in histoList:
57                return True
58            item, cookie = G2frame.PatternTree.GetNextChild(phases, cookie)
59        return False
60    else:
61        return False
62
63def SetDefaultSample():
64    'Needs a doc string'
65    return {'ranId':ran.randint(0,sys.maxint),
66        'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],
67        'DisplaceX':[0.0,False],'DisplaceY':[0.0,False],'Diffuse':[],
68        'Temperature':300.,'Pressure':1.0,'Humidity':0.0,
69        'Voltage':0.0,'Force':0.0,'Gonio. radius':200.0,
70        'Omega':0.0,'Chi':0.0,'Phi':0.0}
71                         
72################################################################################
73#####  Powder Peaks
74################################################################################           
75       
76def UpdatePeakGrid(G2frame, data):
77    '''respond to selection of PWDR powder peaks data tree item.
78    '''
79    if G2frame.dataDisplay:
80        G2frame.dataFrame.Clear()
81       
82    def OnAutoSearch(event):
83        PatternId = G2frame.PatternId
84        PickId = G2frame.PickId
85        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
86        inst,inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
87        profile = G2frame.PatternTree.GetItemPyData(PatternId)[1]
88        x0 = profile[0]
89        iBeg = np.searchsorted(x0,limits[0])
90        iFin = np.searchsorted(x0,limits[1])
91        x = x0[iBeg:iFin]
92        y0 = profile[1][iBeg:iFin]
93        y1 = copy.copy(y0)
94        ysig = np.std(y1)
95        offset = [-1,1]
96        ymask = ma.array(y0,mask=(y0<ysig))
97        for off in offset:
98            ymask = ma.array(ymask,mask=(ymask-np.roll(y0,off)<=0.))
99        indx = ymask.nonzero()
100        mags = ymask[indx]
101        poss = x[indx]
102        refs = zip(poss,mags)
103        refs = G2mth.sortArray(refs,0,reverse=True)
104        for i,ref1 in enumerate(refs):
105            for ref2 in refs[i+1:]:
106                if abs(ref2[0]-ref1[0]) < 0.1*G2pwd.getFWHM(ref1[0],inst):
107                    del(refs[i])   
108        refs = G2mth.sortArray(refs,1,reverse=True)
109        for pos,mag in refs:
110            data.append(G2mth.setPeakparms(inst,inst2,pos,mag))
111        UpdatePeakGrid(G2frame,data)
112        G2plt.PlotPatterns(G2frame)       
113   
114    def OnUnDo(event):
115        DoUnDo()
116        G2frame.dataFrame.UnDo.Enable(False)
117       
118    def DoUnDo():
119        print 'Undo last refinement'
120        file = open(G2frame.undofile,'rb')
121        PatternId = G2frame.PatternId
122        for item in ['Background','Instrument Parameters','Peak List']:
123            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item),cPickle.load(file))
124            if G2frame.dataDisplay.GetName() == item:
125                if item == 'Background':
126                    UpdateBackground(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
127                elif item == 'Instrument Parameters':
128                    UpdateInstrumentGrid(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
129                elif item == 'Peak List':
130                    UpdatePeakGrid(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
131            print item,' recovered'
132        file.close()
133       
134    def SaveState():
135        G2frame.undofile = os.path.join(G2frame.dirname,'GSASII.save')
136        file = open(G2frame.undofile,'wb')
137        PatternId = G2frame.PatternId
138        for item in ['Background','Instrument Parameters','Peak List']:
139            cPickle.dump(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,item)),file,1)
140        file.close()
141        G2frame.dataFrame.UnDo.Enable(True)
142       
143    def OnLSQPeakFit(event):
144        if not G2frame.GSASprojectfile:            #force a save of the gpx file so SaveState can wirte in the same directory
145            G2frame.OnFileSaveas(event)
146        OnPeakFit('LSQ')
147       
148    def OnOneCycle(event):
149        OnPeakFit('LSQ',oneCycle=True)
150       
151    def OnClearPeaks(event):
152        dlg = wx.MessageDialog(G2frame,'Delete all peaks?','Clear peak list',wx.OK|wx.CANCEL)
153        try:
154            if dlg.ShowModal() == wx.ID_OK:
155                peaks = []
156        finally:
157            dlg.Destroy()
158        UpdatePeakGrid(G2frame,peaks)
159        G2plt.PlotPatterns(G2frame)
160       
161    def OnPeakFit(FitPgm,oneCycle=False):
162        SaveState()
163        controls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Controls'))
164        if not controls:
165            controls = {'deriv type':'analytic','min dM/M':0.0001,}     #fill in defaults if needed
166        print 'Peak Fitting with '+controls['deriv type']+' derivatives:'
167        PatternId = G2frame.PatternId
168        PickId = G2frame.PickId
169        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'))
170        if not peaks:
171            G2frame.ErrorDialog('No peaks!','Nothing to fit!')
172            return
173        background = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Background'))
174        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
175        inst,inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
176        data = G2frame.PatternTree.GetItemPyData(PatternId)[1]
177        wx.BeginBusyCursor()
178        dlg = wx.ProgressDialog('Residual','Peak fit Rwp = ',101.0, 
179            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT)
180        screenSize = wx.ClientDisplayRect()
181        Size = dlg.GetSize()
182        dlg.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
183        try:
184            G2pwd.DoPeakFit(FitPgm,peaks,background,limits,inst,inst2,data,oneCycle,controls,dlg)
185        finally:
186            wx.EndBusyCursor()   
187        UpdatePeakGrid(G2frame,peaks)
188        G2plt.PlotPatterns(G2frame)
189        print 'finished'
190        return
191       
192    def OnResetSigGam(event):
193        PatternId = G2frame.PatternId
194        PickId = G2frame.PickId
195        Inst,Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
196        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'))
197        if not peaks:
198            G2frame.ErrorDialog('No peaks!','Nothing to do!')
199            return
200        newpeaks = []
201        for peak in peaks:
202            newpeaks.append(G2mth.setPeakparms(Inst,Inst2,peak[0],peak[2]))
203        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'),newpeaks)
204        UpdatePeakGrid(G2frame,newpeaks)
205               
206    def RefreshPeakGrid(event):
207        r,c =  event.GetRow(),event.GetCol()
208       
209        event.StopPropagation()
210        data = G2frame.PeakTable.GetData()
211        T = []
212        for peak in data:T.append(peak[0])
213        D = dict(zip(T,data))
214        T.sort()
215        X = []
216        for key in T: X.append(D[key])
217        data = X       
218       
219    def setBackgroundColors():
220       for r in range(G2frame.dataDisplay.GetNumberRows()):
221           for c in range(G2frame.dataDisplay.GetNumberCols()):
222               if G2frame.dataDisplay.GetColLabelValue(c) in ['position','intensity','alpha','beta','sigma','gamma']:
223                   if float(G2frame.dataDisplay.GetCellValue(r,c)) < 0.:
224                       G2frame.dataDisplay.SetCellBackgroundColour(r,c,wx.RED)
225                   else:
226                       G2frame.dataDisplay.SetCellBackgroundColour(r,c,wx.WHITE)
227                                                 
228    def KeyEditPeakGrid(event):
229        rowList = G2frame.dataDisplay.GetSelectedRows()
230        colList = G2frame.dataDisplay.GetSelectedCols()
231        selectList = G2frame.dataDisplay.GetSelectedCells()
232        data = G2frame.PatternTree.GetItemPyData(G2frame.PickId)
233        if event.GetKeyCode() == wx.WXK_RETURN:
234            event.Skip(True)
235        elif event.GetKeyCode() == wx.WXK_CONTROL:
236            event.Skip(True)
237        elif event.GetKeyCode() == wx.WXK_SHIFT:
238            event.Skip(True)
239        elif rowList:
240            G2frame.dataDisplay.ClearSelection()
241            if event.GetKeyCode() == wx.WXK_DELETE:
242                G2frame.dataDisplay.ClearGrid()
243                rowList.sort()
244                rowList.reverse()
245                nDel = 0
246                for row in rowList:
247                    G2frame.PeakTable.DeleteRow(row)
248                    nDel += 1
249                if nDel:
250                    msg = wg.GridTableMessage(G2frame.PeakTable, 
251                        wg.GRIDTABLE_NOTIFY_ROWS_DELETED,0,nDel)
252                    G2frame.dataDisplay.ProcessTableMessage(msg)
253                data = G2frame.PeakTable.GetData()
254                G2frame.PatternTree.SetItemPyData(G2frame.PickId,data[:-nDel])
255                G2frame.dataDisplay.ForceRefresh()
256                setBackgroundColors()
257                if not len(G2frame.PatternTree.GetItemPyData(G2frame.PickId)): 
258                    G2frame.dataFrame.PeakFit.Enable(False)
259                       
260        elif colList:
261            G2frame.dataDisplay.ClearSelection()
262            key = event.GetKeyCode()
263            for col in colList:
264                if G2frame.PeakTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
265                    if key == 89: #'Y'
266                        for row in range(G2frame.PeakTable.GetNumberRows()): data[row][col]=True
267                    elif key == 78:  #'N'
268                        for row in range(G2frame.PeakTable.GetNumberRows()): data[row][col]=False
269        elif selectList:
270            G2frame.dataDisplay.ClearSelection()
271            key = event.GetKeyCode()
272            for row,col in selectList:
273                if G2frame.PeakTable.GetTypeName(row,col) == wg.GRID_VALUE_BOOL:
274                    if key == 89: #'Y'
275                        data[row][col]=True
276                    elif key == 78:  #'N'
277                        data[row][col]=False
278        G2plt.PlotPatterns(G2frame)
279           
280    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.PeakMenu)
281    if not G2frame.dataFrame.GetStatusBar():
282        Status = G2frame.dataFrame.CreateStatusBar()
283    Status.SetStatusText('Global refine: select refine column & press Y or N')
284    G2frame.Bind(wx.EVT_MENU, OnAutoSearch, id=G2gd.wxID_AUTOSEARCH)
285    G2frame.Bind(wx.EVT_MENU, OnUnDo, id=G2gd.wxID_UNDO)
286    G2frame.Bind(wx.EVT_MENU, OnLSQPeakFit, id=G2gd.wxID_LSQPEAKFIT)
287    G2frame.Bind(wx.EVT_MENU, OnOneCycle, id=G2gd.wxID_LSQONECYCLE)
288    G2frame.Bind(wx.EVT_MENU, OnClearPeaks, id=G2gd.wxID_CLEARPEAKS)
289    G2frame.Bind(wx.EVT_MENU, OnResetSigGam, id=G2gd.wxID_RESETSIGGAM)
290    G2frame.dataFrame.PeakFit.Enable(False)
291    if data:
292        G2frame.dataFrame.PeakFit.Enable(True)
293        G2frame.dataFrame.PFOneCycle.Enable(True)
294    G2frame.PickTable = []
295    rowLabels = []
296    PatternId = G2frame.PatternId
297    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))[0]
298    for i in range(len(data)): rowLabels.append(str(i+1))
299    if 'C' in Inst['Type'][0]:
300        colLabels = ['position','refine','intensity','refine','sigma','refine','gamma','refine']
301        Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
302            wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
303            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
304            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
305    else:
306        colLabels = ['position','refine','intensity','refine','alpha','refine',
307            'beta','refine','sigma','refine','gamma','refine']
308        Types = [wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
309            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
310            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
311            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
312            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
313            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
314    T = []
315    for peak in data:
316        T.append(peak[0])
317    D = dict(zip(T,data))
318    T.sort()
319    X = []
320    for key in T: X.append(D[key])
321    data = X
322    G2frame.PatternTree.SetItemPyData(G2frame.PickId,data)
323    G2frame.PeakTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
324    G2frame.dataFrame.SetLabel('Peak List')
325    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)
326    G2frame.dataDisplay.SetTable(G2frame.PeakTable, True)
327    setBackgroundColors()                         
328    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshPeakGrid)
329    G2frame.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
330    G2frame.dataDisplay.SetMargins(0,0)
331    G2frame.dataDisplay.AutoSizeColumns(False)
332    G2frame.dataFrame.setSizePosLeft([535,350])
333       
334################################################################################
335#####  Background
336################################################################################           
337       
338def UpdateBackground(G2frame,data):
339    '''respond to selection of PWDR background data tree item.
340    '''
341    if len(data) < 2:       #add Debye diffuse & peaks scattering here
342        data.append({'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]})
343    if 'nPeaks' not in data[1]:
344        data[1].update({'nPeaks':0,'peaksList':[]})
345    ValObj = {}
346   
347    def OnBackFlagCopy(event):
348        flag = data[0][1]
349        backDict = data[-1]
350        if backDict['nDebye']:
351            DBflags = []
352            for term in backDict['debyeTerms']:
353                DBflags.append(term[1::2])
354        if backDict['nPeaks']:
355            PKflags = []
356            for term in backDict['peaksList']:
357                PKflags.append(term[1::2])           
358        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
359        copyList = []
360        dlg = wx.MultiChoiceDialog(G2frame, 
361            'Copy refinement flags to which histograms?', 'Copy flags', 
362            histList, wx.CHOICEDLG_STYLE)
363        try:
364            if dlg.ShowModal() == wx.ID_OK:
365                result = dlg.GetSelections()
366                for i in result: 
367                    copyList.append(histList[i])
368                if 'All' in copyList: 
369                    copyList = histList[1:]
370            for item in copyList:
371                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
372                backData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Background'))
373                backData[0][1] = copy.copy(flag)
374                bkDict = backData[-1]
375                if bkDict['nDebye'] == backDict['nDebye']:
376                    for i,term in enumerate(bkDict['debyeTerms']):
377                        term[1::2] = copy.copy(DBflags[i])
378                if bkDict['nPeaks'] == backDict['nPeaks']:
379                    for i,term in enumerate(bkDict['peaksList']):
380                        term[1::2] = copy.copy(PKflags[i])                   
381        finally:
382            dlg.Destroy()
383           
384    def OnBackCopy(event):
385        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
386        copyList = []
387        dlg = wx.MultiChoiceDialog(G2frame, 
388            'Copy parameters to which histograms?', 'Copy parameters', 
389            histList, wx.CHOICEDLG_STYLE)
390        try:
391            if dlg.ShowModal() == wx.ID_OK:
392                result = dlg.GetSelections()
393                for i in result: 
394                    copyList.append(histList[i])
395                if 'All' in copyList: 
396                    copyList = histList[1:]
397            for item in copyList:
398                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
399                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Background'),
400                    copy.copy(data))
401        finally:
402            dlg.Destroy()
403       
404    def BackSizer():
405       
406        def OnNewType(event):
407            data[0][0] = bakType.GetValue()
408           
409        def OnBakRef(event):
410            data[0][1] = bakRef.GetValue()
411           
412        def OnBakTerms(event):
413            data[0][2] = int(bakTerms.GetValue())
414            M = len(data[0])
415            N = data[0][2]+3
416            item = data[0]
417            if N > M:       #add terms
418                for i in range(M,N): 
419                    item.append(0.0)
420            elif N < M:     #delete terms
421                for i in range(N,M):
422                    del(item[-1])
423            G2frame.PatternTree.SetItemPyData(BackId,data)
424            wx.CallAfter(UpdateBackground,G2frame,data)
425           
426        def OnBakVal(event):
427            Obj = event.GetEventObject()
428            item = ValObj[Obj.GetId()][0]
429            try:
430                value = float(Obj.GetValue())
431            except ValueError:
432                value = data[0][item]
433            data[0][item] = value
434            Obj.SetValue('%10.4f'%(value))
435       
436        backSizer = wx.BoxSizer(wx.VERTICAL)
437        topSizer = wx.BoxSizer(wx.HORIZONTAL)
438        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background function: '),0,wx.ALIGN_CENTER_VERTICAL)
439        bakType = wx.ComboBox(G2frame.dataDisplay,value=data[0][0],
440                choices=Choices,style=wx.CB_READONLY|wx.CB_DROPDOWN)
441        bakType.Bind(wx.EVT_COMBOBOX, OnNewType)
442        topSizer.Add(bakType)
443        topSizer.Add((5,0),0)
444        bakRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
445        bakRef.SetValue(bool(data[0][1]))
446        bakRef.Bind(wx.EVT_CHECKBOX, OnBakRef)
447        topSizer.Add(bakRef,0,wx.ALIGN_CENTER_VERTICAL)
448        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. coeff.: '),0,wx.ALIGN_CENTER_VERTICAL)
449        bakTerms = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[0][2]),choices=[str(i+1) for i in range(36)],
450            style=wx.CB_READONLY|wx.CB_DROPDOWN)
451        bakTerms.Bind(wx.EVT_COMBOBOX,OnBakTerms)
452        topSizer.Add(bakTerms,0,wx.ALIGN_CENTER_VERTICAL)
453        topSizer.Add((5,0),0)
454        backSizer.Add(topSizer)
455        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background coefficients:'),0,wx.ALIGN_CENTER_VERTICAL)
456        bakSizer = wx.FlexGridSizer(1,5,5,5)
457        for i,value in enumerate(data[0][3:]):
458            bakVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.4f'%(value),style=wx.TE_PROCESS_ENTER)
459            bakSizer.Add(bakVal,0,wx.ALIGN_CENTER_VERTICAL)
460            ValObj[bakVal.GetId()] = [i+3]
461            bakVal.Bind(wx.EVT_TEXT_ENTER,OnBakVal)
462            bakVal.Bind(wx.EVT_KILL_FOCUS,OnBakVal)
463        backSizer.Add(bakSizer)
464        return backSizer
465       
466    def DebyeSizer():
467       
468        def OnDebTerms(event):
469            data[1]['nDebye'] = int(debTerms.GetValue())
470            M = len(data[1]['debyeTerms'])
471            N = data[1]['nDebye']
472            if N > M:       #add terms
473                for i in range(M,N): 
474                    data[1]['debyeTerms'].append([1.0,False,1.0,False,0.010,False])
475            elif N < M:     #delete terms
476                for i in range(N,M):
477                    del(data[1]['debyeTerms'][-1])
478            wx.CallAfter(UpdateBackground,G2frame,data)
479           
480        def KeyEditPeakGrid(event):
481            colList = debyeGrid.GetSelectedCols()
482            if event.GetKeyCode() == wx.WXK_RETURN:
483                event.Skip(True)
484            elif event.GetKeyCode() == wx.WXK_CONTROL:
485                event.Skip(True)
486            elif event.GetKeyCode() == wx.WXK_SHIFT:
487                event.Skip(True)
488            elif colList:
489                debyeGrid.ClearSelection()
490                key = event.GetKeyCode()
491                for col in colList:
492                    if debyeTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
493                        if key == 89: #'Y'
494                            for row in range(debyeGrid.GetNumberRows()): data[1]['debyeTerms'][row][col]=True
495                        elif key == 78:  #'N'
496                            for row in range(debyeGrid.GetNumberRows()): data[1]['debyeTerms'][row][col]=False
497
498       
499        debSizer = wx.BoxSizer(wx.VERTICAL)
500        topSizer = wx.BoxSizer(wx.HORIZONTAL)
501        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Debye scattering: '),0,wx.ALIGN_CENTER_VERTICAL)
502        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. coeff.: '),0,wx.ALIGN_CENTER_VERTICAL)
503        debTerms = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[1]['nDebye']),choices=[str(i) for i in range(12)],
504            style=wx.CB_READONLY|wx.CB_DROPDOWN)
505        debTerms.Bind(wx.EVT_COMBOBOX,OnDebTerms)
506        topSizer.Add(debTerms,0,wx.ALIGN_CENTER_VERTICAL)
507        topSizer.Add((5,0),0)
508        debSizer.Add(topSizer)
509        if data[1]['nDebye']:
510            debSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Debye diffuse terms:'),0,wx.ALIGN_CENTER_VERTICAL)       
511            rowLabels = []
512            for i in range(len(data[1]['debyeTerms'])): rowLabels.append(str(i))
513            colLabels = ['A','refine','R','refine','U','refine']
514            Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL,
515            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
516            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
517            debyeTable = G2gd.Table(data[1]['debyeTerms'],rowLabels=rowLabels,colLabels=colLabels,types=Types)
518            debyeGrid = G2gd.GSGrid(parent=G2frame.dataDisplay)
519            debyeGrid.SetTable(debyeTable, True)
520            debyeGrid.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
521            debyeGrid.AutoSizeColumns(False)
522            debSizer.Add(debyeGrid)       
523        return debSizer
524     
525    def PeaksSizer():
526
527        def OnPeaks(event):
528            data[1]['nPeaks'] = int(peaks.GetValue())
529            M = len(data[1]['peaksList'])
530            N = data[1]['nPeaks']
531            if N > M:       #add terms
532                for i in range(M,N): 
533                    data[1]['peaksList'].append([1.0,False,1.0,False,0.10,False,0.10,False])
534            elif N < M:     #delete terms
535                for i in range(N,M):
536                    del(data[1]['peaksList'][-1])
537            wx.CallAfter(UpdateBackground,G2frame,data)
538           
539        def KeyEditPeakGrid(event):
540            colList = peaksGrid.GetSelectedCols()
541            if event.GetKeyCode() == wx.WXK_RETURN:
542                event.Skip(True)
543            elif event.GetKeyCode() == wx.WXK_CONTROL:
544                event.Skip(True)
545            elif event.GetKeyCode() == wx.WXK_SHIFT:
546                event.Skip(True)
547            elif colList:
548                peaksGrid.ClearSelection()
549                key = event.GetKeyCode()
550                for col in colList:
551                    if peaksTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
552                        if key == 89: #'Y'
553                            for row in range(peaksGrid.GetNumberRows()): data[1]['peaksList'][row][col]=True
554                        elif key == 78:  #'N'
555                            for row in range(peaksGrid.GetNumberRows()): data[1]['peaksList'][row][col]=False
556
557        peaksSizer = wx.BoxSizer(wx.VERTICAL)
558        topSizer = wx.BoxSizer(wx.HORIZONTAL)
559        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Peaks in background: '),0,wx.ALIGN_CENTER_VERTICAL)
560        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. peaks: '),0,wx.ALIGN_CENTER_VERTICAL)
561        peaks = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[1]['nPeaks']),choices=[str(i) for i in range(12)],
562            style=wx.CB_READONLY|wx.CB_DROPDOWN)
563        peaks.Bind(wx.EVT_COMBOBOX,OnPeaks)
564        topSizer.Add(peaks,0,wx.ALIGN_CENTER_VERTICAL)
565        topSizer.Add((5,0),0)
566        peaksSizer.Add(topSizer)
567        if data[1]['nPeaks']:
568            peaksSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Peak list:'),0,wx.ALIGN_CENTER_VERTICAL)       
569            rowLabels = []
570            for i in range(len(data[1]['peaksList'])): rowLabels.append(str(i))
571            colLabels = ['pos','refine','int','refine','sig','refine','gam','refine']
572            Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL,
573            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
574            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
575            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
576            peaksTable = G2gd.Table(data[1]['peaksList'],rowLabels=rowLabels,colLabels=colLabels,types=Types)
577            peaksGrid = G2gd.GSGrid(parent=G2frame.dataDisplay)
578            peaksGrid.SetTable(peaksTable, True)
579            peaksGrid.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
580            peaksGrid.AutoSizeColumns(False)
581            peaksSizer.Add(peaksGrid)       
582        return peaksSizer
583               
584    if G2frame.dataDisplay:
585#        G2frame.dataFrame.Clear()
586        G2frame.dataFrame.DestroyChildren()
587    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
588    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.BackMenu)
589    G2frame.dataFrame.SetLabel('Background')
590    if not G2frame.dataFrame.GetStatusBar():
591        Status = G2frame.dataFrame.CreateStatusBar()
592    G2frame.Bind(wx.EVT_MENU,OnBackCopy,id=G2gd.wxID_BACKCOPY)
593    G2frame.Bind(wx.EVT_MENU,OnBackFlagCopy,id=G2gd.wxID_BACKFLAGCOPY)
594    BackId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Background')
595    Choices = ['chebyschev','cosine','lin interpolate','inv interpolate','log interpolate']
596    mainSizer = wx.BoxSizer(wx.VERTICAL)
597    mainSizer.Add(BackSizer())
598    mainSizer.Add((0,5),0)
599    mainSizer.Add(DebyeSizer())
600    mainSizer.Add((0,5),0)
601    mainSizer.Add(PeaksSizer())
602    mainSizer.Layout()   
603    G2frame.dataDisplay.SetSizer(mainSizer)
604    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
605       
606################################################################################
607#####  Limits
608################################################################################           
609       
610def UpdateLimitsGrid(G2frame, data):
611    '''respond to selection of PWDR Limits data tree item.
612    '''
613    if G2frame.dataDisplay:
614        G2frame.dataFrame.Clear()
615    G2frame.ifGetExclude = False
616       
617    def KeyEditPeakGrid(event):
618        if event.GetKeyCode() == wx.WXK_DELETE:
619            row = G2frame.dataDisplay.GetSelectedRows()[0]
620            if row > 1: #can't delete limits!
621                del(data[row])
622                wx.CallAfter(UpdateLimitsGrid,G2frame,data)
623                G2plt.PlotPatterns(G2frame)
624                       
625    def RefreshLimitsGrid(event):
626        event.StopPropagation()
627        data = G2frame.LimitsTable.GetData()
628        old = data[0]
629        new = data[1]
630        new[0] = max(old[0],new[0])
631        new[1] = max(new[0],min(old[1],new[1]))
632        excl = []
633        if len(data) > 2:
634            excl = data[2:]
635            for item in excl:
636                item[0] = max(old[0],item[0])
637                item[1] = max(item[0],min(old[1],item[1]))
638        data = [old,new]+excl
639        G2frame.LimitsTable.SetData(data)
640        G2plt.PlotPatterns(G2frame)
641       
642    def OnLimitCopy(event):
643        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
644        copyList = []
645        dlg = wx.MultiChoiceDialog(G2frame, 
646            'Copy limits to which histograms?', 'Copy limits', 
647            histList, wx.CHOICEDLG_STYLE)
648        try:
649            if dlg.ShowModal() == wx.ID_OK:
650                result = dlg.GetSelections()
651                for i in result: 
652                    copyList.append(histList[i])
653                if 'All' in copyList: 
654                    copyList = histList[1:]
655            for item in copyList:
656                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
657                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Limits'),
658                    copy.copy(data))
659        finally:
660            dlg.Destroy()
661           
662    def OnAddExcl(event):
663        G2frame.ifGetExclude = True
664        print 'Add excluded region'
665       
666    G2frame.LimitsTable = []
667    colLabels = ['Tmin','Tmax']
668    rowLabels = ['original','changed']
669    for i in range(len(data)-2):
670        rowLabels.append('exclude')
671    Types = 2*[wg.GRID_VALUE_FLOAT+':10,3',]
672    G2frame.LimitsTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
673    G2frame.dataFrame.SetLabel('Limits')
674    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.LimitMenu)
675    if not G2frame.dataFrame.GetStatusBar():
676        Status = G2frame.dataFrame.CreateStatusBar()
677    G2frame.Bind(wx.EVT_MENU,OnLimitCopy,id=G2gd.wxID_LIMITCOPY)
678    G2frame.Bind(wx.EVT_MENU,OnAddExcl,id=G2gd.wxID_ADDEXCLREGION)   
679    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)
680    G2frame.dataDisplay.SetTable(G2frame.LimitsTable, True)
681    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshLimitsGrid)               
682    G2frame.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
683    G2frame.dataDisplay.SetMargins(0,0)
684    G2frame.dataDisplay.AutoSizeColumns(False)
685    G2frame.dataFrame.setSizePosLeft([230,260])
686   
687################################################################################
688#####  Instrument parameters
689################################################################################           
690       
691def UpdateInstrumentGrid(G2frame,data):
692    '''respond to selection of PWDR Instrument Parameters
693    data tree item.
694    '''
695    def keycheck(keys):
696        good = []
697        for key in keys:
698            if key in ['Type','U','V','W','X','Y','SH/L','I(L2)/I(L1)','alpha',
699                'beta-0','beta-1','beta-q','sig-0','sig-1','sig-q','Polariz.',
700                'Lam','Azimuth','2-theta','difC','difA','Zero','Lam1','Lam2']:
701                good.append(key)
702        return good
703       
704    keys = keycheck(data.keys())
705    if 'P' in data['Type'][0]:          #powder data
706        insVal = dict(zip(keys,[data[key][1] for key in keys]))
707        insDef = dict(zip(keys,[data[key][0] for key in keys]))
708        insRef = dict(zip(keys,[data[key][2] for key in keys]))
709        if 'NC' in data['Type'][0]:
710            del(insDef['Polariz.'])
711            del(insVal['Polariz.'])
712            del(insRef['Polariz.'])
713    else:                               #single crystal data
714        insVal = dict(zip(keys,[data[key][1] for key in keys]))
715        insDef = dict(zip(keys,[data[key][0] for key in keys]))
716        insRef = {}
717    ValObj = {}
718    RefObj = {}
719    waves = {'CuKa':[1.54051,1.54433],'TiKa':[2.74841,2.75207],'CrKa':[2.28962,2.29351],
720        'FeKa':[1.93597,1.93991],'CoKa':[1.78892,1.79278],'MoKa':[0.70926,0.713543],
721        'AgKa':[0.559363,0.563775]}
722    Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,
723            G2frame.PatternId,'Instrument Parameters'))[1]
724       
725    def inst2data(inst,ref,data):
726        for item in data:
727            try:
728                data[item] = [data[item][0],inst[item],ref[item]]
729            except KeyError:
730                pass        #skip 'Polariz.' for N-data
731        return data
732       
733    def updateData(inst,ref):
734        return inst2data(inst,ref,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,
735            G2frame.PatternId,'Instrument Parameters'))[0])       
736   
737    def RefreshInstrumentGrid(event,doAnyway=False):
738        if doAnyway or event.GetRow() == 1:
739            peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'))
740            newpeaks = []
741            for peak in peaks:
742                newpeaks.append(G2mth.setPeakparms(data,Inst2,peak[0],peak[2]))
743            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'),newpeaks)
744                   
745    def OnLoad(event):
746        '''Loads instrument parameters from a G2 .instprm file
747        in response to the Instrument Parameters-Operations/Load Profile menu
748       
749        Note that similar code is found in ReadPowderInstprm (GSASII.py)
750        '''
751        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II instrument parameters file', '.', '', 
752            'instrument parameter files (*.instprm)|*.instprm',wx.OPEN|wx.CHANGE_DIR)
753        try:
754            if dlg.ShowModal() == wx.ID_OK:
755                filename = dlg.GetPath()
756                File = open(filename,'r')
757                S = File.readline()
758                newItems = []
759                newVals = []
760                while S:
761                    if S[0] == '#':
762                        S = File.readline()
763                        continue
764                    [item,val] = S[:-1].split(':')
765                    newItems.append(item)
766                    try:
767                        newVals.append(float(val))
768                    except ValueError:
769                        newVals.append(val)                       
770                    S = File.readline()               
771                File.close()
772                Inst,Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Instrument Parameters'))
773                inst = G2IO.makeInstDict(newItems,newVals,len(newVals)*[False,])
774                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Instrument Parameters'),[inst,Inst2])
775                RefreshInstrumentGrid(event,doAnyway=True)          #to get peaks updated
776                UpdateInstrumentGrid(G2frame,data)
777                G2plt.PlotPeakWidths(G2frame)
778        finally:
779            dlg.Destroy()
780       
781    def OnSave(event):
782        '''Respond to the Instrument Parameters Operations/Save Profile menu
783        item: writes current parameters to a .instprm file
784        '''
785        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II instrument parameters file', '.', '', 
786            'instrument parameter files (*.instprm)|*.instprm',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
787        try:
788            if dlg.ShowModal() == wx.ID_OK:
789                filename = dlg.GetPath()
790                # make sure extension is .instprm
791                filename = os.path.splitext(filename)[0]+'.instprm'
792                File = open(filename,'w')
793                File.write("#GSAS-II instrument parameter file; do not add/delete or change order of items!\n")
794                for item in data:
795                    File.write(item+':'+str(data[item][1])+'\n')
796                File.close()
797        finally:
798            dlg.Destroy()
799                                               
800    def OnReset(event):
801        insVal.update(insDef)
802        data = updateData(insVal,insRef)
803        RefreshInstrumentGrid(event,doAnyway=True)          #to get peaks updated
804        UpdateInstrumentGrid(G2frame,data)
805        G2plt.PlotPeakWidths(G2frame)
806       
807    def OnInstFlagCopy(event):
808        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
809        keys = data.keys()
810        flags = dict(zip(keys,[data[key][2] for key in keys]))
811        instType = data['Type'][0]
812        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
813        copyList = []
814        dlg = wx.MultiChoiceDialog(G2frame, 
815            'Copy refinement flags from\n'+histName, 'Copy refinement flags', 
816            histList, wx.CHOICEDLG_STYLE)
817        try:
818            if dlg.ShowModal() == wx.ID_OK:
819                result = dlg.GetSelections()
820                for i in result: 
821                    copyList.append(histList[i])
822                if 'All' in copyList: 
823                    copyList = histList[1:]
824            for item in copyList:
825                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
826                instData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'))[0]
827                if len(data) == len(instData) and instType == instData['Type'][0]:   #don't mix data types or lam & lam1/lam2 parms!
828                    for item in instData:
829                        instData[item][2] = copy.copy(flags[item])
830                else:
831                    print item+' not copied - instrument parameters not commensurate'
832        finally:
833            dlg.Destroy()
834       
835    def OnInstCopy(event):
836        #need fix for dictionary
837        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
838        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
839        copyList = []
840        instType = data['Type'][0]
841        dlg = wx.MultiChoiceDialog(G2frame, 
842            'Copy parameters from\n'+histName, 'Copy parameters', 
843            histList, wx.CHOICEDLG_STYLE)
844        try:
845            if dlg.ShowModal() == wx.ID_OK:
846                result = dlg.GetSelections()
847                for i in result: 
848                    copyList.append(histList[i])
849                if 'All' in copyList: 
850                    copyList = histList[1:]
851            for item in copyList:
852                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
853                instData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'))[0]
854                if len(data) == len(instData) and instType == instData['Type'][0]:  #don't mix data types or lam & lam1/lam2 parms!
855                    instData.update(data)
856                else:
857                    print item+' not copied - instrument parameters not commensurate'
858        finally:
859            dlg.Destroy()
860       
861    def OnWaveChange(event):
862        if 'Lam' in insVal:
863            data['Lam1'] = [waves['CuKa'][0],waves['CuKa'][0],0]
864            data['Lam2'] = [waves['CuKa'][1],waves['CuKa'][1],0]
865            data['I(L2)/I(L1)'] = [0.5,0.5,0]
866            del(data['Lam'])
867        else:
868            data['Lam'] = [data['Lam1'][0],data['Lam1'][0],0]
869            del(data['Lam1'])
870        wx.CallAfter(UpdateInstrumentGrid,data)
871               
872    def OnLamPick(event):
873        lamType = lamPick.GetValue()
874        insVal['Lam1'] = waves[lamType][0]
875        insVal['Lam2'] = waves[lamType][1]
876        data = updateData(insVal,insRef)
877        UpdateInstrumentGrid(G2frame,data)
878                 
879    def OnRatValue(event):
880        try:
881            value = float(ratVal.GetValue())
882            if value < 0:
883                raise ValueError
884        except ValueError:
885            value = insVal['I(L2)/I(L1)']
886        insVal['I(L2)/I(L1)'] = value
887        ratVal.SetValue('%10.4f'%(value))
888        data = updateData(insVal,insRef)
889       
890    def OnRatRef(event):
891        insRef['I(L2)/I(L1)'] = ratRef.GetValue()
892        data = updateData(insVal,insRef)
893       
894    def OnWaveValue(event):
895        try:
896            value = float(waveVal.GetValue())
897            if value < 0:
898                raise ValueError
899        except ValueError:
900            value = insVal['Lam']
901        insVal['Lam'] = value
902        waveVal.SetValue('%10.6f'%(value))
903        data = updateData(insVal,insRef)
904       
905    def OnWaveRef(event):
906        insRef['Lam'] = waveRef.GetValue()
907        data = updateData(insVal,insRef)
908       
909    def OnItemValue(event):
910        Obj = event.GetEventObject()
911        item,fmt = ValObj[Obj.GetId()]
912        try:
913            value = float(Obj.GetValue())
914        except ValueError:
915            value = insVal[item]
916        insVal[item] = value
917        Obj.SetValue(fmt%(value))
918        data = updateData(insVal,insRef)
919        G2plt.PlotPeakWidths(G2frame)
920       
921    def OnItemRef(event):
922        Obj = event.GetEventObject()
923        item = RefObj[Obj.GetId()]
924        insRef[item] = Obj.GetValue()
925        data = updateData(insVal,insRef)
926               
927    if G2frame.dataDisplay:
928        G2frame.dataFrame.Clear()
929    try:
930        histoName = G2frame.PatternTree.GetItemPyData(G2frame.PatternId)[-1]
931        ifHisto = IsHistogramInAnyPhase(G2frame,histoName)
932    except TypeError:       #PKS data never used in a phase as data
933        ifhisto = False
934    G2gd.SetDataMenuBar(G2frame)
935    G2frame.dataFrame.SetLabel('Instrument Parameters')
936    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
937    topSizer = wx.FlexGridSizer(1,6,5,5)
938    instSizer = wx.FlexGridSizer(2,6,5,5)
939    topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Histogram Type: '+insVal['Type']),0,wx.ALIGN_CENTER_VERTICAL)
940#    topSizer.Add((5,5),0)
941    if 'P' in insVal['Type']:                   #powder data
942        G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.InstMenu)
943        if not G2frame.dataFrame.GetStatusBar():
944            Status = G2frame.dataFrame.CreateStatusBar()
945        G2frame.Bind(wx.EVT_MENU,OnLoad,id=G2gd.wxID_INSTLOAD)
946        G2frame.Bind(wx.EVT_MENU,OnSave,id=G2gd.wxID_INSTSAVE)
947        G2frame.Bind(wx.EVT_MENU,OnReset,id=G2gd.wxID_INSTPRMRESET)
948        G2frame.Bind(wx.EVT_MENU,OnInstCopy,id=G2gd.wxID_INSTCOPY)
949        G2frame.Bind(wx.EVT_MENU,OnInstFlagCopy,id=G2gd.wxID_INSTFLAGCOPY)
950        G2frame.Bind(wx.EVT_MENU,OnWaveChange,id=G2gd.wxID_CHANGEWAVETYPE)       
951        if 'C' in insVal['Type']:               #constant wavelength
952            #patch
953            if 'Azimuth' not in insVal:
954                insVal['Azimuth'] = 0.0
955                insDef['Azimuth'] = 0.0
956                insRef['Azimuth'] = False
957            #end of patch
958            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Azimuth: %7.2f'%(insVal['Azimuth'])),0,wx.ALIGN_CENTER_VERTICAL)
959            if 'Lam1' in insVal:
960                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Ka1/Ka2:'),
961                        0,wx.ALIGN_CENTER_VERTICAL)
962                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u%8.6f/%8.6f\xc5'%(insVal['Lam1'],insVal['Lam2'])),
963                        0,wx.ALIGN_CENTER_VERTICAL)
964                waveSizer = wx.BoxSizer(wx.HORIZONTAL)
965                waveSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Select: '),0,wx.ALIGN_CENTER_VERTICAL)
966                choice = ['TiKa','CrKa','FeKa','CoKa','CuKa','MoKa','AgKa']
967                lamPick = wx.ComboBox(G2frame.dataDisplay,value=' ',choices=choice,style=wx.CB_READONLY|wx.CB_DROPDOWN)
968                lamPick.Bind(wx.EVT_COMBOBOX, OnLamPick)
969                waveSizer.Add(lamPick,0)
970                topSizer.Add(waveSizer,0)
971                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' I(L2)/I(L1): (%10.4f)'%(insDef['I(L2)/I(L1)'])),
972                        0,wx.ALIGN_CENTER_VERTICAL)
973                ratVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.4f'%(insVal['I(L2)/I(L1)']),style=wx.TE_PROCESS_ENTER)
974                ratVal.Bind(wx.EVT_TEXT_ENTER,OnRatValue)
975                ratVal.Bind(wx.EVT_KILL_FOCUS,OnRatValue)
976                instSizer.Add(ratVal,0)
977                ratRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
978                ratRef.SetValue(bool(insRef['I(L2)/I(L1)']))
979                ratRef.Bind(wx.EVT_CHECKBOX, OnRatRef)
980                instSizer.Add(ratRef,0,wx.ALIGN_CENTER_VERTICAL)
981               
982            else:
983                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u' Lam (\xc5): (%10.6f)'%(insDef['Lam'])),
984                    0,wx.ALIGN_CENTER_VERTICAL)
985                waveVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.6f'%(insVal['Lam']),style=wx.TE_PROCESS_ENTER)
986                waveVal.Bind(wx.EVT_TEXT_ENTER,OnWaveValue)
987                waveVal.Bind(wx.EVT_KILL_FOCUS,OnWaveValue)
988                topSizer.Add(waveVal,0,wx.ALIGN_CENTER_VERTICAL)
989                if ifHisto:
990                    waveRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
991                    waveRef.SetValue(bool(insRef['Lam']))
992                    waveRef.Bind(wx.EVT_CHECKBOX, OnWaveRef)
993                    topSizer.Add(waveRef,0,wx.ALIGN_CENTER_VERTICAL)
994            for item in ['Zero','Polariz.']:
995                fmt = '%10.4f'
996                Fmt = ' %s: ('+fmt+')'
997                if item in insDef:
998                    instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
999                            0,wx.ALIGN_CENTER_VERTICAL)
1000                    itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
1001                    ValObj[itemVal.GetId()] = [item,fmt]
1002                    itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
1003                    itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
1004                    instSizer.Add(itemVal,0,wx.ALIGN_CENTER_VERTICAL)
1005                    if ifHisto:
1006                        itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
1007                        itemRef.SetValue(bool(insRef[item]))
1008                        RefObj[itemRef.GetId()] = item
1009                        itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
1010                        instSizer.Add(itemRef,0,wx.ALIGN_CENTER_VERTICAL)
1011                    else:
1012                        instSizer.Add((5,5),0)
1013                else:                           #skip Polariz. for neutrons
1014                    instSizer.Add((5,5),0)
1015                    instSizer.Add((5,5),0)
1016                    instSizer.Add((5,5),0)
1017            for item in ['U','V','W','X','Y','SH/L']:
1018                fmt = '%10.3f'
1019                if item == 'SH/L':
1020                    fmt = '%10.5f'
1021                Fmt = ' %s: ('+fmt+')'
1022                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
1023                        0,wx.ALIGN_CENTER_VERTICAL)
1024                itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
1025                ValObj[itemVal.GetId()] = [item,fmt]
1026                itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
1027                itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
1028                instSizer.Add(itemVal,0,wx.ALIGN_CENTER_VERTICAL)
1029                itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
1030                itemRef.SetValue(bool(insRef[item]))
1031                RefObj[itemRef.GetId()] = item
1032                itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
1033                instSizer.Add(itemRef,0,wx.ALIGN_CENTER_VERTICAL)
1034        else:                                   #time of flight (neutrons)
1035            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Azimuth: %7.2f'%(insVal['Azimuth'])),0,wx.ALIGN_CENTER_VERTICAL)
1036            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' 2-theta: %7.2f'%(insVal['2-theta'])),0,wx.ALIGN_CENTER_VERTICAL)
1037            if 'Pdabc' in Inst2:
1038                Items = ['sig-0','sig-1','X','Y']
1039                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' difC: %8.2f'%(insVal['difC'])),0,wx.ALIGN_CENTER_VERTICAL)
1040                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' alpha, beta: fixed by table'),0,wx.ALIGN_CENTER_VERTICAL)
1041            else:
1042                Items = ['difC','difA','Zero','alpha','beta-0','beta-1','beta-q','sig-0','sig-1','sig-q','X','Y']
1043            for item in Items:
1044                fmt = '%10.3f'
1045                if 'beta' in item:
1046                    fmt = '%12.4g'
1047                Fmt = ' %s: ('+fmt+')'
1048                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
1049                        0,wx.ALIGN_CENTER_VERTICAL)
1050                itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
1051                ValObj[itemVal.GetId()] = [item,fmt]
1052                itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
1053                itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
1054                instSizer.Add(itemVal,0,wx.ALIGN_CENTER_VERTICAL)
1055                if not ifHisto and item in ['difC','difA','Zero',]:
1056                    instSizer.Add((5,5),0)
1057                else:
1058                    itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
1059                    itemRef.SetValue(bool(insRef[item]))
1060                    RefObj[itemRef.GetId()] = item
1061                    itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
1062                    instSizer.Add(itemRef,0,wx.ALIGN_CENTER_VERTICAL)
1063       
1064    else:                       #single crystal data
1065        if 'C' in insVal['Type']:               #constant wavelength
1066            instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u' Lam (\xc5): (%10.6f)'%(insDef['Lam'])),
1067                0,wx.ALIGN_CENTER_VERTICAL)
1068            waveVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.6f'%(insVal['Lam']),style=wx.TE_PROCESS_ENTER)
1069            waveVal.Bind(wx.EVT_TEXT_ENTER,OnWaveValue)
1070            waveVal.Bind(wx.EVT_KILL_FOCUS,OnWaveValue)
1071            instSizer.Add(waveVal,0,wx.ALIGN_CENTER_VERTICAL)
1072        else:                                   #time of flight (neutrons)
1073            pass                                #for now
1074       
1075    mainSizer = wx.BoxSizer(wx.VERTICAL)
1076    mainSizer.Add(topSizer,0)
1077    mainSizer.Add(instSizer,0)
1078    mainSizer.Layout()   
1079    G2frame.dataDisplay.SetSizer(mainSizer)
1080    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1081   
1082################################################################################
1083#####  Sample parameters
1084################################################################################           
1085       
1086def UpdateSampleGrid(G2frame,data):
1087    '''respond to selection of PWDR Sample Parameters
1088    data tree item.
1089    '''
1090    def SetCopyNames(histName,addNames=[]):
1091        copyNames = ['Scale',]
1092        dataType = data['Type']
1093        histType = 'HKLF'
1094        if 'PWDR' in histName:          #else HKLF - only Scale
1095            histType = 'PWDR'
1096            if 'Debye' in dataType:
1097                copyNames += ['DisplaceX','DisplaceY','Absorption']
1098            else:       #Bragg-Brentano
1099                copyNames += ['Shift','Transparency']
1100        if len(addNames):
1101         copyNames += addNames
1102        return histType,copyNames
1103       
1104    def OnSampleSave(event):
1105        '''Respond to the Sample Parameters Operations/Save menu
1106        item: writes current parameters to a .samprm file
1107        '''
1108        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II sample parameters file', '.', '', 
1109            'sample parameter files (*.samprm)|*.samprm',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1110        try:
1111            if dlg.ShowModal() == wx.ID_OK:
1112                filename = dlg.GetPath()
1113                # make sure extension is .samprm
1114                filename = os.path.splitext(filename)[0]+'.samprm'
1115                File = open(filename,'w')
1116                File.write("#GSAS-II sample parameter file\n")
1117                File.write("'Type':'"+str(data['Type'])+"'\n")
1118                File.write("'Gonio. radius':"+str(data['Gonio. radius'])+"\n")
1119                if data.get('InstrName'):
1120                    File.write("'InstrName':'"+str(data['InstrName'])+"'\n")
1121                File.close()
1122        finally:
1123            dlg.Destroy()
1124                                               
1125       
1126    def OnSampleLoad(event):
1127        '''Loads sample parameters from a G2 .samprm file
1128        in response to the Sample Parameters-Operations/Load menu
1129       
1130        Note that similar code is found in ReadPowderInstprm (GSASII.py)
1131        '''
1132        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II sample parameters file', '.', '', 
1133            'sample parameter files (*.samprm)|*.samprm',wx.OPEN|wx.CHANGE_DIR)
1134        try:
1135            if dlg.ShowModal() == wx.ID_OK:
1136                filename = dlg.GetPath()
1137                File = open(filename,'r')
1138                S = File.readline()
1139                newItems = {}
1140                while S:
1141                    if S[0] == '#':
1142                        S = File.readline()
1143                        continue
1144                    [item,val] = S[:-1].split(':')
1145                    newItems[item.strip("'")] = eval(val)
1146                    S = File.readline()               
1147                File.close()
1148                data.update(newItems)
1149                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Sample Parameters'),data)
1150                UpdateSampleGrid(G2frame,data)
1151        finally:
1152            dlg.Destroy()
1153   
1154    def OnSampleCopy(event):
1155        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
1156        histType,copyNames = SetCopyNames(
1157            histName,
1158            addNames=['Omega','Chi','Phi','Gonio. radius','InstrName'])
1159        copyDict = {}
1160        for parm in copyNames:
1161            copyDict[parm] = data[parm]
1162        histList = ['All '+histType,]
1163        AllList = {}
1164        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1165        while item:
1166            name = G2frame.PatternTree.GetItemText(item)
1167            if histType in name and name != histName:
1168                allname = name.split(' Azm=')[0]
1169                if allname in AllList:
1170                    AllList[allname] += 1
1171                else:
1172                    AllList[allname] = 1
1173                histList.append(name)
1174            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1175        if len(histList) == 1:      #nothing to copy to!
1176            return
1177        nAll = 0
1178        AllNames = AllList.keys()
1179        AllNames.sort()
1180        for allname in AllNames:
1181            if AllList[allname] > 1:
1182                histList.insert(1+nAll,'All '+allname)
1183                nAll += 1
1184        copyList = []
1185        dlg = wx.MultiChoiceDialog(G2frame,'Copy parameters from\n'+histName,
1186            'Copy parameters',histList,wx.CHOICEDLG_STYLE)
1187        try:
1188            if dlg.ShowModal() == wx.ID_OK:
1189                result = dlg.GetSelections()
1190                for i in result: 
1191                    copyList.append(histList[i])
1192                for allname in AllList:
1193                    if 'All '+allname in copyList:
1194                        copyList = []
1195                        for name in histList:
1196                            if name.split(' Azm=')[0] == allname:
1197                                copyList.append(name)
1198                        break       #only one All allowed
1199                if 'All '+histType in copyList: 
1200                    copyList = histList[1+nAll:]
1201            for item in copyList:
1202                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
1203                sampleData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
1204                sampleData.update(copy.deepcopy(copyDict))
1205        finally:
1206            dlg.Destroy()
1207
1208    def OnSampleFlagCopy(event):
1209        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
1210        histType,copyNames = SetCopyNames(histName)
1211        flagDict = {}
1212        for parm in copyNames:
1213            flagDict[parm] = data[parm][1]
1214        histList = ['All '+histType,]
1215        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1216        while item:
1217            name = G2frame.PatternTree.GetItemText(item)
1218            if histType in name and name != histName:
1219                histList.append(name)
1220            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1221        if len(histList) == 1:      #nothing to copy to!
1222            return
1223        copyList = []
1224        dlg = wx.MultiChoiceDialog(G2frame,'Copy parameters from\n'+histName,
1225            'Copy refinement flags',histList,wx.CHOICEDLG_STYLE)
1226        try:
1227            if dlg.ShowModal() == wx.ID_OK:
1228                result = dlg.GetSelections()
1229                for i in result: 
1230                    copyList.append(histList[i])
1231                if 'All '+histType in copyList: 
1232                    copyList = histList[1:]
1233            for item in copyList:
1234                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
1235                sampleData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
1236                for name in copyNames:
1237                    sampleData[name][1] = copy.copy(flagDict[name])
1238        finally:
1239            dlg.Destroy()
1240
1241    if G2frame.dataDisplay:
1242        G2frame.dataFrame.Clear()
1243    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.SampleMenu)
1244    G2frame.dataFrame.SetLabel('Sample Parameters')
1245    G2frame.Bind(wx.EVT_MENU, OnSampleCopy, id=G2gd.wxID_SAMPLECOPY)
1246    G2frame.Bind(wx.EVT_MENU, OnSampleFlagCopy, id=G2gd.wxID_SAMPLEFLAGCOPY)
1247    G2frame.Bind(wx.EVT_MENU, OnSampleSave, id=G2gd.wxID_SAMPLESAVE)
1248    G2frame.Bind(wx.EVT_MENU, OnSampleLoad, id=G2gd.wxID_SAMPLELOAD)
1249    if not G2frame.dataFrame.GetStatusBar():
1250        Status = G2frame.dataFrame.CreateStatusBar()   
1251    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1252
1253#patch
1254    if 'ranId' not in data:
1255        data['ranId'] = ran.randint(0,sys.maxint)
1256    if not 'Gonio. radius' in data:
1257        data['Gonio. radius'] = 200.0
1258    if not 'Omega' in data:
1259        data.update({'Omega':0.0,'Chi':0.0,'Phi':0.0})
1260#patch end
1261   
1262    parms = [['Gonio. radius',' Goniometer radius(mm): ','%.2f',]]
1263    if data['Type'] == 'Debye-Scherrer':
1264        parms += [['DisplaceX',u' Sample X displ. perp. to beam (\xb5m): ','%.2f',],
1265            ['DisplaceY',u' Sample Y displ. || to beam (\xb5m): ','%.2f',],
1266            ['Absorption',u' Sample absorption(\xb5r): ','%.4f',],]
1267    elif data['Type'] == 'Bragg-Brentano':
1268        parms += [['Shift',u' Sample displacement(\xb5m): ','%.2f',],
1269            ['Transparency',u' Sample transparency(1/\xb5eff,cm): ','%.4f'],]
1270    parms.append(['Omega','Goniometer omega:','%.2f'])
1271    parms.append(['Chi','Goniometer chi:','%.2f'])
1272    parms.append(['Phi','Goniometer phi:','%.2f'])
1273    parms.append(['Temperature',' Sample temperature(K): ','%.2f'])
1274    parms.append(['Pressure',' Sample pressure(MPa): ','%.3f'])
1275    parms.append(['Humidity',' Sample humidity(%): ','%.1f'])
1276    parms.append(['Voltage',' Sample voltage(V): ','%.3f'])
1277    parms.append(['Force',' Applied load(MN): ','%.3f'])
1278    objList = {}
1279
1280    def OnScaleRef(event):
1281        Obj = event.GetEventObject()
1282        data['Scale'][1] = Obj.GetValue()
1283       
1284    def OnScaleVal(event):
1285        Obj = event.GetEventObject()
1286        try:
1287            scale = float(Obj.GetValue())
1288            if scale > 0:
1289                data['Scale'][0] = scale
1290        except ValueError:
1291            pass
1292        Obj.SetValue("%.4f"%(data['Scale'][0]))          #reset in case of error
1293       
1294    def OnHistoType(event):
1295        Obj = event.GetEventObject()
1296        data['Type'] = Obj.GetValue()
1297        if data['Type'] == 'Bragg-Brentano' and 'Shift' not in data:    #set up defaults for new type(s)
1298            data['Shift'] = [0.0,False]
1299            data['Transparency'] = [0.0,False]
1300        wx.CallAfter(UpdateSampleGrid,G2frame,data)
1301       
1302    def OnParmRef(event):
1303        Obj = event.GetEventObject()
1304        parm = objList[Obj.GetId()]
1305        data[parm][1] = Obj.GetValue()
1306       
1307    def OnParmVal(event):
1308        Obj = event.GetEventObject()
1309        parm = objList[Obj.GetId()]
1310        try:
1311            if 'list' in str(type(data[parm[0]])): 
1312                data[parm[0]][0] = float(Obj.GetValue())
1313            else:
1314                data[parm[0]] = float(Obj.GetValue())
1315        except ValueError:
1316            pass
1317        if 'list' in str(type(data[parm[0]])): 
1318            Obj.SetValue(parm[2]%(data[parm[0]][0]))          #reset in case of error
1319        else:
1320            Obj.SetValue(parm[2]%(data[parm[0]]))          #reset in case of error
1321
1322    def SetNameVal():
1323        inst = instNameVal.GetValue()
1324        data['InstrName'] = inst.strip()
1325
1326    def OnNameVal(event):
1327        event.Skip()
1328        wx.CallAfter(SetNameVal)       
1329               
1330    mainSizer = wx.BoxSizer(wx.VERTICAL)
1331    topSizer = wx.BoxSizer(wx.HORIZONTAL)
1332    topSizer.Add((-1,-1),1,wx.EXPAND,1)
1333    topSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample and Experimental Parameters'))
1334    topSizer.Add((-1,-1),1,wx.EXPAND,1)
1335    mainSizer.Add(topSizer,0,wx.EXPAND,1)
1336    nameSizer = wx.BoxSizer(wx.HORIZONTAL)
1337    nameSizer.Add(wx.StaticText(G2frame.dataDisplay,wx.ID_ANY,'Instrument Name'),
1338                0,wx.ALIGN_CENTER_VERTICAL)
1339    nameSizer.Add((-1,-1),1,wx.EXPAND,1)
1340    instNameVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,data.get('InstrName',''),
1341                              size=(200,-1),style=wx.TE_PROCESS_ENTER)       
1342    nameSizer.Add(instNameVal)
1343    instNameVal.Bind(wx.EVT_CHAR,OnNameVal)
1344    mainSizer.Add(nameSizer,0,wx.EXPAND,1)
1345    mainSizer.Add((0,5),0)
1346
1347    mainSizer.Add((5,5),0)
1348    parmSizer = wx.FlexGridSizer(10,2,5,0)
1349    scaleRef = wx.CheckBox(G2frame.dataDisplay,label=' Histogram scale factor: ')
1350    scaleRef.SetValue(data['Scale'][1])
1351    scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
1352    parmSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
1353    scaleVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,
1354        '%.4f'%(data['Scale'][0]),style=wx.TE_PROCESS_ENTER)
1355    scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
1356    scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
1357    parmSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
1358    typeSizer = wx.BoxSizer(wx.HORIZONTAL)
1359    choices = ['Debye-Scherrer','Bragg-Brentano',]
1360    histoType = wx.ComboBox(G2frame.dataDisplay,wx.ID_ANY,value=data['Type'],choices=choices,
1361        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1362    histoType.Bind(wx.EVT_COMBOBOX, OnHistoType)
1363    parmSizer.Add(histoType)
1364    parmSizer.Add((5,5),0)
1365   
1366    for parm in parms:
1367        if 'list' in str(type(data[parm[0]])):
1368            parmRef = wx.CheckBox(G2frame.dataDisplay,label=parm[1])
1369            objList[parmRef.GetId()] = parm[0]
1370            parmRef.SetValue(data[parm[0]][1])
1371            parmRef.Bind(wx.EVT_CHECKBOX, OnParmRef)
1372            parmSizer.Add(parmRef,0,wx.ALIGN_CENTER_VERTICAL)
1373            parmVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,
1374                parm[2]%(data[parm[0]][0]),style=wx.TE_PROCESS_ENTER)
1375        else:
1376            parmSizer.Add(wx.StaticText(G2frame.dataDisplay,label=parm[1]),
1377                0,wx.ALIGN_CENTER_VERTICAL)
1378            parmVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,
1379                parm[2]%(data[parm[0]]),style=wx.TE_PROCESS_ENTER)       
1380        objList[parmVal.GetId()] = parm
1381        parmVal.Bind(wx.EVT_TEXT_ENTER,OnParmVal)
1382        parmVal.Bind(wx.EVT_KILL_FOCUS,OnParmVal)
1383        parmSizer.Add(parmVal,1,wx.EXPAND)
1384    mainSizer.Add(parmSizer)
1385    mainSizer.Add((0,5),0)   
1386   
1387    mainSizer.Layout()   
1388    G2frame.dataDisplay.SetSizer(mainSizer)
1389    Size = mainSizer.Fit(G2frame.dataFrame)
1390    G2frame.dataDisplay.SetSize(Size)
1391    G2frame.dataFrame.setSizePosLeft(Size)
1392               
1393################################################################################
1394#####  Indexing Peaks
1395################################################################################           
1396       
1397def UpdateIndexPeaksGrid(G2frame, data):
1398    '''respond to selection of PWDR Index Peak List data
1399    tree item.
1400    '''
1401    IndexId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Index Peak List')
1402    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[0]
1403    wave = G2mth.getWave(Inst)
1404   
1405    def RefreshIndexPeaksGrid(event):
1406        r,c =  event.GetRow(),event.GetCol()
1407        data = G2frame.IndexPeaksTable.GetData()
1408        if c == 2:
1409            if data[r][c]:
1410                data[r][c] = False
1411            else:
1412                data[r][c] = True
1413            G2frame.IndexPeaksTable.SetData(data)
1414            G2frame.PatternTree.SetItemPyData(IndexId,data)
1415            G2frame.dataDisplay.ForceRefresh()
1416           
1417    def OnReload(event):
1418        data = []
1419        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'))
1420        for peak in peaks:
1421            dsp = wave/(2.0*sind((peak[0]-Inst['Zero'][1])/2.0))
1422            data.append([peak[0],peak[2],True,False,0,0,0,dsp,0.0])
1423        G2frame.PatternTree.SetItemPyData(IndexId,data)
1424        UpdateIndexPeaksGrid(G2frame,data)
1425       
1426    def KeyEditPickGrid(event):
1427        colList = G2frame.dataDisplay.GetSelectedCols()
1428        rowList = G2frame.dataDisplay.GetSelectedRows()
1429        data = G2frame.PatternTree.GetItemPyData(IndexId)
1430        if event.GetKeyCode() == wx.WXK_RETURN:
1431            event.Skip(True)
1432        elif event.GetKeyCode() == wx.WXK_CONTROL:
1433            event.Skip(True)
1434        elif event.GetKeyCode() == wx.WXK_SHIFT:
1435            event.Skip(True)
1436        elif colList:
1437            G2frame.dataDisplay.ClearSelection()
1438            key = event.GetKeyCode()
1439            for col in colList:
1440                if G2frame.IndexPeaksTable.GetColLabelValue(col) in ['use','refine']:
1441                    if key == 89: #'Y'
1442                        for row in range(G2frame.IndexPeaksTable.GetNumberRows()): data[row][col]=True
1443                    elif key == 78:  #'N'
1444                        for row in range(G2frame.IndexPeaksTable.GetNumberRows()): data[row][col]=False
1445           
1446    if G2frame.dataDisplay:
1447        G2frame.dataFrame.Clear()
1448    if not G2frame.dataFrame.GetStatusBar():
1449        Status = G2frame.dataFrame.CreateStatusBar()
1450    if 'PWD' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1451        G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.IndPeaksMenu)
1452        G2frame.Bind(wx.EVT_MENU, OnReload, id=G2gd.wxID_INDXRELOAD)
1453    G2frame.dataFrame.IndexPeaks.Enable(False)
1454    G2frame.IndexPeaksTable = []
1455    if data:
1456        G2frame.dataFrame.IndexPeaks.Enable(True)
1457        cells = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Unit Cells List'))
1458        if cells:
1459            cellist = cells[2]
1460            dmin = cells[3]
1461            G2frame.HKL = []
1462            for i,cell in enumerate(cellist):
1463                if cell[-1]:
1464                    ibrav = cell[2]
1465                    A = G2lat.cell2A(cell[3:9])
1466                    G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,A)
1467                    G2indx.IndexPeaks(data,G2frame.HKL)
1468                    for hkl in G2frame.HKL:
1469                        hkl.append(2.0*asind(wave/(2.*hkl[3]))+Inst['Zero'][1])             
1470    rowLabels = []
1471    for i in range(len(data)): rowLabels.append(str(i+1))
1472    colLabels = ['position','intensity','use','indexed','h','k','l','d-obs','d-calc']
1473    Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
1474        wg.GRID_VALUE_BOOL,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,
1475        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5']
1476    G2frame.PatternTree.SetItemPyData(IndexId,data)
1477    G2frame.IndexPeaksTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1478    G2frame.dataFrame.SetLabel('Index Peak List')
1479    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)               
1480    G2frame.dataDisplay.SetTable(G2frame.IndexPeaksTable, True)
1481    for r in range(G2frame.dataDisplay.GetNumberRows()):
1482        for c in range(G2frame.dataDisplay.GetNumberCols()):
1483            if c == 2:
1484                G2frame.dataDisplay.SetReadOnly(r,c,isReadOnly=False)
1485            else:
1486                G2frame.dataDisplay.SetReadOnly(r,c,isReadOnly=True)
1487    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_LEFT_CLICK, RefreshIndexPeaksGrid)
1488    G2frame.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPickGrid)                 
1489    G2frame.dataDisplay.SetMargins(0,0)
1490    G2frame.dataDisplay.AutoSizeColumns(False)
1491    G2frame.dataFrame.setSizePosLeft([490,300])
1492 
1493################################################################################
1494#####  Unit cells
1495################################################################################           
1496       
1497def UpdateUnitCellsGrid(G2frame, data):
1498    '''respond to selection of PWDR Unit Cells data tree item.
1499    '''
1500    UnitCellsId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Unit Cells List')
1501    SPGlist = G2spc.spglist
1502    bravaisSymb = ['Fm3m','Im3m','Pm3m','R3-H','P6/mmm','I4/mmm',
1503        'P4/mmm','Fmmm','Immm','Cmmm','Pmmm','C2/m','P2/m','P1']
1504    spaceGroups = ['F m 3 m','I m 3 m','P m 3 m','R 3 m','P 6/m m m','I 4/m m m',
1505        'P 4/m m m','F m m m','I m m m','C m m m','P m m m','C 2/m','P 2/m','P -1']
1506    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[0]
1507    wave = G2mth.getWave(Inst)
1508   
1509    def SetLattice(controls):
1510        ibrav = bravaisSymb.index(controls[5])
1511        if ibrav in [0,1,2]:
1512            controls[7] = controls[8] = controls[6]
1513            controls[9] = controls[10] = controls[11] = 90.
1514        elif ibrav in [3,4,5,6]:
1515            controls[7] = controls[6]
1516            controls[9] = controls[10] = controls[11] = 90.
1517            if ibrav in [3,4]:
1518                controls[11] = 120.
1519        elif ibrav in [7,8,9,10]:
1520            controls[9] = controls[10] = controls[11] = 90.
1521        elif ibrav in [11,12]:
1522            controls[9] = controls[11] = 90.  # b unique
1523        if len(controls) < 13: controls.append(0)
1524        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1525        return ibrav
1526       
1527    def OnNcNo(event):
1528        controls[2] = NcNo.GetValue()
1529       
1530    def OnStartVol(event):
1531        try:
1532            stVol = int(float(startVol.GetValue()))
1533            if stVol < 25:
1534                raise ValueError
1535        except ValueError:
1536            stVol = 25
1537        controls[3] = stVol
1538        startVol.SetValue("%d"%(stVol))
1539       
1540    def OnBravais(event):
1541        Obj = event.GetEventObject()
1542        bravais[bravList.index(Obj.GetId())] = Obj.GetValue()
1543       
1544    def OnZero(event):
1545        try:
1546            Zero = min(5.0,max(-5.0,float(zero.GetValue())))
1547        except ValueError:
1548            Zero = 0.0
1549        controls[1] = Zero
1550        zero.SetValue("%.4f"%(Zero))
1551       
1552    def OnZeroVar(event):
1553        controls[0] = zeroVar.GetValue()
1554       
1555    def OnBravSel(event):
1556        brav = bravSel.GetString(bravSel.GetSelection())
1557        controls[5] = brav
1558        controls[13] = SPGlist[brav][0]       
1559        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1560       
1561    def OnSpcSel(event):
1562        controls[13] = spcSel.GetString(spcSel.GetSelection())       
1563       
1564    def OnCellChange(event):
1565        ibrav = bravaisSymb.index(controls[5])
1566        Obj = event.GetEventObject()
1567        ObjId = cellList.index(Obj.GetId())
1568        try:
1569            value = max(1.0,float(Obj.GetValue()))
1570        except ValueError:
1571            if ObjId < 3:               #bad cell edge - reset
1572                value = controls[6+ObjId]
1573            else:                       #bad angle
1574                value = 90.
1575        if ibrav in [0,1,2]:
1576            controls[6] = controls[7] = controls[8] = value
1577            controls[9] = controls[10] = controls[11] = 90.0
1578            Obj.SetValue("%.5f"%(controls[6]))
1579        elif ibrav in [3,4,5,6]:
1580            if ObjId == 0:
1581                controls[6] = controls[7] = value
1582                Obj.SetValue("%.5f"%(controls[6]))
1583            else:
1584                controls[8] = value
1585                Obj.SetValue("%.5f"%(controls[8]))
1586            controls[9] = controls[10] = controls[11] = 90.0
1587            if ibrav in [3,4]:
1588                controls[11] = 120.
1589        elif ibrav in [7,8,9,10]:
1590            controls[6+ObjId] = value
1591            Obj.SetValue("%.5f"%(controls[6+ObjId]))
1592            controls[9] = controls[10] = controls[11] = 90.0
1593        elif ibrav in [11,12]:
1594            controls[9] = controls[11] = 90.0
1595            if ObjId != 3:
1596                controls[6+ObjId] = value
1597                Obj.SetValue("%.5f"%(controls[6+ObjId]))
1598            else:
1599                controls[10] = value
1600                Obj.SetValue("%.3f"%(controls[10]))
1601        else:
1602            controls[6+ObjId] = value
1603            if ObjId < 3:
1604                Obj.SetValue("%.5f"%(controls[6+ObjId]))
1605            else:
1606                Obj.SetValue("%.3f"%(controls[6+ObjId]))
1607        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1608        volVal.SetValue("%.3f"%(controls[12]))
1609       
1610    def OnHklShow(event):
1611        PatternId = G2frame.PatternId
1612        PickId = G2frame.PickId   
1613        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
1614        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1615        cell = controls[6:12]
1616        A = G2lat.cell2A(cell)
1617        ibrav = bravaisSymb.index(controls[5])
1618        spc = controls[13]
1619        SGData = G2spc.SpcGroup(spc)[1]
1620        dmin = wave/(2.0*sind(limits[1]/2.0))
1621        G2frame.HKL = G2pwd.getHKLpeak(dmin,SGData,A)
1622        for hkl in G2frame.HKL:
1623            hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1624        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1625            G2plt.PlotPowderLines(G2frame)
1626        else:
1627            G2plt.PlotPatterns(G2frame)
1628           
1629    def OnSortCells(event):
1630        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(UnitCellsId)
1631        c =  event.GetCol()
1632        if colLabels[c] == 'M20':
1633            cells = G2indx.sortM20(cells)
1634        elif colLabels[c] == 'Volume':
1635            cells = G2indx.sortVolume(cells)
1636        else:
1637            return
1638        data = [controls,bravais,cells,dmin]
1639        G2frame.PatternTree.SetItemPyData(UnitCellsId,data)
1640        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1641       
1642    def CopyUnitCell(event):
1643        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(UnitCellsId)
1644        for Cell in cells:
1645            if Cell[-2]:
1646                break
1647        cell = Cell[2:9]
1648        controls[4] = 1
1649        controls[5] = bravaisSymb[cell[0]]
1650        controls[6:12] = cell[1:8]
1651        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1652        controls[13] = spaceGroups[bravaisSymb.index(controls[5])]
1653        G2frame.PatternTree.SetItemPyData(UnitCellsId,[controls,bravais,cells,dmin])
1654        G2frame.dataFrame.RefineCell.Enable(True)
1655        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)       
1656               
1657    def RefineCell(event):
1658        def cellPrint(ibrav,A):
1659            cell = G2lat.A2cell(A)
1660            Vol = G2lat.calc_V(A)
1661            if ibrav in [0,1,2]:
1662                print "%s%10.6f" % ('a =',cell[0])
1663            elif ibrav in [3,4,5,6]:
1664                print "%s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],' c =',cell[2],' volume =',Vol)
1665            elif ibrav in [7,8,9,10]:
1666                print "%s%10.6f %s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2],' volume =',Vol)
1667            elif ibrav in [11,12]:
1668                print "%s%10.6f %s%10.6f %s%10.6f %s%8.3f %s%12.3f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2],'beta =',cell[4],' volume =',Vol)
1669            else:
1670                print "%s%10.6f %s%10.6f %s%10.6f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2])
1671                print "%s%8.3f %s%8.3f %s%8.3f %s%12.3f" % ('alpha =',cell[3],'beta =',cell[4],'gamma =',cell[5],' volume =',Vol)
1672             
1673        PatternId = G2frame.PatternId
1674        PickId = G2frame.PickId   
1675        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List'))
1676        if not peaks:
1677            G2frame.ErrorDialog('No peaks!', 'Nothing to refine!')
1678            return       
1679        print 'Refine cell'
1680        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1681        cell = controls[6:12]
1682        A = G2lat.cell2A(cell)
1683        ibrav = bravaisSymb.index(controls[5])
1684        SGData = G2spc.SpcGroup(controls[13])[1]
1685        dmin = G2indx.getDmin(peaks)-0.005
1686        G2frame.HKL = G2pwd.getHKLpeak(dmin,SGData,A)
1687        G2indx.IndexPeaks(peaks,G2frame.HKL)
1688        Lhkl,M20,X20,Aref,Zero = G2indx.refinePeaksZ(peaks,wave,ibrav,A,controls[1],controls[0])           
1689        controls[1] = Zero
1690        controls[6:12] = G2lat.A2cell(Aref)
1691        controls[12] = G2lat.calc_V(Aref)
1692        data = [controls,bravais,cells,dmin]
1693        cells = G2frame.PatternTree.GetItemPyData(UnitCellsId)[2]
1694        for cell in cells:
1695            cell[-2] = False
1696        cells.insert(0,[M20,X20,ibrav]+controls[6:13]+[True,False])
1697        data[2] = cells
1698        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'),data)
1699        G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,Aref)
1700        print "%s%10.3f" % ('refinement M20 = ',M20)
1701        print 'unindexed lines = ',X20
1702        cellPrint(ibrav,Aref)
1703        for hkl in G2frame.HKL:
1704            hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1705        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1706            G2plt.PlotPowderLines(G2frame)
1707        else:
1708            G2plt.PlotPatterns(G2frame)
1709        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1710       
1711    def IndexPeaks(event):
1712        PatternId = G2frame.PatternId   
1713        print 'Peak Indexing'
1714        keepcells = []
1715        try:
1716            controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1717            for cell in cells:
1718                if cell[11]:
1719                    keepcells.append(cell)
1720        except IndexError:
1721            pass
1722        except ValueError:
1723            G2frame.ErrorDialog('Error','Need to set controls in Unit Cell List first')
1724            return
1725        if True not in bravais:
1726            G2frame.ErrorDialog('Error','No Bravais lattices selected')
1727            return
1728        G2frame.dataFrame.CopyCell.Enable(False)
1729        G2frame.dataFrame.RefineCell.Enable(False)
1730        OK,dmin,newcells = G2indx.DoIndexPeaks(peaks,wave,controls,bravais)
1731        cells = keepcells+newcells
1732        cells = G2indx.sortM20(cells)
1733        cells[0][10] = True
1734        if OK:
1735            data = [controls,bravais,cells,dmin]
1736            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'),data)
1737            bestCell = cells[0]
1738            if bestCell[0] > 10.:
1739                G2frame.HKL = G2lat.GenHBravais(dmin,bestCell[2],G2lat.cell2A(bestCell[3:9]))
1740                for hkl in G2frame.HKL:
1741                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1742                if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1743                    G2plt.PlotPowderLines(G2frame)
1744                else:
1745                    G2plt.PlotPatterns(G2frame)
1746            G2frame.dataFrame.CopyCell.Enable(True)
1747            G2frame.dataFrame.IndexPeaks.Enable(True)
1748            G2frame.dataFrame.MakeNewPhase.Enable(True)
1749        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1750               
1751    def RefreshUnitCellsGrid(event):
1752        data =G2frame.PatternTree.GetItemPyData(UnitCellsId)
1753        cells,dmin = data[2:]
1754        r,c =  event.GetRow(),event.GetCol()
1755        if cells:
1756            if c == 2:
1757                for i in range(len(cells)):
1758                    cells[i][-2] = False
1759                    UnitCellsTable.SetValue(i,c,False)
1760                UnitCellsTable.SetValue(r,c,True)
1761                gridDisplay.ForceRefresh()
1762                cells[r][-2] = True
1763                ibrav = cells[r][2]
1764                A = G2lat.cell2A(cells[r][3:9])
1765                G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,A)
1766                for hkl in G2frame.HKL:
1767                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1768                if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1769                    G2plt.PlotPowderLines(G2frame)
1770                else:
1771                    G2plt.PlotPatterns(G2frame)
1772            elif c == 11:
1773                if UnitCellsTable.GetValue(r,c):
1774                    UnitCellsTable.SetValue(r,c,False)
1775                    cells[r][c] = False
1776                else:
1777                    cells[r][c] = True
1778                    UnitCellsTable.SetValue(r,c,True)
1779                gridDisplay.ForceRefresh()
1780            G2frame.PatternTree.SetItemPyData(UnitCellsId,data)               
1781       
1782    def MakeNewPhase(event):
1783        if not G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases'):
1784            sub = G2frame.PatternTree.AppendItem(parent=G2frame.root,text='Phases')
1785        else:
1786            sub = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases')
1787        PhaseName = ''
1788        dlg = wx.TextEntryDialog(None,'Enter a name for this phase','Phase Name Entry','New phase',
1789            style=wx.OK)
1790        try:
1791            if dlg.ShowModal() == wx.ID_OK:
1792                PhaseName = dlg.GetValue()
1793                cells = G2frame.PatternTree.GetItemPyData(UnitCellsId)[2]
1794                for Cell in cells:
1795                    if Cell[-2]:
1796                        break
1797                cell = Cell[2:10]       
1798                sub = G2frame.PatternTree.AppendItem(parent=sub,text=PhaseName)
1799                E,SGData = G2spc.SpcGroup(controls[13])
1800                G2frame.PatternTree.SetItemPyData(sub, \
1801                    G2IO.SetNewPhase(Name=PhaseName,SGData=SGData,cell=cell[1:]))
1802                Status.SetStatusText('Change space group if needed')
1803        finally:
1804            dlg.Destroy()
1805           
1806    if G2frame.dataDisplay:
1807        G2frame.dataFrame.Clear()
1808    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.IndexMenu)
1809    if not G2frame.dataFrame.GetStatusBar():
1810        Status = G2frame.dataFrame.CreateStatusBar()
1811    G2frame.Bind(wx.EVT_MENU, IndexPeaks, id=G2gd.wxID_INDEXPEAKS)
1812    G2frame.Bind(wx.EVT_MENU, CopyUnitCell, id=G2gd.wxID_COPYCELL)
1813    G2frame.Bind(wx.EVT_MENU, RefineCell, id=G2gd.wxID_REFINECELL)
1814    G2frame.Bind(wx.EVT_MENU, MakeNewPhase, id=G2gd.wxID_MAKENEWPHASE)
1815   
1816    controls,bravais,cells,dmin = data
1817    if len(controls) < 13:              #add cell volume if missing
1818        controls.append(G2lat.calc_V(G2lat.cell2A(controls[6:12])))
1819    if len(controls) < 14:              #add space gropu used in indexing
1820        controls.append(spaceGroups[bravaisSymb.index(controls[5])])
1821    G2frame.PatternTree.SetItemPyData(UnitCellsId,data)            #update with volume
1822    bravaisNames = ['Cubic-F','Cubic-I','Cubic-P','Trigonal-R','Trigonal/Hexagonal-P',
1823        'Tetragonal-I','Tetragonal-P','Orthorhombic-F','Orthorhombic-I','Orthorhombic-C',
1824        'Orthorhombic-P','Monoclinic-C','Monoclinic-P','Triclinic']
1825    cellGUIlist = [[[0,1,2],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
1826    [[3,4,5,6],6,zip([" Unit cell: a = "," c = "," Vol = "],["%.5f","%.5f","%.3f"],[True,True,False],[0,2,0])],
1827    [[7,8,9,10],8,zip([" Unit cell: a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
1828        [True,True,True,False],[0,1,2,0])],
1829    [[11,12],10,zip([" Unit cell: a = "," b = "," c = "," beta = "," Vol = "],
1830        ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
1831    [[13,],8,zip([" Unit cell: a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
1832        ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
1833        [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
1834   
1835    G2frame.dataFrame.SetLabel('Unit Cells List')
1836    G2frame.sp = wx.SplitterWindow(G2frame.dataFrame)
1837    G2frame.dataDisplay = wx.Panel(G2frame.sp, style=wx.SUNKEN_BORDER)
1838    G2frame.dataFrame.IndexPeaks.Enable(False)
1839    peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Index Peak List'))
1840    if peaks:
1841        G2frame.dataFrame.IndexPeaks.Enable(True)
1842    G2frame.dataFrame.RefineCell.Enable(False)
1843    if controls[12] > 1.0:                               #if a "real" volume (i.e. not default)
1844        G2frame.dataFrame.RefineCell.Enable(True)   
1845    G2frame.dataFrame.CopyCell.Enable(False)
1846    G2frame.dataFrame.MakeNewPhase.Enable(False)       
1847    if cells:
1848        G2frame.bottom = wx.Panel(G2frame.sp, style=wx.SUNKEN_BORDER)
1849        G2frame.sp.SplitHorizontally(G2frame.dataDisplay,G2frame.bottom,0)
1850        G2frame.dataFrame.CopyCell.Enable(True)
1851        G2frame.dataFrame.MakeNewPhase.Enable(True)       
1852    mainSizer = wx.BoxSizer(wx.VERTICAL)
1853    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Indexing controls: '),0,wx.ALIGN_CENTER_VERTICAL)
1854    mainSizer.Add((5,5),0)
1855    littleSizer = wx.FlexGridSizer(2,5,5,5)
1856    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Max Nc/Nobs '),0,wx.ALIGN_CENTER_VERTICAL)
1857    NcNo = wx.SpinCtrl(G2frame.dataDisplay)
1858    NcNo.SetRange(1,6)
1859    NcNo.SetValue(controls[2])
1860    NcNo.Bind(wx.EVT_SPINCTRL,OnNcNo)
1861    littleSizer.Add(NcNo,0,wx.ALIGN_CENTER_VERTICAL)
1862    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Start Volume '),0,wx.ALIGN_CENTER_VERTICAL)
1863    startVol = wx.TextCtrl(G2frame.dataDisplay,value=str('%d'%(controls[3])),style=wx.TE_PROCESS_ENTER)
1864    startVol.Bind(wx.EVT_TEXT_ENTER,OnStartVol)
1865    startVol.Bind(wx.EVT_KILL_FOCUS,OnStartVol)
1866    littleSizer.Add(startVol,0,wx.ALIGN_CENTER_VERTICAL)
1867    mainSizer.Add(littleSizer,0)
1868    mainSizer.Add((5,5),0)
1869    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Select Bravais Lattices for indexing: '),
1870        0,wx.ALIGN_CENTER_VERTICAL)
1871    mainSizer.Add((5,5),0)
1872    littleSizer = wx.FlexGridSizer(2,7,5,5)
1873    bravList = []
1874    bravs = zip(bravais,bravaisNames)
1875    for brav,bravName in bravs:
1876        bravCk = wx.CheckBox(G2frame.dataDisplay,label=bravName)
1877        bravList.append(bravCk.GetId())
1878        bravCk.SetValue(brav)
1879        bravCk.Bind(wx.EVT_CHECKBOX,OnBravais)
1880        littleSizer.Add(bravCk,0,wx.ALIGN_CENTER_VERTICAL)
1881    mainSizer.Add(littleSizer,0)
1882    mainSizer.Add((5,5),0)
1883   
1884    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Cell Refinement: '),0,wx.ALIGN_CENTER_VERTICAL)
1885    mainSizer.Add((5,5),0)
1886    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
1887    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Bravais lattice "),0,wx.ALIGN_CENTER_VERTICAL)
1888    bravSel = wx.Choice(G2frame.dataDisplay,choices=bravaisSymb)
1889    bravSel.SetSelection(bravaisSymb.index(controls[5]))
1890    bravSel.Bind(wx.EVT_CHOICE,OnBravSel)
1891    littleSizer.Add(bravSel,0,wx.ALIGN_CENTER_VERTICAL)
1892    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Space group "),0,wx.ALIGN_CENTER_VERTICAL)
1893    spcSel = wx.Choice(G2frame.dataDisplay,choices=SPGlist[controls[5]])
1894    spcSel.SetSelection(SPGlist[controls[5]].index(controls[13]))
1895    spcSel.Bind(wx.EVT_CHOICE,OnSpcSel)
1896    littleSizer.Add(spcSel,0,wx.ALIGN_CENTER_VERTICAL)
1897    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Zero offset"),0,wx.ALIGN_CENTER_VERTICAL)
1898    zero = wx.TextCtrl(G2frame.dataDisplay,value="%.4f"%(controls[1]),style=wx.TE_PROCESS_ENTER)
1899    zero.Bind(wx.EVT_TEXT_ENTER,OnZero)
1900    zero.Bind(wx.EVT_KILL_FOCUS,OnZero)
1901    littleSizer.Add(zero,0,wx.ALIGN_CENTER_VERTICAL)
1902    zeroVar = wx.CheckBox(G2frame.dataDisplay,label="Refine?")
1903    zeroVar.SetValue(controls[0])
1904    zeroVar.Bind(wx.EVT_CHECKBOX,OnZeroVar)
1905    littleSizer.Add(zeroVar,0,wx.ALIGN_CENTER_VERTICAL)
1906    hklShow = wx.Button(G2frame.dataDisplay,label="Show hkl positions")
1907    hklShow.Bind(wx.EVT_BUTTON,OnHklShow)
1908    littleSizer.Add(hklShow,0,wx.ALIGN_CENTER_VERTICAL)
1909    mainSizer.Add(littleSizer,0)
1910   
1911    mainSizer.Add((5,5),0)
1912    ibrav = SetLattice(controls)
1913    for cellGUI in cellGUIlist:
1914        if ibrav in cellGUI[0]:
1915            useGUI = cellGUI
1916    cellList = []
1917    littleSizer = wx.FlexGridSizer(2,useGUI[1],5,5)
1918    for txt,fmt,ifEdit,Id in useGUI[2]:
1919        littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL)
1920        if ifEdit:          #a,b,c,etc.
1921            cellVal = wx.TextCtrl(G2frame.dataDisplay,value=(fmt%(controls[6+Id])),style=wx.TE_PROCESS_ENTER)
1922            cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
1923            cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
1924            littleSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL)
1925            cellList.append(cellVal.GetId())
1926        else:               #volume
1927            volVal = wx.TextCtrl(G2frame.dataDisplay,value=(fmt%(controls[12])),style=wx.TE_READONLY)
1928            volVal.SetBackgroundColour(VERY_LIGHT_GREY)
1929            littleSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL)
1930    mainSizer.Add(littleSizer,0)
1931       
1932    mainSizer.Layout()   
1933    G2frame.dataDisplay.SetSizer(mainSizer)
1934    topSize = mainSizer.Fit(G2frame.dataFrame)
1935    G2frame.dataDisplay.SetSize(topSize)
1936    if cells:
1937        if ibrav == 13:
1938            topSize[1] += 230
1939        else:
1940            topSize[1] += 200
1941    G2frame.dataFrame.setSizePosLeft(topSize)   
1942   
1943    if cells:
1944        bottomSize = topSize        #screwy but bottom doesn't have a size in linux!
1945        bottomSize[0] -= 20         #to reveal slider
1946        if ibrav == 13:
1947            bottomSize[1] -= 240
1948        else:
1949            bottomSize[1] -= 210
1950        wx.StaticText(parent=G2frame.bottom,label=' Indexing Result ')
1951        rowLabels = []
1952        colLabels = ['M20','X20','use','Bravais','a','b','c','alpha','beta','gamma','Volume','Keep']
1953        Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_NUMBER,wg.GRID_VALUE_BOOL,wg.GRID_VALUE_STRING,]+ \
1954            3*[wg.GRID_VALUE_FLOAT+':10,5',]+3*[wg.GRID_VALUE_FLOAT+':10,3',]+ \
1955            [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL]
1956        numRows = len(cells)
1957        table = []
1958        for cell in cells:
1959            rowLabels.append('')
1960            row = cell[0:2]+[cell[-2]]+[bravaisSymb[cell[2]]]+cell[3:10]+[cell[11],]
1961            if cell[-2]:
1962                A = G2lat.cell2A(cell[3:9])
1963                G2frame.HKL = G2lat.GenHBravais(dmin,cell[2],A)
1964                for hkl in G2frame.HKL:
1965                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1966            table.append(row)
1967        UnitCellsTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1968        gridDisplay = G2gd.GSGrid(G2frame.bottom)
1969        gridDisplay.SetPosition(wx.Point(0,20))               
1970        gridDisplay.SetTable(UnitCellsTable, True)
1971        G2frame.dataFrame.CopyCell.Enable(True)
1972        gridDisplay.Bind(wg.EVT_GRID_CELL_LEFT_CLICK,RefreshUnitCellsGrid)
1973        gridDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK,OnSortCells)
1974        gridDisplay.SetMargins(0,0)
1975        gridDisplay.SetRowLabelSize(0)
1976        gridDisplay.AutoSizeColumns(False)
1977        for r in range(gridDisplay.GetNumberRows()):
1978            for c in range(gridDisplay.GetNumberCols()):
1979                if c == 2:
1980                    gridDisplay.SetReadOnly(r,c,isReadOnly=False)
1981                else:
1982                    gridDisplay.SetReadOnly(r,c,isReadOnly=True)
1983        gridDisplay.SetSize(bottomSize)
1984
1985################################################################################
1986#####  Reflection list
1987################################################################################           
1988       
1989def UpdateReflectionGrid(G2frame,data,HKLF=False,Name=''):
1990    '''respond to selection of PWDR Reflections data tree item.
1991    '''
1992    if not data:
1993        print 'No phases, no reflections'
1994        return
1995    if HKLF:
1996        G2frame.RefList = 1
1997        phaseName = Name
1998    else:
1999        phaseName = G2frame.RefList
2000        phases = data.keys()
2001   
2002        def OnSelectPhase(event):
2003            dlg = wx.SingleChoiceDialog(G2frame,'Select','Phase',phases)
2004            try:
2005                if dlg.ShowModal() == wx.ID_OK:
2006                    sel = dlg.GetSelection()
2007                    G2frame.RefList = phases[sel]
2008                    UpdateReflectionGrid(G2frame,data)
2009            finally:
2010                dlg.Destroy()
2011            G2plt.PlotPatterns(G2frame)
2012       
2013    if G2frame.dataDisplay:
2014        G2frame.dataFrame.Clear()
2015    rowLabels = []
2016    if HKLF:
2017        G2gd.SetDataMenuBar(G2frame)
2018        refs = data[1]['RefList']
2019    else:       
2020        G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ReflMenu)
2021        if not G2frame.dataFrame.GetStatusBar():
2022            Status = G2frame.dataFrame.CreateStatusBar()   
2023        G2frame.Bind(wx.EVT_MENU, OnSelectPhase, id=G2gd.wxID_SELECTPHASE)
2024        G2frame.dataFrame.SelectPhase.Enable(False)
2025        if len(data) > 1:
2026            G2frame.dataFrame.SelectPhase.Enable(True)
2027        try:            #patch for old reflection lists
2028            refList = np.array(data[G2frame.RefList]['RefList'])
2029            I100 = refList.T[8]*refList.T[11]
2030        except TypeError:
2031            refList = np.array([refl[:11] for refl in data[G2frame.RefList]])
2032            I100 = refList.T[8]*np.array([refl[13] for refl in data[G2frame.RefList]])
2033        Imax = np.max(I100)
2034        if Imax:
2035            I100 *= 100.0/Imax
2036        refs = np.vstack((refList.T[:11],I100)).T
2037    for i in range(len(refs)): rowLabels.append(str(i))
2038    if HKLF:
2039        colLabels = ['H','K','L','mul','d','Fosq','sig','Fcsq','FoTsq','FcTsq','phase',]
2040    else:
2041        colLabels = ['H','K','L','mul','d','pos','sig','gam','Fosq','Fcsq','phase','I100',]
2042    Types = 4*[wg.GRID_VALUE_LONG,]+4*[wg.GRID_VALUE_FLOAT+':10,4',]+ \
2043        2*[wg.GRID_VALUE_FLOAT+':10,2',]+[wg.GRID_VALUE_FLOAT+':10,3',]+ \
2044        [wg.GRID_VALUE_FLOAT+':10,2',]
2045    G2frame.PeakTable = G2gd.Table(refs,rowLabels=rowLabels,colLabels=colLabels,types=Types)
2046    G2frame.dataFrame.SetLabel('Reflection List for '+phaseName)
2047    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)
2048    G2frame.dataDisplay.SetTable(G2frame.PeakTable, True)
2049    G2frame.dataDisplay.EnableEditing(False)
2050    G2frame.dataDisplay.SetMargins(0,0)
2051    G2frame.dataDisplay.AutoSizeColumns(False)
2052    G2frame.dataDisplay.Fit()
2053    size = G2frame.dataDisplay.GetSize()
2054    G2frame.dataFrame.setSizePosLeft([size[0]+32,350])
2055################################################################################
2056#####  PDF controls
2057################################################################################           
2058       
2059def UpdatePDFGrid(G2frame,data):
2060    '''respond to selection of PWDR PDF data tree item.
2061    '''
2062    global inst
2063    tth2q = lambda t,w:4.0*math.pi*sind(t/2.0)/w
2064    dataFile = G2frame.PatternTree.GetItemText(G2frame.PatternId)
2065    powName = 'PWDR'+dataFile[4:]
2066    powId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, powName)
2067    fullLimits,limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId, 'Limits'))[:2]
2068    inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId, 'Instrument Parameters'))[0]
2069    if 'Lam' in inst:
2070        keV = 12.397639/inst['Lam'][1]
2071    else:
2072        keV = 12.397639/inst['Lam1'][0]
2073    wave = 12.397639/keV
2074    qLimits = [tth2q(fullLimits[0],wave),tth2q(fullLimits[1],wave)]
2075    data['QScaleLim'][1] = min(qLimits[1],data['QScaleLim'][1])
2076    if data['QScaleLim'][0]:
2077        data['QScaleLim'][0] = max(qLimits[0],data['QScaleLim'][0])
2078    else:                                #initial setting at 90% of max Q
2079        data['QScaleLim'][0] = 0.90*data['QScaleLim'][1]
2080    polariz = inst['Polariz.'][1]
2081    azimuth = inst['Azimuth'][1]
2082    itemDict = {}
2083   
2084    def FillFileSizer(fileSizer,key):
2085        #fileSizer is a FlexGridSizer(3,6)
2086       
2087        def OnSelectFile(event):
2088            Obj = event.GetEventObject()
2089            fileKey,itemKey,fmt = itemDict[Obj.GetId()]
2090            if itemKey == 'Name':
2091                value = Obj.GetValue()
2092            Obj.SetValue(fmt%(value))
2093            data[fileKey][itemKey] = value
2094            UpdatePDFGrid(G2frame,data)
2095       
2096        def OnValueChange(event):
2097            Obj = event.GetEventObject()
2098            fileKey,itemKey,fmt = itemDict[Obj.GetId()]
2099            try:
2100                value = float(Obj.GetValue())
2101            except ValueError:
2102                value = -1.0
2103            Obj.SetValue(fmt%(value))
2104            data[fileKey][itemKey] = value
2105            auxPlot = ComputePDF(data)
2106            G2plt.PlotISFG(G2frame,newPlot=True)
2107                       
2108        item = data[key]
2109        fileList = np.array(GetFileList('PWDR')).T[1]
2110        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' '+key+' file:'),0,wx.ALIGN_CENTER_VERTICAL)
2111        fileName = wx.ComboBox(G2frame.dataDisplay,value=item['Name'],choices=fileList,
2112            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2113        itemDict[fileName.GetId()] = [key,'Name','%s']
2114        fileName.Bind(wx.EVT_COMBOBOX,OnSelectFile)       
2115        fileSizer.Add(fileName,0,)
2116        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Multiplier:'),0,wx.ALIGN_CENTER_VERTICAL)
2117        mult = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(item['Mult']),style=wx.TE_PROCESS_ENTER)
2118        itemDict[mult.GetId()] = [key,'Mult','%.3f']
2119        mult.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2120        mult.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2121        fileSizer.Add(mult,0,)
2122        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Add:'),0,wx.ALIGN_CENTER_VERTICAL)
2123        add = wx.TextCtrl(G2frame.dataDisplay,value='%.0f'%(item['Add']),style=wx.TE_PROCESS_ENTER)
2124        itemDict[add.GetId()] = [key,'Add','%.0f']
2125        add.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2126        add.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2127        fileSizer.Add(add,0,)
2128       
2129    def SumElementVolumes():
2130        sumVol = 0.
2131        ElList = data['ElList']
2132        for El in ElList:
2133            Avol = (4.*math.pi/3.)*ElList[El]['Drad']**3
2134            sumVol += Avol*ElList[El]['FormulaNo']
2135        return sumVol
2136        auxPlot = ComputePDF(data)
2137        G2plt.PlotISFG(G2frame,newPlot=True)       
2138       
2139    def FillElemSizer(elemSizer,ElData):
2140       
2141        def OnFractionChange(event):
2142            try:
2143                value = max(0.0,float(num.GetValue()))
2144            except ValueError:
2145                value = 0.0
2146            num.SetValue('%.3f'%(value))
2147            ElData['FormulaNo'] = value
2148            data['Form Vol'] = max(10.0,SumElementVolumes())
2149            formVol.SetValue('%.2f'%(data['Form Vol']))
2150            wx.CallAfter(UpdatePDFGrid,G2frame,data)
2151            auxPlot = ComputePDF(data)
2152            G2plt.PlotISFG(G2frame,newPlot=True)       
2153       
2154        elemSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,
2155            label=' Element: '+'%2s'%(ElData['Symbol'])+' * '),0,wx.ALIGN_CENTER_VERTICAL)
2156        num = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(ElData['FormulaNo']),style=wx.TE_PROCESS_ENTER)
2157        num.Bind(wx.EVT_TEXT_ENTER,OnFractionChange)       
2158        num.Bind(wx.EVT_KILL_FOCUS,OnFractionChange)
2159        elemSizer.Add(num,0,wx.ALIGN_CENTER_VERTICAL)
2160        elemSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,
2161            label="f': %.3f"%(ElData['fp'])+' f": %.3f'%(ElData['fpp'])+' mu: %.2f barns'%(ElData['mu']) ),
2162            0,wx.ALIGN_CENTER_VERTICAL)
2163           
2164    def OnGeometry(event):
2165        data['Geometry'] = geometry.GetValue()
2166        UpdatePDFGrid(G2frame,data)
2167        auxPlot = ComputePDF(data)
2168        G2plt.PlotISFG(G2frame,newPlot=True)       
2169       
2170    def OnDetType(event):
2171        data['DetType'] = detType.GetValue()
2172        UpdatePDFGrid(G2frame,data)
2173        auxPlot = ComputePDF(data)
2174        G2plt.PlotISFG(G2frame,newPlot=True)       
2175       
2176    def OnFormVol(event):
2177        try:
2178            value = float(formVol.GetValue())
2179            if value <= 0.0:
2180                raise ValueError
2181        except ValueError:
2182            value = data['Form Vol']
2183        data['Form Vol'] = value
2184        UpdatePDFGrid(G2frame,data)
2185        auxPlot = ComputePDF(data)
2186        G2plt.PlotISFG(G2frame,newPlot=False)       
2187       
2188    def OnDiameter(event):
2189        try:
2190            value = float(diam.GetValue())
2191            if value <= 0.0:
2192                raise ValueError
2193        except ValueError:
2194            value = data['Diam']
2195        data['Diam'] = value
2196        UpdatePDFGrid(G2frame,data)
2197        auxPlot = ComputePDF(data)
2198        G2plt.PlotISFG(G2frame,newPlot=False)
2199       
2200    def OnPolaVal(event):
2201        try:
2202            value = float(polaVal.GetValue())
2203            if not (0.0 <= value <= 1.0):
2204                raise ValueError
2205        except ValueError:
2206            value = inst['Polariz.'][1]
2207        inst['Polariz.'][1] = value
2208        polaVal.SetValue('%.2f'%(inst['Polariz.'][1]))
2209        UpdatePDFGrid(G2frame,data)
2210        auxPlot = ComputePDF(data)
2211        G2plt.PlotISFG(G2frame,newPlot=False)
2212               
2213    def OnAzimVal(event):
2214        try:
2215            value = float(azimVal.GetValue())
2216            if not (0. <= value <= 360.):
2217                raise ValueError
2218        except ValueError:
2219            value = inst['Azimuth'][1]
2220        inst['Azimuth'][1] = value
2221        azimVal.SetValue('%.1f'%(inst['Azimuth'][1]))
2222        UpdatePDFGrid(G2frame,data)
2223        auxPlot = ComputePDF(data)
2224        G2plt.PlotISFG(G2frame,newPlot=False)
2225                       
2226    def OnObliqCoeff(event):
2227        try:
2228            value = float(obliqCoeff.GetValue())
2229            if value < 0.0:
2230                raise ValueError
2231            elif value > 1.0:
2232                value = 1.0
2233        except ValueError:
2234            value = data['ObliqCoeff']
2235        data['ObliqCoeff'] = value
2236        obliqCoeff.SetValue('%.3f'%(value))
2237        auxPlot = ComputePDF(data)
2238        G2plt.PlotISFG(G2frame,newPlot=False)
2239       
2240    def OnRulandWdt(event):
2241        try:
2242            value = float(rulandWdt.GetValue())
2243            if value <= 0.001:
2244                raise ValueError
2245            elif value > 1.0:
2246                value = 1.0
2247        except ValueError:
2248            value = data['Ruland']
2249        data['Ruland'] = value
2250        rulandWdt.SetValue('%.3f'%(value))
2251        auxPlot = ComputePDF(data)
2252        G2plt.PlotISFG(G2frame,newPlot=False)
2253       
2254    def OnRulSlider(event):
2255        value = int(rulandSldr.GetValue())/1000.
2256        data['Ruland'] = max(0.001,value)
2257        rulandWdt.SetValue('%.3f'%(data['Ruland']))
2258        auxPlot = ComputePDF(data)
2259        G2plt.PlotISFG(G2frame,newPlot=False)
2260       
2261    def OnLorch(event):
2262        data['Lorch'] = lorch.GetValue()
2263        auxPlot = ComputePDF(data)
2264        G2plt.PlotISFG(G2frame,newPlot=False)       
2265                       
2266    def OnPacking(event):
2267        try:
2268            value = float(pack.GetValue())
2269            if value <= 0.0:
2270                raise ValueError
2271        except ValueError:
2272            value = data['Pack']
2273        data['Pack'] = value
2274        UpdatePDFGrid(G2frame,data)
2275        auxPlot = ComputePDF(data)
2276        G2plt.PlotISFG(G2frame,newPlot=False)       
2277               
2278    def OnSQmin(event):
2279        try:
2280            value = float(SQmin.GetValue())
2281            if value < qLimits[0]:
2282                raise ValueError
2283        except ValueError:
2284            value = max(qLimits[0],data['QScaleLim'][0])
2285        data['QScaleLim'][0] = value
2286        SQmin.SetValue('%.1f'%(value))
2287        auxPlot = ComputePDF(data)
2288        G2plt.PlotISFG(G2frame,newPlot=True)       
2289       
2290    def OnSQmax(event):
2291        try:
2292            value = float(SQmax.GetValue())
2293            if value > qLimits[1]:
2294                raise ValueError
2295        except ValueError:
2296            value = min(qLimits[1],data['QScaleLim'][1])
2297        data['QScaleLim'][1] = value
2298        if value < data['QScaleLim'][0]:
2299            data['QScaleLim'][0] = 0.90*value
2300            SQmin.SetValue('%.1f'%(data['QScaleLim'][0]))
2301        SQmax.SetValue('%.1f'%(value))
2302        auxPlot = ComputePDF(data)
2303        G2plt.PlotISFG(G2frame,newPlot=True)
2304       
2305    def OnResetQ(event):
2306        resetQ.SetValue(False)
2307        data['QScaleLim'][1] = qLimits[1]
2308        SQmax.SetValue('%.1f'%(data['QScaleLim'][1]))
2309        data['QScaleLim'][0] = 0.9*qLimits[1]
2310        SQmin.SetValue('%.1f'%(data['QScaleLim'][0]))
2311        auxPlot = ComputePDF(data)
2312        G2plt.PlotISFG(G2frame,newPlot=True)       
2313
2314    def GetFileList(fileType,skip=None):
2315        fileList = [[False,'',0]]
2316        Source = ''
2317        id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
2318        while id:
2319            name = G2frame.PatternTree.GetItemText(id)
2320            if fileType in name:
2321                if id == skip:
2322                    Source = name
2323                else:
2324                    fileList.append([False,name,id])
2325            id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
2326        if skip:
2327            return fileList,Source
2328        else:
2329            return fileList
2330       
2331    def OnCopyPDFControls(event):
2332        import copy
2333        TextList,Source = GetFileList('PDF',skip=G2frame.PatternId)
2334        TextList[0] = [False,'All PDF',0]
2335        if len(TextList) == 1:
2336            G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "PDF" pattern')
2337            return
2338        dlg = G2frame.CopyDialog(G2frame,'Copy PDF controls','Copy controls from '+Source+' to:',TextList)
2339        try:
2340            if dlg.ShowModal() == wx.ID_OK:
2341                result = dlg.GetData()
2342                if result[0][0]:
2343                    result = TextList[1:]
2344                    for item in result: item[0] = True
2345                for i,item in enumerate(result):
2346                    ifcopy,name,id = item
2347                    if ifcopy:
2348                        olddata = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'PDF Controls'))
2349                        sample = olddata['Sample']
2350                        olddata.update(copy.deepcopy(data))
2351                        olddata['Sample'] = sample
2352                        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'PDF Controls'),olddata)
2353                Status.SetStatusText('PDF controls copied')
2354        finally:
2355            dlg.Destroy()
2356               
2357    def OnSavePDFControls(event):
2358        print 'save PDF controls?'
2359       
2360    def OnLoadPDFControls(event):
2361        print 'Load PDF controls?'
2362       
2363    def OnAddElement(event):
2364        ElList = data['ElList']
2365        PE = G2elemGUI.PickElement(G2frame,oneOnly=True)
2366        if PE.ShowModal() == wx.ID_OK:
2367            El = PE.Elem
2368            if El not in ElList and El != 'None':
2369                ElemSym = El.strip().upper()               
2370                FpMu = G2elem.FPcalc(G2elem.GetXsectionCoeff(ElemSym), keV)
2371                ElData = G2elem.GetFormFactorCoeff(ElemSym)[0]
2372                ElData['FormulaNo'] = 0.0
2373                ElData.update(G2elem.GetAtomInfo(ElemSym))
2374                ElData.update(dict(zip(['fp','fpp','mu'],FpMu)))
2375                ElData.update(G2elem.GetFFC5(El))
2376                data['ElList'][El] = ElData
2377            data['Form Vol'] = max(10.0,SumElementVolumes())
2378        PE.Destroy()
2379        UpdatePDFGrid(G2frame,data)
2380       
2381    def OnDeleteElement(event):
2382        ElList = data['ElList']
2383        choice = ElList.keys()
2384        dlg = G2elemGUI.DeleteElement(G2frame,choice=choice)
2385        if dlg.ShowModal() == wx.ID_OK:
2386            del ElList[dlg.GetDeleteElement()]
2387        dlg.Destroy()
2388        UpdatePDFGrid(G2frame,data)
2389               
2390    def ComputePDF(Data):
2391        xydata = {}
2392        for key in ['Sample','Sample Bkg.','Container','Container Bkg.']:
2393            name = Data[key]['Name']
2394            if name:
2395                xydata[key] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root,name))
2396                PDFname = name
2397        powName = xydata['Sample'][2]
2398        powId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,powName)
2399        inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId,'Instrument Parameters'))[0]
2400        auxPlot = G2pwd.CalcPDF(Data,inst,xydata)
2401        PDFId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'PDF '+powName[4:])
2402        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'I(Q)'+powName[4:]),xydata['IofQ'])
2403        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'S(Q)'+powName[4:]),xydata['SofQ'])
2404        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'F(Q)'+powName[4:]),xydata['FofQ'])
2405        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'G(R)'+powName[4:]),xydata['GofR'])
2406        return auxPlot
2407       
2408    def OnComputePDF(event):
2409        print 'Calculating PDF:'
2410        auxPlot = ComputePDF(data)
2411        print 'Done calculating PDF:'
2412        Status.SetStatusText('PDF computed')
2413        for plot in auxPlot:
2414            G2plt.PlotXY(G2frame,plot[:2],type=plot[2])
2415       
2416        G2plt.PlotISFG(G2frame,newPlot=True,type='I(Q)')
2417        G2plt.PlotISFG(G2frame,newPlot=True,type='S(Q)')
2418        G2plt.PlotISFG(G2frame,newPlot=True,type='F(Q)')
2419        G2plt.PlotISFG(G2frame,newPlot=True,type='G(R)')
2420       
2421    def OnComputeAllPDF(event):
2422        print 'Calculating PDFs:'
2423        if G2frame.PatternTree.GetCount():
2424            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
2425            while id:
2426                Name = G2frame.PatternTree.GetItemText(id)
2427                if 'PDF' in Name:
2428                    Data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id,'PDF Controls'))
2429                    auxPlot = ComputePDF(Data)                   
2430                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
2431            Status.SetStatusText('All PDFs computed')
2432            G2plt.PlotISFG(G2frame,newPlot=True,type='G(R)')
2433            print ' Done calculating PDFs:'
2434       
2435    def OnShowTip(G2frame,tip):
2436        print tip   
2437               
2438    if G2frame.dataDisplay:
2439        G2frame.dataFrame.Clear()
2440    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.PDFMenu)
2441    if not G2frame.dataFrame.GetStatusBar():
2442        Status = G2frame.dataFrame.CreateStatusBar()   
2443    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
2444    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyPDFControls, id=G2gd.wxID_PDFCOPYCONTROLS)
2445    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSavePDFControls, id=G2gd.wxID_PDFSAVECONTROLS)
2446    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadPDFControls, id=G2gd.wxID_PDFLOADCONTROLS)
2447    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddElement, id=G2gd.wxID_PDFADDELEMENT)
2448    G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteElement, id=G2gd.wxID_PDFDELELEMENT)
2449    G2frame.dataFrame.Bind(wx.EVT_MENU, OnComputePDF, id=G2gd.wxID_PDFCOMPUTE)
2450    G2frame.dataFrame.Bind(wx.EVT_MENU, OnComputeAllPDF, id=G2gd.wxID_PDFCOMPUTEALL)
2451    mainSizer = wx.BoxSizer(wx.VERTICAL)
2452    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' PDF data files: '),0,wx.ALIGN_CENTER_VERTICAL)
2453    mainSizer.Add((5,5),0)
2454    str = ' Sample file: PWDR %s   Wavelength, A: %.5f  Energy, keV: %.3f  Polariz.: %.2f '%(dataFile[3:],wave,keV,polariz)
2455    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=str),0,wx.ALIGN_CENTER_VERTICAL)
2456#    dataSizer = wx.BoxSizer(wx.HORIZONTAL)
2457#    dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Azimuth'),0,wx.ALIGN_CENTER_VERTICAL)
2458#    azimVal = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(inst['Azimuth']))
2459#    azimVal.Bind(wx.EVT_TEXT_ENTER,OnAzimVal)       
2460#    azimVal.Bind(wx.EVT_KILL_FOCUS,OnAzimVal)
2461#    dataSizer.Add(azimVal,0)   
2462#    dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Polarization'),0,wx.ALIGN_CENTER_VERTICAL)
2463#    polaVal = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(inst['Polariz.']))
2464#    polaVal.Bind(wx.EVT_TEXT_ENTER,OnPolaVal)       
2465#    polaVal.Bind(wx.EVT_KILL_FOCUS,OnPolaVal)
2466#    dataSizer.Add(polaVal,0)   
2467#    mainSizer.Add(dataSizer,0)
2468    mainSizer.Add((5,5),0)
2469    fileSizer = wx.FlexGridSizer(3,6,5,1)
2470    select = ['Sample Bkg.','Container']
2471    if data['Container']['Name']:
2472        select.append('Container Bkg.')
2473    for key in select:
2474        FillFileSizer(fileSizer,key)
2475    mainSizer.Add(fileSizer,0)
2476    mainSizer.Add((5,5),0)
2477    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample information: '),0,wx.ALIGN_CENTER_VERTICAL)
2478    mainSizer.Add((5,5),0)   
2479
2480    ElList = data['ElList']
2481    Abs = G2lat.CellAbsorption(ElList,data['Form Vol'])
2482    Trans = G2pwd.Transmission(data['Geometry'],Abs*data['Pack'],data['Diam'])
2483    elemSizer = wx.FlexGridSizer(3,3,5,1)
2484    for El in ElList:
2485        FillElemSizer(elemSizer,ElList[El])
2486    mainSizer.Add(elemSizer,0)
2487    mainSizer.Add((5,5),0)   
2488    midSizer = wx.BoxSizer(wx.HORIZONTAL)
2489    midSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Formula volume: '),0,wx.ALIGN_CENTER_VERTICAL)
2490    formVol = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(data['Form Vol']))
2491    formVol.Bind(wx.EVT_TEXT_ENTER,OnFormVol)       
2492    formVol.Bind(wx.EVT_KILL_FOCUS,OnFormVol)
2493    midSizer.Add(formVol,0)
2494    midSizer.Add(wx.StaticText(G2frame.dataDisplay,
2495        label=' Theoretical absorption: %.4f cm-1 Sample absorption: %.4f cm-1'%(Abs,Abs*data['Pack'])),
2496        0,wx.ALIGN_CENTER_VERTICAL)
2497    mainSizer.Add(midSizer,0)
2498    mainSizer.Add((5,5),0)   
2499
2500    geoBox = wx.BoxSizer(wx.HORIZONTAL)
2501    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample geometry: '),0,wx.ALIGN_CENTER_VERTICAL)
2502    choice = ['Cylinder','Bragg-Brentano','Tilting flat plate in transmission','Fixed flat plate']
2503    geometry = wx.ComboBox(G2frame.dataDisplay,value=data['Geometry'],choices=choice,
2504            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2505    geometry.Bind(wx.EVT_COMBOBOX, OnGeometry)
2506    geoBox.Add(geometry,0)
2507    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample diameter/thickness, mm: '),0,wx.ALIGN_CENTER_VERTICAL)
2508    diam = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Diam']))
2509    diam.Bind(wx.EVT_TEXT_ENTER,OnDiameter)       
2510    diam.Bind(wx.EVT_KILL_FOCUS,OnDiameter)
2511#    diam.Bind(wx.EVT_SET_FOCUS,OnShowTip(G2frame,'tip')) #this doesn't work - what would????
2512    geoBox.Add(diam,0)
2513    mainSizer.Add(geoBox,0)
2514    mainSizer.Add((5,5),0)   
2515    geoBox = wx.BoxSizer(wx.HORIZONTAL)
2516    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Packing: '),0,wx.ALIGN_CENTER_VERTICAL)
2517    pack = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(data['Pack']))
2518    pack.Bind(wx.EVT_TEXT_ENTER,OnPacking)       
2519    pack.Bind(wx.EVT_KILL_FOCUS,OnPacking)
2520    geoBox.Add(pack,0)
2521    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample transmission: %.3f %%'%(Trans)),0,wx.ALIGN_CENTER_VERTICAL)   
2522    mainSizer.Add(geoBox,0)
2523    mainSizer.Add((5,5),0)   
2524       
2525    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' S(Q)->F(Q)->G(R) controls: '),0,wx.ALIGN_CENTER_VERTICAL)
2526    mainSizer.Add((5,5),0)
2527    sqBox = wx.BoxSizer(wx.HORIZONTAL)
2528    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Detector type: '),0,wx.ALIGN_CENTER_VERTICAL)
2529    choice = ['Image plate','Point detector']
2530    detType = wx.ComboBox(G2frame.dataDisplay,value=data['DetType'],choices=choice,
2531            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2532    detType.Bind(wx.EVT_COMBOBOX, OnDetType)
2533    sqBox.Add(detType,0)
2534    if data['DetType'] == 'Image plate':
2535        sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' IP transmission coeff.: '),0,wx.ALIGN_CENTER_VERTICAL)
2536        obliqCoeff = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['ObliqCoeff']))
2537        obliqCoeff.Bind(wx.EVT_TEXT_ENTER,OnObliqCoeff)       
2538        obliqCoeff.Bind(wx.EVT_KILL_FOCUS,OnObliqCoeff)
2539        sqBox.Add(obliqCoeff,0)
2540    mainSizer.Add(sqBox,0)
2541       
2542    sqBox = wx.BoxSizer(wx.HORIZONTAL)
2543    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Ruland width: '),0,wx.ALIGN_CENTER_VERTICAL)   
2544    rulandSldr = wx.Slider(parent=G2frame.dataDisplay,style=wx.SL_HORIZONTAL,
2545        value=int(1000*data['Ruland']))
2546    sqBox.Add(rulandSldr,1,wx.EXPAND)
2547    rulandSldr.Bind(wx.EVT_SLIDER, OnRulSlider)
2548    rulandWdt = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Ruland']))
2549    rulandWdt.Bind(wx.EVT_TEXT_ENTER,OnRulandWdt)       
2550    rulandWdt.Bind(wx.EVT_KILL_FOCUS,OnRulandWdt)
2551    sqBox.Add(rulandWdt,0,wx.ALIGN_CENTER_VERTICAL)   
2552    mainSizer.Add(sqBox,0,wx.ALIGN_LEFT|wx.EXPAND)
2553   
2554    sqBox = wx.BoxSizer(wx.HORIZONTAL)
2555    lorch = wx.CheckBox(parent=G2frame.dataDisplay,label='Lorch damping?')
2556    lorch.SetValue(data['Lorch'])
2557    lorch.Bind(wx.EVT_CHECKBOX, OnLorch)
2558    sqBox.Add(lorch,0,wx.ALIGN_CENTER_VERTICAL)
2559    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Scaling q-range: '),0,wx.ALIGN_CENTER_VERTICAL)
2560    SQmin = wx.TextCtrl(G2frame.dataDisplay,value='%.1f'%(data['QScaleLim'][0]))
2561    SQmin.Bind(wx.EVT_TEXT_ENTER,OnSQmin)       
2562    SQmin.Bind(wx.EVT_KILL_FOCUS,OnSQmin)   
2563    sqBox.Add(SQmin,0)
2564    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' to '),0,wx.ALIGN_CENTER_VERTICAL)
2565    SQmax = wx.TextCtrl(G2frame.dataDisplay,value='%.1f'%(data['QScaleLim'][1]))
2566    SQmax.Bind(wx.EVT_TEXT_ENTER,OnSQmax)       
2567    SQmax.Bind(wx.EVT_KILL_FOCUS,OnSQmax)
2568    sqBox.Add(SQmax,0)
2569    resetQ = wx.CheckBox(parent=G2frame.dataDisplay,label='Reset?')
2570    sqBox.Add(resetQ,0)
2571    resetQ.Bind(wx.EVT_CHECKBOX, OnResetQ)
2572   
2573    mainSizer.Add(sqBox,0)
2574
2575    mainSizer.Layout()   
2576    G2frame.dataDisplay.SetSizer(mainSizer)
2577    Size = mainSizer.Fit(G2frame.dataFrame)
2578    G2frame.dataDisplay.SetSize(Size)
2579    G2frame.dataFrame.setSizePosLeft(Size)
2580   
Note: See TracBrowser for help on using the repository browser.