source: trunk/GSASIIpwdGUI.py @ 1205

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

Add models to SASD data tree
Add error bar plotting to SASD data
Add I*Q4 option to log SASD data
got rid of the if, else blocks for all key driven toggles in G2plot

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