source: trunk/GSASIIpwdGUI.py @ 795

Last change on this file since 795 was 795, checked in by vondreele, 10 years ago

implement TOF input, peak search & fitting
auto peak search
convert instrument parms to dictionary
add charge flip on max rho

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