source: trunk/GSASIIpwdGUI.py @ 938

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

Add instrument name support; add export menu & CIF testing

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