source: trunk/GSASIIpwdGUI.py @ 1233

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

replace wx.Align_CENTER_VERTICAL with WACV in G2pwdGUI & G2phsGUI
start on SASD modelling

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 142.8 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASIIpwdGUI - powder data display routines
3########### SVN repository information ###################
4# $Date: 2014-03-03 15:16:53 +0000 (Mon, 03 Mar 2014) $
5# $Author: vondreele $
6# $Revision: 1233 $
7# $URL: trunk/GSASIIpwdGUI.py $
8# $Id: GSASIIpwdGUI.py 1233 2014-03-03 15:16:53Z 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: 1233 $")
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+':10,3',]
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,Limits,Substances,Sample,data)
2451       
2452    def OnSelectFit(event):
2453        data['Current'] = fitSel.GetValue()
2454        wx.CallAfter(UpdateModelsGrid,G2frame,data)
2455       
2456    def OnValueChange(event):
2457        Obj = event.GetEventObject()
2458        itemKey,ind,fmt = Indx[Obj.GetId()]
2459        try:
2460            value = float(Obj.GetValue())
2461        except ValueError:
2462            value = 0.0
2463        Obj.SetValue(fmt%(value))
2464        data[itemKey][ind] = value
2465       
2466    def OnCheckBox(event):
2467        Obj = event.GetEventObject()
2468        itemKey,ind = Indx[Obj.GetId()]
2469        data[itemKey][ind] = Obj.GetValue()
2470       
2471    def OnIntVal(event):
2472        Obj = event.GetEventObject()
2473        item,ind = Indx[Obj.GetId()]
2474        item[ind] = int(Obj.GetValue())
2475       
2476    def SizeSizer():
2477       
2478        def OnShape(event):
2479            data['Size']['Shape'][0] = partsh.GetValue()
2480            wx.CallAfter(UpdateModelsGrid,G2frame,data)
2481           
2482        def OnMethod(event):
2483            data['Size']['Method'] = method.GetValue()
2484            wx.CallAfter(UpdateModelsGrid,G2frame,data)
2485           
2486        def OnPartVal(event):
2487            try:
2488                val = max(0.0,float(partprm.GetValue()))
2489            except ValueError:
2490                val = 1
2491            data['Size']['Shape'][1] = val
2492            partprm.SetValue('%.3f'%(val))
2493           
2494        for item in data['Size']: print item,data['Size'][item]
2495        sizeSizer = wx.BoxSizer(wx.VERTICAL)
2496        sizeSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Size distribution parameters: '),0,WACV)
2497        binSizer = wx.FlexGridSizer(1,7,5,5)
2498        binSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' No. size bins: '),0,WACV)
2499        bins = ['50','100','150','200']
2500        nbins = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['Nbins']),choices=bins,
2501            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2502        Indx[nbins.GetId()] = [data['Size'],'Nbins']
2503        nbins.Bind(wx.EVT_COMBOBOX,OnIntVal)       
2504        binSizer.Add(nbins,0,WACV)
2505        binSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min diam.: '),0,WACV)
2506        minDias = ['10','25','50','100','150','200']
2507        mindiam = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['MinDiam']),choices=minDias,
2508            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2509        mindiam.Bind(wx.EVT_COMBOBOX,OnIntVal)       
2510        Indx[mindiam.GetId()] = [data['Size'],'MinDiam']
2511        binSizer.Add(mindiam,0,WACV)
2512        binSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Max diam.: '),0,WACV)
2513        maxDias = [str(1000*(i+1)) for i in range(10)]
2514        maxdiam = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['MaxDiam']),choices=maxDias,
2515            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2516        maxdiam.Bind(wx.EVT_COMBOBOX,OnIntVal)       
2517        Indx[maxdiam.GetId()] = [data['Size'],'MaxDiam']
2518        binSizer.Add(maxdiam,0,WACV)
2519        logbins = wx.CheckBox(G2frame.dataDisplay,label='Log bins?')
2520        Indx[logbins.GetId()] = ['Size','logBins']
2521        logbins.SetValue(data['Size']['logBins'])
2522        logbins.Bind(wx.EVT_CHECKBOX, OnCheckBox)
2523        binSizer.Add(logbins,0,WACV)
2524        sizeSizer.Add(binSizer,0)
2525        sizeSizer.Add((5,5),0)
2526        partSizer = wx.BoxSizer(wx.HORIZONTAL)
2527        partSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Particle description: '),0,WACV)
2528        shapes = {'Spheroid':' Aspect ratio: ','Cylinder Diam.':' Diameter ','Cylinder AR':' Aspect ratio: ',
2529            'Unified sphere':'','Unified rod':' Diameter: ','Unified rod AR':' Aspect ratio: ',
2530            'Unified disk':' Thickness: '}
2531        partsh = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['Shape'][0]),choices=shapes.keys(),
2532            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2533        partsh.Bind(wx.EVT_COMBOBOX,OnShape)       
2534        partSizer.Add(partsh,0,WACV)
2535        if data['Size']['Shape'][0] not in ['Unified sphere',]:
2536            partSizer.Add(wx.StaticText(G2frame.dataDisplay,label=shapes[data['Size']['Shape'][0]]),0,WACV)
2537            partprm = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Size']['Shape'][1]),
2538                style=wx.TE_PROCESS_ENTER)
2539            partprm.Bind(wx.EVT_TEXT_ENTER,OnPartVal)       
2540            partprm.Bind(wx.EVT_KILL_FOCUS,OnPartVal)
2541            partSizer.Add(partprm,0,WACV)
2542        sizeSizer.Add(partSizer,0)
2543        sizeSizer.Add((5,5),0)
2544        fitSizer = wx.BoxSizer(wx.HORIZONTAL)
2545        methods = ['MaxEnt','IPG',]
2546        fitSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Fitting method: '),0,WACV)
2547        method = wx.ComboBox(G2frame.dataDisplay,value=data['Size']['Method'],choices=methods,
2548            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2549        method.Bind(wx.EVT_COMBOBOX,OnMethod)
2550        fitSizer.Add(method,0,WACV)
2551        iters = ['10','25','50','100','150','200']       
2552        fitSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' No. iterations: '),0,WACV)
2553        Method = data['Size']['Method']
2554        iter = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size'][Method]['Niter']),choices=iters,
2555            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2556        Indx[iter.GetId()] = [data['Size'][Method],'Niter']
2557        iter.Bind(wx.EVT_COMBOBOX,OnIntVal)
2558        fitSizer.Add(iter,0,WACV)
2559       
2560        sizeSizer.Add(fitSizer,0)
2561
2562        return sizeSizer
2563       
2564    def PartSizer():
2565        for item in data['Particle']: print item,data['Particle'][item]
2566        partSizer = wx.BoxSizer(wx.VERTICAL)
2567        partSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Particle fit parameters: '),0,WACV)
2568        return partSizer
2569       
2570    def UnifSizer():
2571        for item in data['Unified']: print item,data['Unified'][item]
2572        unifSizer = wx.BoxSizer(wx.VERTICAL)
2573        unifSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Unified fit parameters: '),0,WACV)
2574        return unifSizer
2575       
2576    Sample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Sample Parameters'))
2577    Limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Limits'))
2578    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))
2579    Substances = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Substances'))
2580    Profile = G2frame.PatternTree.GetItemPyData(G2frame.PatternId)[1]
2581
2582    if G2frame.dataDisplay:
2583        G2frame.dataFrame.DestroyChildren()
2584    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ModelMenu)
2585    if not G2frame.dataFrame.GetStatusBar():
2586        Status = G2frame.dataFrame.CreateStatusBar()
2587    G2frame.dataFrame.SetLabel('Modelling')
2588    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
2589    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyModel, id=G2gd.wxID_MODELCOPY)
2590    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitModel, id=G2gd.wxID_MODELFIT)
2591    Indx = {}
2592    mainSizer = wx.BoxSizer(wx.VERTICAL)
2593    topSizer = wx.BoxSizer(wx.HORIZONTAL)
2594    models = ['Size dist.','Unified fit','Particle fit']
2595    topSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Modeling by: '),0,WACV)
2596    fitSel = wx.ComboBox(G2frame.dataDisplay,value=data['Current'],choices=models,
2597        style=wx.CB_READONLY|wx.CB_DROPDOWN)
2598    fitSel.Bind(wx.EVT_COMBOBOX,OnSelectFit)       
2599    topSizer.Add(fitSel,0,WACV)
2600    mainSizer.Add(topSizer)
2601    G2gd.HorizontalLine(mainSizer,G2frame.dataDisplay)
2602    if 'Size' in data['Current']:
2603        mainSizer.Add(SizeSizer())       
2604    elif 'Particle' in data['Current']:
2605        mainSizer.Add(PartSizer())
2606    elif 'Unified' in data['Current']:
2607        mainSizer.Add(UnifSizer())
2608    G2gd.HorizontalLine(mainSizer,G2frame.dataDisplay)   
2609    backSizer = wx.BoxSizer(wx.HORIZONTAL)
2610    backSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Background:'),0,WACV)
2611    backVal = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Back'][0]),style=wx.TE_PROCESS_ENTER)
2612    Indx[backVal.GetId()] = ['Back',0,'%.3f']
2613    backVal.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2614    backVal.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2615    backSizer.Add(backVal,0,WACV)
2616    backVar = wx.CheckBox(G2frame.dataDisplay,label='Apply?')
2617    Indx[backVar.GetId()] = ['Back',1]
2618    backVar.SetValue(data['Back'][1])
2619    backVar.Bind(wx.EVT_CHECKBOX, OnCheckBox)
2620    backSizer.Add(backVar,0,WACV)
2621    mainSizer.Add(backSizer)
2622
2623    mainSizer.Layout()   
2624    G2frame.dataDisplay.SetSizer(mainSizer)
2625    G2frame.dataDisplay.SetAutoLayout(1)
2626    G2frame.dataDisplay.SetupScrolling()
2627    Size = mainSizer.Fit(G2frame.dataFrame)
2628    Size[0] += 25
2629    G2frame.dataDisplay.SetSize(Size)
2630    G2frame.dataFrame.setSizePosLeft(Size)   
2631       
2632   
2633################################################################################
2634#####  PDF controls
2635################################################################################           
2636       
2637def UpdatePDFGrid(G2frame,data):
2638    '''respond to selection of PWDR PDF data tree item.
2639    '''
2640    global inst
2641    tth2q = lambda t,w:4.0*math.pi*sind(t/2.0)/w
2642    dataFile = G2frame.PatternTree.GetItemText(G2frame.PatternId)
2643    powName = 'PWDR'+dataFile[4:]
2644    powId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, powName)
2645    fullLimits,limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId, 'Limits'))[:2]
2646    inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId, 'Instrument Parameters'))[0]
2647    if 'Lam' in inst:
2648        keV = 12.397639/inst['Lam'][1]
2649    else:
2650        keV = 12.397639/inst['Lam1'][0]
2651    wave = 12.397639/keV
2652    qLimits = [tth2q(fullLimits[0],wave),tth2q(fullLimits[1],wave)]
2653    data['QScaleLim'][1] = min(qLimits[1],data['QScaleLim'][1])
2654    if data['QScaleLim'][0]:
2655        data['QScaleLim'][0] = max(qLimits[0],data['QScaleLim'][0])
2656    else:                                #initial setting at 90% of max Q
2657        data['QScaleLim'][0] = 0.90*data['QScaleLim'][1]
2658    polariz = inst['Polariz.'][1]
2659    azimuth = inst['Azimuth'][1]
2660    itemDict = {}
2661   
2662    def FillFileSizer(fileSizer,key):
2663        #fileSizer is a FlexGridSizer(3,6)
2664       
2665        def OnSelectFile(event):
2666            Obj = event.GetEventObject()
2667            fileKey,itemKey,fmt = itemDict[Obj.GetId()]
2668            if itemKey == 'Name':
2669                value = Obj.GetValue()
2670            Obj.SetValue(fmt%(value))
2671            data[fileKey][itemKey] = value
2672            UpdatePDFGrid(G2frame,data)
2673       
2674        def OnValueChange(event):
2675            Obj = event.GetEventObject()
2676            fileKey,itemKey,fmt = itemDict[Obj.GetId()]
2677            try:
2678                value = float(Obj.GetValue())
2679            except ValueError:
2680                value = -1.0
2681            Obj.SetValue(fmt%(value))
2682            data[fileKey][itemKey] = value
2683            auxPlot = ComputePDF(data)
2684            G2plt.PlotISFG(G2frame,newPlot=True)
2685                       
2686        item = data[key]
2687        fileList = np.array(GetFileList('PWDR')).T[1]
2688        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' '+key+' file:'),0,WACV)
2689        fileName = wx.ComboBox(G2frame.dataDisplay,value=item['Name'],choices=fileList,
2690            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2691        itemDict[fileName.GetId()] = [key,'Name','%s']
2692        fileName.Bind(wx.EVT_COMBOBOX,OnSelectFile)       
2693        fileSizer.Add(fileName,0,)
2694        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Multiplier:'),0,WACV)
2695        mult = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(item['Mult']),style=wx.TE_PROCESS_ENTER)
2696        itemDict[mult.GetId()] = [key,'Mult','%.3f']
2697        mult.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2698        mult.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2699        fileSizer.Add(mult,0,)
2700        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Add:'),0,WACV)
2701        add = wx.TextCtrl(G2frame.dataDisplay,value='%.0f'%(item['Add']),style=wx.TE_PROCESS_ENTER)
2702        itemDict[add.GetId()] = [key,'Add','%.0f']
2703        add.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2704        add.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2705        fileSizer.Add(add,0,)
2706       
2707    def SumElementVolumes():
2708        sumVol = 0.
2709        ElList = data['ElList']
2710        for El in ElList:
2711            Avol = (4.*math.pi/3.)*ElList[El]['Drad']**3
2712            sumVol += Avol*ElList[El]['FormulaNo']
2713        return sumVol
2714        auxPlot = ComputePDF(data)
2715        G2plt.PlotISFG(G2frame,newPlot=True)       
2716       
2717    def FillElemSizer(elemSizer,ElData):
2718       
2719        def OnFractionChange(event):
2720            try:
2721                value = max(0.0,float(num.GetValue()))
2722            except ValueError:
2723                value = 0.0
2724            num.SetValue('%.3f'%(value))
2725            ElData['FormulaNo'] = value
2726            data['Form Vol'] = max(10.0,SumElementVolumes())
2727            formVol.SetValue('%.2f'%(data['Form Vol']))
2728            wx.CallAfter(UpdatePDFGrid,G2frame,data)
2729            auxPlot = ComputePDF(data)
2730            G2plt.PlotISFG(G2frame,newPlot=True)       
2731       
2732        elemSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,
2733            label=' Element: '+'%2s'%(ElData['Symbol'])+' * '),0,WACV)
2734        num = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(ElData['FormulaNo']),style=wx.TE_PROCESS_ENTER)
2735        num.Bind(wx.EVT_TEXT_ENTER,OnFractionChange)       
2736        num.Bind(wx.EVT_KILL_FOCUS,OnFractionChange)
2737        elemSizer.Add(num,0,WACV)
2738        elemSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,
2739            label="f': %.3f"%(ElData['fp'])+' f": %.3f'%(ElData['fpp'])+' mu: %.2f barns'%(ElData['mu']) ),
2740            0,WACV)
2741           
2742    def OnGeometry(event):
2743        data['Geometry'] = geometry.GetValue()
2744        UpdatePDFGrid(G2frame,data)
2745        auxPlot = ComputePDF(data)
2746        G2plt.PlotISFG(G2frame,newPlot=True)       
2747       
2748    def OnDetType(event):
2749        data['DetType'] = detType.GetValue()
2750        UpdatePDFGrid(G2frame,data)
2751        auxPlot = ComputePDF(data)
2752        G2plt.PlotISFG(G2frame,newPlot=True)       
2753       
2754    def OnFormVol(event):
2755        try:
2756            value = float(formVol.GetValue())
2757            if value <= 0.0:
2758                raise ValueError
2759        except ValueError:
2760            value = data['Form Vol']
2761        data['Form Vol'] = value
2762        UpdatePDFGrid(G2frame,data)
2763        auxPlot = ComputePDF(data)
2764        G2plt.PlotISFG(G2frame,newPlot=False)       
2765       
2766    def OnDiameter(event):
2767        try:
2768            value = float(diam.GetValue())
2769            if value <= 0.0:
2770                raise ValueError
2771        except ValueError:
2772            value = data['Diam']
2773        data['Diam'] = value
2774        UpdatePDFGrid(G2frame,data)
2775        auxPlot = ComputePDF(data)
2776        G2plt.PlotISFG(G2frame,newPlot=False)
2777       
2778    def OnPolaVal(event):
2779        try:
2780            value = float(polaVal.GetValue())
2781            if not (0.0 <= value <= 1.0):
2782                raise ValueError
2783        except ValueError:
2784            value = inst['Polariz.'][1]
2785        inst['Polariz.'][1] = value
2786        polaVal.SetValue('%.2f'%(inst['Polariz.'][1]))
2787        UpdatePDFGrid(G2frame,data)
2788        auxPlot = ComputePDF(data)
2789        G2plt.PlotISFG(G2frame,newPlot=False)
2790               
2791    def OnAzimVal(event):
2792        try:
2793            value = float(azimVal.GetValue())
2794            if not (0. <= value <= 360.):
2795                raise ValueError
2796        except ValueError:
2797            value = inst['Azimuth'][1]
2798        inst['Azimuth'][1] = value
2799        azimVal.SetValue('%.1f'%(inst['Azimuth'][1]))
2800        UpdatePDFGrid(G2frame,data)
2801        auxPlot = ComputePDF(data)
2802        G2plt.PlotISFG(G2frame,newPlot=False)
2803                       
2804    def OnObliqCoeff(event):
2805        try:
2806            value = float(obliqCoeff.GetValue())
2807            if value < 0.0:
2808                raise ValueError
2809            elif value > 1.0:
2810                value = 1.0
2811        except ValueError:
2812            value = data['ObliqCoeff']
2813        data['ObliqCoeff'] = value
2814        obliqCoeff.SetValue('%.3f'%(value))
2815        auxPlot = ComputePDF(data)
2816        G2plt.PlotISFG(G2frame,newPlot=False)
2817       
2818    def OnRulandWdt(event):
2819        try:
2820            value = float(rulandWdt.GetValue())
2821            if value <= 0.001:
2822                raise ValueError
2823            elif value > 1.0:
2824                value = 1.0
2825        except ValueError:
2826            value = data['Ruland']
2827        data['Ruland'] = value
2828        rulandWdt.SetValue('%.3f'%(value))
2829        auxPlot = ComputePDF(data)
2830        G2plt.PlotISFG(G2frame,newPlot=False)
2831       
2832    def OnRulSlider(event):
2833        value = int(rulandSldr.GetValue())/1000.
2834        data['Ruland'] = max(0.001,value)
2835        rulandWdt.SetValue('%.3f'%(data['Ruland']))
2836        auxPlot = ComputePDF(data)
2837        G2plt.PlotISFG(G2frame,newPlot=False)
2838       
2839    def OnLorch(event):
2840        data['Lorch'] = lorch.GetValue()
2841        auxPlot = ComputePDF(data)
2842        G2plt.PlotISFG(G2frame,newPlot=False)       
2843                       
2844    def OnPacking(event):
2845        try:
2846            value = float(pack.GetValue())
2847            if value <= 0.0:
2848                raise ValueError
2849        except ValueError:
2850            value = data['Pack']
2851        data['Pack'] = value
2852        UpdatePDFGrid(G2frame,data)
2853        auxPlot = ComputePDF(data)
2854        G2plt.PlotISFG(G2frame,newPlot=False)       
2855               
2856    def OnSQmin(event):
2857        try:
2858            value = float(SQmin.GetValue())
2859            if value < qLimits[0]:
2860                raise ValueError
2861        except ValueError:
2862            value = max(qLimits[0],data['QScaleLim'][0])
2863        data['QScaleLim'][0] = value
2864        SQmin.SetValue('%.1f'%(value))
2865        auxPlot = ComputePDF(data)
2866        G2plt.PlotISFG(G2frame,newPlot=True)       
2867       
2868    def OnSQmax(event):
2869        try:
2870            value = float(SQmax.GetValue())
2871            if value > qLimits[1]:
2872                raise ValueError
2873        except ValueError:
2874            value = min(qLimits[1],data['QScaleLim'][1])
2875        data['QScaleLim'][1] = value
2876        if value < data['QScaleLim'][0]:
2877            data['QScaleLim'][0] = 0.90*value
2878            SQmin.SetValue('%.1f'%(data['QScaleLim'][0]))
2879        SQmax.SetValue('%.1f'%(value))
2880        auxPlot = ComputePDF(data)
2881        G2plt.PlotISFG(G2frame,newPlot=True)
2882       
2883    def OnResetQ(event):
2884        resetQ.SetValue(False)
2885        data['QScaleLim'][1] = qLimits[1]
2886        SQmax.SetValue('%.1f'%(data['QScaleLim'][1]))
2887        data['QScaleLim'][0] = 0.9*qLimits[1]
2888        SQmin.SetValue('%.1f'%(data['QScaleLim'][0]))
2889        auxPlot = ComputePDF(data)
2890        G2plt.PlotISFG(G2frame,newPlot=True)       
2891
2892    def GetFileList(fileType,skip=None):
2893        fileList = [[False,'',0]]
2894        Source = ''
2895        id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
2896        while id:
2897            name = G2frame.PatternTree.GetItemText(id)
2898            if fileType in name:
2899                if id == skip:
2900                    Source = name
2901                else:
2902                    fileList.append([False,name,id])
2903            id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
2904        if skip:
2905            return fileList,Source
2906        else:
2907            return fileList
2908       
2909    def OnCopyPDFControls(event):
2910        import copy
2911        TextList,Source = GetFileList('PDF',skip=G2frame.PatternId)
2912        TextList[0] = [False,'All PDF',0]
2913        if len(TextList) == 1:
2914            G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "PDF" pattern')
2915            return
2916        dlg = G2frame.CopyDialog(G2frame,'Copy PDF controls','Copy controls from '+Source+' to:',TextList)
2917        try:
2918            if dlg.ShowModal() == wx.ID_OK:
2919                result = dlg.GetData()
2920                if result[0][0]:
2921                    result = TextList[1:]
2922                    for item in result: item[0] = True
2923                for i,item in enumerate(result):
2924                    ifcopy,name,id = item
2925                    if ifcopy:
2926                        olddata = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'PDF Controls'))
2927                        sample = olddata['Sample']
2928                        olddata.update(copy.deepcopy(data))
2929                        olddata['Sample'] = sample
2930                        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'PDF Controls'),olddata)
2931                Status.SetStatusText('PDF controls copied')
2932        finally:
2933            dlg.Destroy()
2934               
2935    def OnSavePDFControls(event):
2936        print 'save PDF controls?'
2937       
2938    def OnLoadPDFControls(event):
2939        print 'Load PDF controls?'
2940       
2941    def OnAddElement(event):
2942        ElList = data['ElList']
2943        PE = G2elemGUI.PickElement(G2frame,oneOnly=True)
2944        if PE.ShowModal() == wx.ID_OK:
2945            El = PE.Elem
2946            if El not in ElList and El != 'None':
2947                ElemSym = El.strip().upper()               
2948                FpMu = G2elem.FPcalc(G2elem.GetXsectionCoeff(ElemSym), keV)
2949                ElData = G2elem.GetFormFactorCoeff(ElemSym)[0]
2950                ElData['FormulaNo'] = 0.0
2951                ElData.update(G2elem.GetAtomInfo(ElemSym))
2952                ElData.update(dict(zip(['fp','fpp','mu'],FpMu)))
2953                ElData.update(G2elem.GetFFC5(El))
2954                data['ElList'][El] = ElData
2955            data['Form Vol'] = max(10.0,SumElementVolumes())
2956        PE.Destroy()
2957        UpdatePDFGrid(G2frame,data)
2958       
2959    def OnDeleteElement(event):
2960        ElList = data['ElList']
2961        choice = ElList.keys()
2962        dlg = G2elemGUI.DeleteElement(G2frame,choice=choice)
2963        if dlg.ShowModal() == wx.ID_OK:
2964            del ElList[dlg.GetDeleteElement()]
2965        dlg.Destroy()
2966        UpdatePDFGrid(G2frame,data)
2967               
2968    def ComputePDF(Data):
2969        xydata = {}
2970        for key in ['Sample','Sample Bkg.','Container','Container Bkg.']:
2971            name = Data[key]['Name']
2972            if name:
2973                xydata[key] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root,name))
2974                PDFname = name
2975        powName = xydata['Sample'][2]
2976        powId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,powName)
2977        inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId,'Instrument Parameters'))[0]
2978        auxPlot = G2pwd.CalcPDF(Data,inst,xydata)
2979        PDFId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'PDF '+powName[4:])
2980        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'I(Q)'+powName[4:]),xydata['IofQ'])
2981        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'S(Q)'+powName[4:]),xydata['SofQ'])
2982        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'F(Q)'+powName[4:]),xydata['FofQ'])
2983        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'G(R)'+powName[4:]),xydata['GofR'])
2984        return auxPlot
2985       
2986    def OnComputePDF(event):
2987        print 'Calculating PDF:'
2988        auxPlot = ComputePDF(data)
2989        print 'Done calculating PDF:'
2990        Status.SetStatusText('PDF computed')
2991        for plot in auxPlot:
2992            G2plt.PlotXY(G2frame,plot[:2],type=plot[2])
2993       
2994        G2plt.PlotISFG(G2frame,newPlot=True,type='I(Q)')
2995        G2plt.PlotISFG(G2frame,newPlot=True,type='S(Q)')
2996        G2plt.PlotISFG(G2frame,newPlot=True,type='F(Q)')
2997        G2plt.PlotISFG(G2frame,newPlot=True,type='G(R)')
2998       
2999    def OnComputeAllPDF(event):
3000        print 'Calculating PDFs:'
3001        if G2frame.PatternTree.GetCount():
3002            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
3003            while id:
3004                Name = G2frame.PatternTree.GetItemText(id)
3005                if 'PDF' in Name:
3006                    Data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id,'PDF Controls'))
3007                    auxPlot = ComputePDF(Data)                   
3008                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
3009            Status.SetStatusText('All PDFs computed')
3010            G2plt.PlotISFG(G2frame,newPlot=True,type='G(R)')
3011            print ' Done calculating PDFs:'
3012       
3013    def OnShowTip(G2frame,tip):
3014        print tip   
3015               
3016    if G2frame.dataDisplay:
3017        G2frame.dataFrame.Clear()
3018    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.PDFMenu)
3019    if not G2frame.dataFrame.GetStatusBar():
3020        Status = G2frame.dataFrame.CreateStatusBar()   
3021    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
3022    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyPDFControls, id=G2gd.wxID_PDFCOPYCONTROLS)
3023    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSavePDFControls, id=G2gd.wxID_PDFSAVECONTROLS)
3024    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadPDFControls, id=G2gd.wxID_PDFLOADCONTROLS)
3025    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddElement, id=G2gd.wxID_PDFADDELEMENT)
3026    G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteElement, id=G2gd.wxID_PDFDELELEMENT)
3027    G2frame.dataFrame.Bind(wx.EVT_MENU, OnComputePDF, id=G2gd.wxID_PDFCOMPUTE)
3028    G2frame.dataFrame.Bind(wx.EVT_MENU, OnComputeAllPDF, id=G2gd.wxID_PDFCOMPUTEALL)
3029    mainSizer = wx.BoxSizer(wx.VERTICAL)
3030    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' PDF data files: '),0,WACV)
3031    mainSizer.Add((5,5),0)
3032    str = ' Sample file: PWDR %s   Wavelength, A: %.5f  Energy, keV: %.3f  Polariz.: %.2f '%(dataFile[3:],wave,keV,polariz)
3033    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=str),0,WACV)
3034#    dataSizer = wx.BoxSizer(wx.HORIZONTAL)
3035#    dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Azimuth'),0,WACV)
3036#    azimVal = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(inst['Azimuth']))
3037#    azimVal.Bind(wx.EVT_TEXT_ENTER,OnAzimVal)       
3038#    azimVal.Bind(wx.EVT_KILL_FOCUS,OnAzimVal)
3039#    dataSizer.Add(azimVal,0)   
3040#    dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Polarization'),0,WACV)
3041#    polaVal = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(inst['Polariz.']))
3042#    polaVal.Bind(wx.EVT_TEXT_ENTER,OnPolaVal)       
3043#    polaVal.Bind(wx.EVT_KILL_FOCUS,OnPolaVal)
3044#    dataSizer.Add(polaVal,0)   
3045#    mainSizer.Add(dataSizer,0)
3046    mainSizer.Add((5,5),0)
3047    fileSizer = wx.FlexGridSizer(3,6,5,1)
3048    select = ['Sample Bkg.','Container']
3049    if data['Container']['Name']:
3050        select.append('Container Bkg.')
3051    for key in select:
3052        FillFileSizer(fileSizer,key)
3053    mainSizer.Add(fileSizer,0)
3054    mainSizer.Add((5,5),0)
3055    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample information: '),0,WACV)
3056    mainSizer.Add((5,5),0)   
3057
3058    ElList = data['ElList']
3059    Abs = G2lat.CellAbsorption(ElList,data['Form Vol'])
3060    Trans = G2pwd.Transmission(data['Geometry'],Abs*data['Pack'],data['Diam'])
3061    elemSizer = wx.FlexGridSizer(3,3,5,1)
3062    for El in ElList:
3063        FillElemSizer(elemSizer,ElList[El])
3064    mainSizer.Add(elemSizer,0)
3065    mainSizer.Add((5,5),0)   
3066    midSizer = wx.BoxSizer(wx.HORIZONTAL)
3067    midSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Formula volume: '),0,WACV)
3068    formVol = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(data['Form Vol']))
3069    formVol.Bind(wx.EVT_TEXT_ENTER,OnFormVol)       
3070    formVol.Bind(wx.EVT_KILL_FOCUS,OnFormVol)
3071    midSizer.Add(formVol,0)
3072    midSizer.Add(wx.StaticText(G2frame.dataDisplay,
3073        label=' Theoretical absorption: %.4f cm-1 Sample absorption: %.4f cm-1'%(Abs,Abs*data['Pack'])),
3074        0,WACV)
3075    mainSizer.Add(midSizer,0)
3076    mainSizer.Add((5,5),0)   
3077
3078    geoBox = wx.BoxSizer(wx.HORIZONTAL)
3079    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample geometry: '),0,WACV)
3080    choice = ['Cylinder','Bragg-Brentano','Tilting flat plate in transmission','Fixed flat plate']
3081    geometry = wx.ComboBox(G2frame.dataDisplay,value=data['Geometry'],choices=choice,
3082            style=wx.CB_READONLY|wx.CB_DROPDOWN)
3083    geometry.Bind(wx.EVT_COMBOBOX, OnGeometry)
3084    geoBox.Add(geometry,0)
3085    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample diameter/thickness, mm: '),0,WACV)
3086    diam = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Diam']))
3087    diam.Bind(wx.EVT_TEXT_ENTER,OnDiameter)       
3088    diam.Bind(wx.EVT_KILL_FOCUS,OnDiameter)
3089#    diam.Bind(wx.EVT_SET_FOCUS,OnShowTip(G2frame,'tip')) #this doesn't work - what would????
3090    geoBox.Add(diam,0)
3091    mainSizer.Add(geoBox,0)
3092    mainSizer.Add((5,5),0)   
3093    geoBox = wx.BoxSizer(wx.HORIZONTAL)
3094    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Packing: '),0,WACV)
3095    pack = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(data['Pack']))
3096    pack.Bind(wx.EVT_TEXT_ENTER,OnPacking)       
3097    pack.Bind(wx.EVT_KILL_FOCUS,OnPacking)
3098    geoBox.Add(pack,0)
3099    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample transmission: %.3f %%'%(Trans)),0,WACV)   
3100    mainSizer.Add(geoBox,0)
3101    mainSizer.Add((5,5),0)   
3102       
3103    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' S(Q)->F(Q)->G(R) controls: '),0,WACV)
3104    mainSizer.Add((5,5),0)
3105    sqBox = wx.BoxSizer(wx.HORIZONTAL)
3106    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Detector type: '),0,WACV)
3107    choice = ['Image plate','Point detector']
3108    detType = wx.ComboBox(G2frame.dataDisplay,value=data['DetType'],choices=choice,
3109            style=wx.CB_READONLY|wx.CB_DROPDOWN)
3110    detType.Bind(wx.EVT_COMBOBOX, OnDetType)
3111    sqBox.Add(detType,0)
3112    if data['DetType'] == 'Image plate':
3113        sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' IP transmission coeff.: '),0,WACV)
3114        obliqCoeff = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['ObliqCoeff']))
3115        obliqCoeff.Bind(wx.EVT_TEXT_ENTER,OnObliqCoeff)       
3116        obliqCoeff.Bind(wx.EVT_KILL_FOCUS,OnObliqCoeff)
3117        sqBox.Add(obliqCoeff,0)
3118    mainSizer.Add(sqBox,0)
3119       
3120    sqBox = wx.BoxSizer(wx.HORIZONTAL)
3121    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Ruland width: '),0,WACV)   
3122    rulandSldr = wx.Slider(parent=G2frame.dataDisplay,style=wx.SL_HORIZONTAL,
3123        value=int(1000*data['Ruland']))
3124    sqBox.Add(rulandSldr,1,wx.EXPAND)
3125    rulandSldr.Bind(wx.EVT_SLIDER, OnRulSlider)
3126    rulandWdt = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Ruland']))
3127    rulandWdt.Bind(wx.EVT_TEXT_ENTER,OnRulandWdt)       
3128    rulandWdt.Bind(wx.EVT_KILL_FOCUS,OnRulandWdt)
3129    sqBox.Add(rulandWdt,0,WACV)   
3130    mainSizer.Add(sqBox,0,wx.ALIGN_LEFT|wx.EXPAND)
3131   
3132    sqBox = wx.BoxSizer(wx.HORIZONTAL)
3133    lorch = wx.CheckBox(parent=G2frame.dataDisplay,label='Lorch damping?')
3134    lorch.SetValue(data['Lorch'])
3135    lorch.Bind(wx.EVT_CHECKBOX, OnLorch)
3136    sqBox.Add(lorch,0,WACV)
3137    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Scaling q-range: '),0,WACV)
3138    SQmin = wx.TextCtrl(G2frame.dataDisplay,value='%.1f'%(data['QScaleLim'][0]))
3139    SQmin.Bind(wx.EVT_TEXT_ENTER,OnSQmin)       
3140    SQmin.Bind(wx.EVT_KILL_FOCUS,OnSQmin)   
3141    sqBox.Add(SQmin,0)
3142    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' to '),0,WACV)
3143    SQmax = wx.TextCtrl(G2frame.dataDisplay,value='%.1f'%(data['QScaleLim'][1]))
3144    SQmax.Bind(wx.EVT_TEXT_ENTER,OnSQmax)       
3145    SQmax.Bind(wx.EVT_KILL_FOCUS,OnSQmax)
3146    sqBox.Add(SQmax,0)
3147    resetQ = wx.CheckBox(parent=G2frame.dataDisplay,label='Reset?')
3148    sqBox.Add(resetQ,0)
3149    resetQ.Bind(wx.EVT_CHECKBOX, OnResetQ)
3150   
3151    mainSizer.Add(sqBox,0)
3152
3153    mainSizer.Layout()   
3154    G2frame.dataDisplay.SetSizer(mainSizer)
3155    Size = mainSizer.Fit(G2frame.dataFrame)
3156    G2frame.dataDisplay.SetSize(Size)
3157    G2frame.dataFrame.setSizePosLeft(Size)
3158   
Note: See TracBrowser for help on using the repository browser.