source: trunk/GSASIIpwdGUI.py @ 923

Last change on this file since 923 was 923, checked in by toby, 10 years ago

more doc updates

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