source: trunk/GSASIIpwdGUI.py @ 1244

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

fix geometric correction in integrate - too many 1/cos(2-theta)
plot of size distribution from SASD
MaxEnt? size distribution in operation (some tuning/errors)

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