source: trunk/GSASIIpwdGUI.py @ 1263

Last change on this file since 1263 was 1263, checked in by vondreele, 9 years ago

comment out the LEAVE_WINDOW in ValidatedTextCtrl? - leads to weird behavior when just moving mouse around.
Add SASD Model Add facility for Particle Modeling
Add Neutron CW SASD import & change default file extensions for SASD.
Begin Unified & Model fit routines - they don't do anything yet

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