source: trunk/GSASIIpwdGUI.py @ 1008

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

make Auto peak search eliminate duplicates

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