source: trunk/GSASIIpwdGUI.py @ 1199

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

1st import of small angle data, create SASD data from image.
Work on proper plotting of SASD data
work on image GUI stuff for small angle data

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