source: trunk/GSASIIpwdGUI.py @ 945

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

some mods for POWGEN data for single peak fitting
unify profile parm calcs into G2mth

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