source: trunk/GSASIIpwdGUI.py @ 1232

Last change on this file since 1232 was 1232, checked in by vondreele, 8 years ago

add copy substances
fix azimuth offset in polarization calc
make sasd come out as semilog plot
fix limits in log plots

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