source: trunk/GSASIIpwdGUI.py @ 997

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

implement export of hkl files extracted from powder data

  • 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-07-17 21:11:37 +0000 (Wed, 17 Jul 2013) $
5# $Author: vondreele $
6# $Revision: 997 $
7# $URL: trunk/GSASIIpwdGUI.py $
8# $Id: GSASIIpwdGUI.py 997 2013-07-17 21:11:37Z vondreele $
9########### SVN repository information ###################
10'''
11*GSASIIpwdGUI: Powder Pattern GUI routines*
12-------------------------------------------
13
14Used to define GUI controls for the routines that interact
15with the powder histogram (PWDR) data tree items.
16
17'''
18import sys
19import os.path
20import wx
21import wx.grid as wg
22import numpy as np
23import numpy.ma as ma
24import math
25import time
26import copy
27import random as ran
28import cPickle
29import GSASIIpath
30GSASIIpath.SetVersionNumber("$Revision: 997 $")
31import GSASIImath as G2mth
32import GSASIIpwd as G2pwd
33import GSASIIIO as G2IO
34import GSASIIlattice as G2lat
35import GSASIIspc as G2spc
36import GSASIIindex as G2indx
37import GSASIIplot as G2plt
38import GSASIIgrid as G2gd
39import GSASIIElemGUI as G2elemGUI
40import GSASIIElem as G2elem
41VERY_LIGHT_GREY = wx.Colour(235,235,235)
42# trig functions in degrees
43sind = lambda x: math.sin(x*math.pi/180.)
44tand = lambda x: math.tan(x*math.pi/180.)
45cosd = lambda x: math.cos(x*math.pi/180.)
46asind = lambda x: 180.*math.asin(x)/math.pi
47   
48def IsHistogramInAnyPhase(G2frame,histoName):
49    'Needs a doc string'
50    phases = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases')
51    if phases:
52        item, cookie = G2frame.PatternTree.GetFirstChild(phases)
53        while item:
54            data = G2frame.PatternTree.GetItemPyData(item)
55            histoList = data['Histograms'].keys()
56            if histoName in histoList:
57                return True
58            item, cookie = G2frame.PatternTree.GetNextChild(phases, cookie)
59        return False
60    else:
61        return False
62
63def SetDefaultSample():
64    'Needs a doc string'
65    return {'ranId':ran.randint(0,sys.maxint),
66        'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],
67        'DisplaceX':[0.0,False],'DisplaceY':[0.0,False],'Diffuse':[],
68        'Temperature':300.,'Pressure':1.0,'Humidity':0.0,
69        'Voltage':0.0,'Force':0.0,'Gonio. radius':200.0,
70        'Omega':0.0,'Chi':0.0,'Phi':0.0}
71                         
72################################################################################
73#####  Powder Peaks
74################################################################################           
75       
76def UpdatePeakGrid(G2frame, data):
77    '''respond to selection of PWDR powder peaks data tree item.
78    '''
79    if G2frame.dataDisplay:
80        G2frame.dataFrame.Clear()
81       
82    def OnAutoSearch(event):
83        PatternId = G2frame.PatternId
84        PickId = G2frame.PickId
85        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
86        inst,inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
87        profile = G2frame.PatternTree.GetItemPyData(PatternId)[1]
88        x0 = profile[0]
89        iBeg = np.searchsorted(x0,limits[0])
90        iFin = np.searchsorted(x0,limits[1])
91        x = x0[iBeg:iFin]
92        y0 = profile[1][iBeg:iFin]
93        y1 = copy.copy(y0)
94        ysig = np.std(y1)
95        offset = [-1,1]
96        ymask = ma.array(y0,mask=(y0<ysig))
97        for off in offset:
98            ymask = ma.array(ymask,mask=(ymask-np.roll(y0,off)<=0.))
99        indx = ymask.nonzero()
100        mags = ymask[indx]
101        poss = x[indx]
102        for pos,mag in zip(poss,mags):
103            data.append(G2mth.setPeakparms(inst,inst2,pos,mag))
104        UpdatePeakGrid(G2frame,data)
105        G2plt.PlotPatterns(G2frame)       
106   
107    def OnUnDo(event):
108        DoUnDo()
109        G2frame.dataFrame.UnDo.Enable(False)
110       
111    def DoUnDo():
112        print 'Undo last refinement'
113        file = open(G2frame.undofile,'rb')
114        PatternId = G2frame.PatternId
115        for item in ['Background','Instrument Parameters','Peak List']:
116            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item),cPickle.load(file))
117            if G2frame.dataDisplay.GetName() == item:
118                if item == 'Background':
119                    UpdateBackground(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
120                elif item == 'Instrument Parameters':
121                    UpdateInstrumentGrid(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
122                elif item == 'Peak List':
123                    UpdatePeakGrid(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
124            print item,' recovered'
125        file.close()
126       
127    def SaveState():
128        G2frame.undofile = os.path.join(G2frame.dirname,'GSASII.save')
129        file = open(G2frame.undofile,'wb')
130        PatternId = G2frame.PatternId
131        for item in ['Background','Instrument Parameters','Peak List']:
132            cPickle.dump(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,item)),file,1)
133        file.close()
134        G2frame.dataFrame.UnDo.Enable(True)
135       
136    def OnLSQPeakFit(event):
137        if not G2frame.GSASprojectfile:            #force a save of the gpx file so SaveState can wirte in the same directory
138            G2frame.OnFileSaveas(event)
139        OnPeakFit('LSQ')
140       
141    def OnOneCycle(event):
142        OnPeakFit('LSQ',oneCycle=True)
143       
144    def OnClearPeaks(event):
145        dlg = wx.MessageDialog(G2frame,'Delete all peaks?','Clear peak list',wx.OK|wx.CANCEL)
146        try:
147            if dlg.ShowModal() == wx.ID_OK:
148                peaks = []
149        finally:
150            dlg.Destroy()
151        UpdatePeakGrid(G2frame,peaks)
152        G2plt.PlotPatterns(G2frame)
153       
154    def OnPeakFit(FitPgm,oneCycle=False):
155        SaveState()
156        controls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Controls'))
157        if not controls:
158            controls = {'deriv type':'analytic','min dM/M':0.0001,}     #fill in defaults if needed
159        print 'Peak Fitting with '+controls['deriv type']+' derivatives:'
160        PatternId = G2frame.PatternId
161        PickId = G2frame.PickId
162        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'))
163        if not peaks:
164            G2frame.ErrorDialog('No peaks!','Nothing to fit!')
165            return
166        background = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Background'))
167        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
168        inst,inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
169        data = G2frame.PatternTree.GetItemPyData(PatternId)[1]
170        wx.BeginBusyCursor()
171        dlg = wx.ProgressDialog('Residual','Peak fit Rwp = ',101.0, 
172            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT)
173        screenSize = wx.ClientDisplayRect()
174        Size = dlg.GetSize()
175        dlg.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
176        try:
177            G2pwd.DoPeakFit(FitPgm,peaks,background,limits,inst,inst2,data,oneCycle,controls,dlg)
178        finally:
179            wx.EndBusyCursor()   
180        UpdatePeakGrid(G2frame,peaks)
181        G2plt.PlotPatterns(G2frame)
182        print 'finished'
183        return
184       
185    def OnResetSigGam(event):
186        PatternId = G2frame.PatternId
187        PickId = G2frame.PickId
188        Inst,Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
189        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'))
190        if not peaks:
191            G2frame.ErrorDialog('No peaks!','Nothing to do!')
192            return
193        newpeaks = []
194        for peak in peaks:
195            newpeaks.append(G2mth.setPeakparms(Inst,Inst2,peak[0],peak[2]))
196        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'),newpeaks)
197        UpdatePeakGrid(G2frame,newpeaks)
198               
199    def RefreshPeakGrid(event):
200        r,c =  event.GetRow(),event.GetCol()
201       
202        event.StopPropagation()
203        data = G2frame.PeakTable.GetData()
204        T = []
205        for peak in data:T.append(peak[0])
206        D = dict(zip(T,data))
207        T.sort()
208        X = []
209        for key in T: X.append(D[key])
210        data = X       
211       
212    def setBackgroundColors():
213       for r in range(G2frame.dataDisplay.GetNumberRows()):
214           for c in range(G2frame.dataDisplay.GetNumberCols()):
215               if G2frame.dataDisplay.GetColLabelValue(c) in ['position','intensity','alpha','beta','sigma','gamma']:
216                   if float(G2frame.dataDisplay.GetCellValue(r,c)) < 0.:
217                       G2frame.dataDisplay.SetCellBackgroundColour(r,c,wx.RED)
218                   else:
219                       G2frame.dataDisplay.SetCellBackgroundColour(r,c,wx.WHITE)
220                                                 
221    def KeyEditPeakGrid(event):
222        rowList = G2frame.dataDisplay.GetSelectedRows()
223        colList = G2frame.dataDisplay.GetSelectedCols()
224        selectList = G2frame.dataDisplay.GetSelectedCells()
225        data = G2frame.PatternTree.GetItemPyData(G2frame.PickId)
226        if event.GetKeyCode() == wx.WXK_RETURN:
227            event.Skip(True)
228        elif event.GetKeyCode() == wx.WXK_CONTROL:
229            event.Skip(True)
230        elif event.GetKeyCode() == wx.WXK_SHIFT:
231            event.Skip(True)
232        elif rowList:
233            G2frame.dataDisplay.ClearSelection()
234            if event.GetKeyCode() == wx.WXK_DELETE:
235                G2frame.dataDisplay.ClearGrid()
236                rowList.sort()
237                rowList.reverse()
238                nDel = 0
239                for row in rowList:
240                    G2frame.PeakTable.DeleteRow(row)
241                    nDel += 1
242                if nDel:
243                    msg = wg.GridTableMessage(G2frame.PeakTable, 
244                        wg.GRIDTABLE_NOTIFY_ROWS_DELETED,0,nDel)
245                    G2frame.dataDisplay.ProcessTableMessage(msg)
246                data = G2frame.PeakTable.GetData()
247                G2frame.PatternTree.SetItemPyData(G2frame.PickId,data[:-nDel])
248                G2frame.dataDisplay.ForceRefresh()
249                setBackgroundColors()
250                if not len(G2frame.PatternTree.GetItemPyData(G2frame.PickId)): 
251                    G2frame.dataFrame.PeakFit.Enable(False)
252                       
253        elif colList:
254            G2frame.dataDisplay.ClearSelection()
255            key = event.GetKeyCode()
256            for col in colList:
257                if G2frame.PeakTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
258                    if key == 89: #'Y'
259                        for row in range(G2frame.PeakTable.GetNumberRows()): data[row][col]=True
260                    elif key == 78:  #'N'
261                        for row in range(G2frame.PeakTable.GetNumberRows()): data[row][col]=False
262        elif selectList:
263            G2frame.dataDisplay.ClearSelection()
264            key = event.GetKeyCode()
265            for row,col in selectList:
266                if G2frame.PeakTable.GetTypeName(row,col) == wg.GRID_VALUE_BOOL:
267                    if key == 89: #'Y'
268                        data[row][col]=True
269                    elif key == 78:  #'N'
270                        data[row][col]=False
271        G2plt.PlotPatterns(G2frame)
272           
273    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.PeakMenu)
274    if not G2frame.dataFrame.GetStatusBar():
275        Status = G2frame.dataFrame.CreateStatusBar()
276    Status.SetStatusText('Global refine: select refine column & press Y or N')
277    G2frame.Bind(wx.EVT_MENU, OnAutoSearch, id=G2gd.wxID_AUTOSEARCH)
278    G2frame.Bind(wx.EVT_MENU, OnUnDo, id=G2gd.wxID_UNDO)
279    G2frame.Bind(wx.EVT_MENU, OnLSQPeakFit, id=G2gd.wxID_LSQPEAKFIT)
280    G2frame.Bind(wx.EVT_MENU, OnOneCycle, id=G2gd.wxID_LSQONECYCLE)
281    G2frame.Bind(wx.EVT_MENU, OnClearPeaks, id=G2gd.wxID_CLEARPEAKS)
282    G2frame.Bind(wx.EVT_MENU, OnResetSigGam, id=G2gd.wxID_RESETSIGGAM)
283    G2frame.dataFrame.PeakFit.Enable(False)
284    if data:
285        G2frame.dataFrame.PeakFit.Enable(True)
286        G2frame.dataFrame.PFOneCycle.Enable(True)
287    G2frame.PickTable = []
288    rowLabels = []
289    PatternId = G2frame.PatternId
290    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))[0]
291    for i in range(len(data)): rowLabels.append(str(i+1))
292    if 'C' in Inst['Type'][0]:
293        colLabels = ['position','refine','intensity','refine','sigma','refine','gamma','refine']
294        Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
295            wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
296            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
297            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
298    else:
299        colLabels = ['position','refine','intensity','refine','alpha','refine',
300            'beta','refine','sigma','refine','gamma','refine']
301        Types = [wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
302            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
303            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
304            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
305            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
306            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
307    T = []
308    for peak in data:
309        T.append(peak[0])
310    D = dict(zip(T,data))
311    T.sort()
312    X = []
313    for key in T: X.append(D[key])
314    data = X
315    G2frame.PatternTree.SetItemPyData(G2frame.PickId,data)
316    G2frame.PeakTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
317    G2frame.dataFrame.SetLabel('Peak List')
318    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)
319    G2frame.dataDisplay.SetTable(G2frame.PeakTable, True)
320    setBackgroundColors()                         
321    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshPeakGrid)
322    G2frame.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
323    G2frame.dataDisplay.SetMargins(0,0)
324    G2frame.dataDisplay.AutoSizeColumns(False)
325    G2frame.dataFrame.setSizePosLeft([535,350])
326       
327################################################################################
328#####  Background
329################################################################################           
330       
331def UpdateBackground(G2frame,data):
332    '''respond to selection of PWDR background data tree item.
333    '''
334    if len(data) < 2:       #add Debye diffuse & peaks scattering here
335        data.append({'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]})
336    if 'nPeaks' not in data[1]:
337        data[1].update({'nPeaks':0,'peaksList':[]})
338    ValObj = {}
339   
340    def OnBackFlagCopy(event):
341        flag = data[0][1]
342        backDict = data[-1]
343        if backDict['nDebye']:
344            DBflags = []
345            for term in backDict['debyeTerms']:
346                DBflags.append(term[1::2])
347        if backDict['nPeaks']:
348            PKflags = []
349            for term in backDict['peaksList']:
350                PKflags.append(term[1::2])           
351        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
352        copyList = []
353        dlg = wx.MultiChoiceDialog(G2frame, 
354            'Copy refinement flags to which histograms?', 'Copy flags', 
355            histList, wx.CHOICEDLG_STYLE)
356        try:
357            if dlg.ShowModal() == wx.ID_OK:
358                result = dlg.GetSelections()
359                for i in result: 
360                    copyList.append(histList[i])
361                if 'All' in copyList: 
362                    copyList = histList[1:]
363            for item in copyList:
364                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
365                backData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Background'))
366                backData[0][1] = copy.copy(flag)
367                bkDict = backData[-1]
368                if bkDict['nDebye'] == backDict['nDebye']:
369                    for i,term in enumerate(bkDict['debyeTerms']):
370                        term[1::2] = copy.copy(DBflags[i])
371                if bkDict['nPeaks'] == backDict['nPeaks']:
372                    for i,term in enumerate(bkDict['peaksList']):
373                        term[1::2] = copy.copy(PKflags[i])                   
374        finally:
375            dlg.Destroy()
376           
377    def OnBackCopy(event):
378        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
379        copyList = []
380        dlg = wx.MultiChoiceDialog(G2frame, 
381            'Copy parameters to which histograms?', 'Copy parameters', 
382            histList, wx.CHOICEDLG_STYLE)
383        try:
384            if dlg.ShowModal() == wx.ID_OK:
385                result = dlg.GetSelections()
386                for i in result: 
387                    copyList.append(histList[i])
388                if 'All' in copyList: 
389                    copyList = histList[1:]
390            for item in copyList:
391                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
392                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Background'),
393                    copy.copy(data))
394        finally:
395            dlg.Destroy()
396       
397    def BackSizer():
398       
399        def OnNewType(event):
400            data[0][0] = bakType.GetValue()
401           
402        def OnBakRef(event):
403            data[0][1] = bakRef.GetValue()
404           
405        def OnBakTerms(event):
406            data[0][2] = int(bakTerms.GetValue())
407            M = len(data[0])
408            N = data[0][2]+3
409            item = data[0]
410            if N > M:       #add terms
411                for i in range(M,N): 
412                    item.append(0.0)
413            elif N < M:     #delete terms
414                for i in range(N,M):
415                    del(item[-1])
416            G2frame.PatternTree.SetItemPyData(BackId,data)
417            wx.CallAfter(UpdateBackground,G2frame,data)
418           
419        def OnBakVal(event):
420            Obj = event.GetEventObject()
421            item = ValObj[Obj.GetId()][0]
422            try:
423                value = float(Obj.GetValue())
424            except ValueError:
425                value = data[0][item]
426            data[0][item] = value
427            Obj.SetValue('%10.4f'%(value))
428       
429        backSizer = wx.BoxSizer(wx.VERTICAL)
430        topSizer = wx.BoxSizer(wx.HORIZONTAL)
431        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background function: '),0,wx.ALIGN_CENTER_VERTICAL)
432        bakType = wx.ComboBox(G2frame.dataDisplay,value=data[0][0],
433                choices=Choices,style=wx.CB_READONLY|wx.CB_DROPDOWN)
434        bakType.Bind(wx.EVT_COMBOBOX, OnNewType)
435        topSizer.Add(bakType)
436        topSizer.Add((5,0),0)
437        bakRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
438        bakRef.SetValue(bool(data[0][1]))
439        bakRef.Bind(wx.EVT_CHECKBOX, OnBakRef)
440        topSizer.Add(bakRef,0,wx.ALIGN_CENTER_VERTICAL)
441        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. coeff.: '),0,wx.ALIGN_CENTER_VERTICAL)
442        bakTerms = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[0][2]),choices=[str(i+1) for i in range(36)],
443            style=wx.CB_READONLY|wx.CB_DROPDOWN)
444        bakTerms.Bind(wx.EVT_COMBOBOX,OnBakTerms)
445        topSizer.Add(bakTerms,0,wx.ALIGN_CENTER_VERTICAL)
446        topSizer.Add((5,0),0)
447        backSizer.Add(topSizer)
448        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background coefficients:'),0,wx.ALIGN_CENTER_VERTICAL)
449        bakSizer = wx.FlexGridSizer(1,5,5,5)
450        for i,value in enumerate(data[0][3:]):
451            bakVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.4f'%(value),style=wx.TE_PROCESS_ENTER)
452            bakSizer.Add(bakVal,0,wx.ALIGN_CENTER_VERTICAL)
453            ValObj[bakVal.GetId()] = [i+3]
454            bakVal.Bind(wx.EVT_TEXT_ENTER,OnBakVal)
455            bakVal.Bind(wx.EVT_KILL_FOCUS,OnBakVal)
456        backSizer.Add(bakSizer)
457        return backSizer
458       
459    def DebyeSizer():
460       
461        def OnDebTerms(event):
462            data[1]['nDebye'] = int(debTerms.GetValue())
463            M = len(data[1]['debyeTerms'])
464            N = data[1]['nDebye']
465            if N > M:       #add terms
466                for i in range(M,N): 
467                    data[1]['debyeTerms'].append([1.0,False,1.0,False,0.010,False])
468            elif N < M:     #delete terms
469                for i in range(N,M):
470                    del(data[1]['debyeTerms'][-1])
471            wx.CallAfter(UpdateBackground,G2frame,data)
472           
473        def KeyEditPeakGrid(event):
474            colList = debyeGrid.GetSelectedCols()
475            if event.GetKeyCode() == wx.WXK_RETURN:
476                event.Skip(True)
477            elif event.GetKeyCode() == wx.WXK_CONTROL:
478                event.Skip(True)
479            elif event.GetKeyCode() == wx.WXK_SHIFT:
480                event.Skip(True)
481            elif colList:
482                debyeGrid.ClearSelection()
483                key = event.GetKeyCode()
484                for col in colList:
485                    if debyeTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
486                        if key == 89: #'Y'
487                            for row in range(debyeGrid.GetNumberRows()): data[1]['debyeTerms'][row][col]=True
488                        elif key == 78:  #'N'
489                            for row in range(debyeGrid.GetNumberRows()): data[1]['debyeTerms'][row][col]=False
490
491       
492        debSizer = wx.BoxSizer(wx.VERTICAL)
493        topSizer = wx.BoxSizer(wx.HORIZONTAL)
494        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Debye scattering: '),0,wx.ALIGN_CENTER_VERTICAL)
495        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. coeff.: '),0,wx.ALIGN_CENTER_VERTICAL)
496        debTerms = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[1]['nDebye']),choices=[str(i) for i in range(12)],
497            style=wx.CB_READONLY|wx.CB_DROPDOWN)
498        debTerms.Bind(wx.EVT_COMBOBOX,OnDebTerms)
499        topSizer.Add(debTerms,0,wx.ALIGN_CENTER_VERTICAL)
500        topSizer.Add((5,0),0)
501        debSizer.Add(topSizer)
502        if data[1]['nDebye']:
503            debSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Debye diffuse terms:'),0,wx.ALIGN_CENTER_VERTICAL)       
504            rowLabels = []
505            for i in range(len(data[1]['debyeTerms'])): rowLabels.append(str(i))
506            colLabels = ['A','refine','R','refine','U','refine']
507            Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL,
508            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
509            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
510            debyeTable = G2gd.Table(data[1]['debyeTerms'],rowLabels=rowLabels,colLabels=colLabels,types=Types)
511            debyeGrid = G2gd.GSGrid(parent=G2frame.dataDisplay)
512            debyeGrid.SetTable(debyeTable, True)
513            debyeGrid.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
514            debyeGrid.AutoSizeColumns(False)
515            debSizer.Add(debyeGrid)       
516        return debSizer
517     
518    def PeaksSizer():
519
520        def OnPeaks(event):
521            data[1]['nPeaks'] = int(peaks.GetValue())
522            M = len(data[1]['peaksList'])
523            N = data[1]['nPeaks']
524            if N > M:       #add terms
525                for i in range(M,N): 
526                    data[1]['peaksList'].append([1.0,False,1.0,False,0.10,False,0.10,False])
527            elif N < M:     #delete terms
528                for i in range(N,M):
529                    del(data[1]['peaksList'][-1])
530            wx.CallAfter(UpdateBackground,G2frame,data)
531           
532        def KeyEditPeakGrid(event):
533            colList = peaksGrid.GetSelectedCols()
534            if event.GetKeyCode() == wx.WXK_RETURN:
535                event.Skip(True)
536            elif event.GetKeyCode() == wx.WXK_CONTROL:
537                event.Skip(True)
538            elif event.GetKeyCode() == wx.WXK_SHIFT:
539                event.Skip(True)
540            elif colList:
541                peaksGrid.ClearSelection()
542                key = event.GetKeyCode()
543                for col in colList:
544                    if peaksTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
545                        if key == 89: #'Y'
546                            for row in range(peaksGrid.GetNumberRows()): data[1]['peaksList'][row][col]=True
547                        elif key == 78:  #'N'
548                            for row in range(peaksGrid.GetNumberRows()): data[1]['peaksList'][row][col]=False
549
550        peaksSizer = wx.BoxSizer(wx.VERTICAL)
551        topSizer = wx.BoxSizer(wx.HORIZONTAL)
552        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Peaks in background: '),0,wx.ALIGN_CENTER_VERTICAL)
553        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. peaks: '),0,wx.ALIGN_CENTER_VERTICAL)
554        peaks = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[1]['nPeaks']),choices=[str(i) for i in range(12)],
555            style=wx.CB_READONLY|wx.CB_DROPDOWN)
556        peaks.Bind(wx.EVT_COMBOBOX,OnPeaks)
557        topSizer.Add(peaks,0,wx.ALIGN_CENTER_VERTICAL)
558        topSizer.Add((5,0),0)
559        peaksSizer.Add(topSizer)
560        if data[1]['nPeaks']:
561            peaksSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Peak list:'),0,wx.ALIGN_CENTER_VERTICAL)       
562            rowLabels = []
563            for i in range(len(data[1]['peaksList'])): rowLabels.append(str(i))
564            colLabels = ['pos','refine','int','refine','sig','refine','gam','refine']
565            Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL,
566            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
567            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
568            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
569            peaksTable = G2gd.Table(data[1]['peaksList'],rowLabels=rowLabels,colLabels=colLabels,types=Types)
570            peaksGrid = G2gd.GSGrid(parent=G2frame.dataDisplay)
571            peaksGrid.SetTable(peaksTable, True)
572            peaksGrid.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
573            peaksGrid.AutoSizeColumns(False)
574            peaksSizer.Add(peaksGrid)       
575        return peaksSizer
576               
577    if G2frame.dataDisplay:
578#        G2frame.dataFrame.Clear()
579        G2frame.dataFrame.DestroyChildren()
580    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
581    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.BackMenu)
582    G2frame.dataFrame.SetLabel('Background')
583    if not G2frame.dataFrame.GetStatusBar():
584        Status = G2frame.dataFrame.CreateStatusBar()
585    G2frame.Bind(wx.EVT_MENU,OnBackCopy,id=G2gd.wxID_BACKCOPY)
586    G2frame.Bind(wx.EVT_MENU,OnBackFlagCopy,id=G2gd.wxID_BACKFLAGCOPY)
587    BackId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Background')
588    Choices = ['chebyschev','cosine','lin interpolate','inv interpolate','log interpolate']
589    mainSizer = wx.BoxSizer(wx.VERTICAL)
590    mainSizer.Add(BackSizer())
591    mainSizer.Add((0,5),0)
592    mainSizer.Add(DebyeSizer())
593    mainSizer.Add((0,5),0)
594    mainSizer.Add(PeaksSizer())
595    mainSizer.Layout()   
596    G2frame.dataDisplay.SetSizer(mainSizer)
597    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
598       
599################################################################################
600#####  Limits
601################################################################################           
602       
603def UpdateLimitsGrid(G2frame, data):
604    '''respond to selection of PWDR Limits data tree item.
605    '''
606    #Add excluded regions here
607    if G2frame.dataDisplay:
608        G2frame.dataFrame.Clear()
609       
610    def RefreshLimitsGrid(event):
611        event.StopPropagation()
612        data = G2frame.LimitsTable.GetData()
613        old = data[0]
614        new = data[1]
615        new[0] = max(old[0],new[0])
616        new[1] = max(new[0],min(old[1],new[1]))
617        data = [old,new]
618        G2plt.PlotPatterns(G2frame)
619       
620    def OnLimitCopy(event):
621        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
622        copyList = []
623        dlg = wx.MultiChoiceDialog(G2frame, 
624            'Copy limits to which histograms?', 'Copy limits', 
625            histList, wx.CHOICEDLG_STYLE)
626        try:
627            if dlg.ShowModal() == wx.ID_OK:
628                result = dlg.GetSelections()
629                for i in result: 
630                    copyList.append(histList[i])
631                if 'All' in copyList: 
632                    copyList = histList[1:]
633            for item in copyList:
634                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
635                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Limits'),
636                    copy.copy(data))
637        finally:
638            dlg.Destroy()
639       
640    G2frame.LimitsTable = []
641    colLabels = ['Tmin','Tmax']
642    rowLabels = ['original','changed']
643    Types = 2*[wg.GRID_VALUE_FLOAT+':10,3',]
644    G2frame.LimitsTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
645    G2frame.dataFrame.SetLabel('Limits')
646    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.LimitMenu)
647    if not G2frame.dataFrame.GetStatusBar():
648        Status = G2frame.dataFrame.CreateStatusBar()
649    G2frame.Bind(wx.EVT_MENU,OnLimitCopy,id=G2gd.wxID_LIMITCOPY)
650    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)
651    G2frame.dataDisplay.SetTable(G2frame.LimitsTable, True)
652    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshLimitsGrid)               
653    G2frame.dataDisplay.SetMargins(0,0)
654    G2frame.dataDisplay.AutoSizeColumns(False)
655    G2frame.dataFrame.setSizePosLeft([230,160])
656   
657################################################################################
658#####  Instrument parameters
659################################################################################           
660       
661def UpdateInstrumentGrid(G2frame,data):
662    '''respond to selection of PWDR Instrument Parameters
663    data tree item.
664    '''
665    def keycheck(keys):
666        good = []
667        for key in keys:
668            if key in ['Type','U','V','W','X','Y','SH/L','I(L2)/I(L1)','alpha',
669                'beta-0','beta-1','beta-q','sig-0','sig-1','sig-q','Polariz.',
670                'Lam','Azimuth','2-theta','difC','difA','Zero','Lam1','Lam2']:
671                good.append(key)
672        return good
673       
674    keys = keycheck(data.keys())
675    if 'P' in data['Type'][0]:          #powder data
676        insVal = dict(zip(keys,[data[key][1] for key in keys]))
677        insDef = dict(zip(keys,[data[key][0] for key in keys]))
678        insRef = dict(zip(keys,[data[key][2] for key in keys]))
679        if 'NC' in data['Type'][0]:
680            del(insDef['Polariz.'])
681            del(insVal['Polariz.'])
682            del(insRef['Polariz.'])
683    else:                               #single crystal data
684        insVal = dict(zip(keys,[data[key][1] for key in keys]))
685        insDef = dict(zip(keys,[data[key][0] for key in keys]))
686        insRef = {}
687    ValObj = {}
688    RefObj = {}
689    waves = {'CuKa':[1.54051,1.54433],'TiKa':[2.74841,2.75207],'CrKa':[2.28962,2.29351],
690        'FeKa':[1.93597,1.93991],'CoKa':[1.78892,1.79278],'MoKa':[0.70926,0.713543],
691        'AgKa':[0.559363,0.563775]}
692    Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,
693            G2frame.PatternId,'Instrument Parameters'))[1]
694       
695    def inst2data(inst,ref,data):
696        for item in data:
697            try:
698                data[item] = [data[item][0],inst[item],ref[item]]
699            except KeyError:
700                pass        #skip 'Polariz.' for N-data
701        return data
702       
703    def updateData(inst,ref):
704        return inst2data(inst,ref,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,
705            G2frame.PatternId,'Instrument Parameters'))[0])       
706   
707    def RefreshInstrumentGrid(event,doAnyway=False):
708        if doAnyway or event.GetRow() == 1:
709            peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'))
710            newpeaks = []
711            for peak in peaks:
712                newpeaks.append(G2mth.setPeakparms(data,Inst2,peak[0],peak[2]))
713            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'),newpeaks)
714                   
715    def OnLoad(event):
716        '''Loads instrument parameters from a G2 .instprm file
717        in response to the Instrument Parameters-Operations/Load Profile menu
718       
719        Note that similar code is found in ReadPowderInstprm (GSASII.py)
720        '''
721        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II instrument parameters file', '.', '', 
722            'instrument parameter files (*.instprm)|*.instprm',wx.OPEN|wx.CHANGE_DIR)
723        try:
724            if dlg.ShowModal() == wx.ID_OK:
725                filename = dlg.GetPath()
726                File = open(filename,'r')
727                S = File.readline()
728                newItems = []
729                newVals = []
730                while S:
731                    if S[0] == '#':
732                        S = File.readline()
733                        continue
734                    [item,val] = S[:-1].split(':')
735                    newItems.append(item)
736                    try:
737                        newVals.append(float(val))
738                    except ValueError:
739                        newVals.append(val)                       
740                    S = File.readline()               
741                File.close()
742                Inst,Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Instrument Parameters'))
743                inst = G2IO.makeInstDict(newItems,newVals,len(newVals)*[False,])
744                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Instrument Parameters'),[inst,Inst2])
745                RefreshInstrumentGrid(event,doAnyway=True)          #to get peaks updated
746                UpdateInstrumentGrid(G2frame,data)
747                G2plt.PlotPeakWidths(G2frame)
748        finally:
749            dlg.Destroy()
750       
751    def OnSave(event):
752        '''Respond to the Instrument Parameters Operations/Save Profile menu
753        item: writes current parameters to a .instprm file
754        '''
755        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II instrument parameters file', '.', '', 
756            'instrument parameter files (*.instprm)|*.instprm',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
757        try:
758            if dlg.ShowModal() == wx.ID_OK:
759                filename = dlg.GetPath()
760                # make sure extension is .instprm
761                filename = os.path.splitext(filename)[0]+'.instprm'
762                File = open(filename,'w')
763                File.write("#GSAS-II instrument parameter file; do not add/delete or change order of items!\n")
764                for item in data:
765                    File.write(item+':'+str(data[item][1])+'\n')
766                File.close()
767        finally:
768            dlg.Destroy()
769                                               
770    def OnReset(event):
771        insVal.update(insDef)
772        data = updateData(insVal,insRef)
773        RefreshInstrumentGrid(event,doAnyway=True)          #to get peaks updated
774        UpdateInstrumentGrid(G2frame,data)
775        G2plt.PlotPeakWidths(G2frame)
776       
777    def OnInstFlagCopy(event):
778        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
779        keys = data.keys()
780        flags = dict(zip(keys,[data[key][2] for key in keys]))
781        instType = data['Type'][0]
782        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
783        copyList = []
784        dlg = wx.MultiChoiceDialog(G2frame, 
785            'Copy refinement flags from\n'+histName, 'Copy refinement flags', 
786            histList, wx.CHOICEDLG_STYLE)
787        try:
788            if dlg.ShowModal() == wx.ID_OK:
789                result = dlg.GetSelections()
790                for i in result: 
791                    copyList.append(histList[i])
792                if 'All' in copyList: 
793                    copyList = histList[1:]
794            for item in copyList:
795                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
796                instData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'))[0]
797                if len(data) == len(instData) and instType == instData['Type'][0]:   #don't mix data types or lam & lam1/lam2 parms!
798                    for item in instData:
799                        instData[item][2] = copy.copy(flags[item])
800                else:
801                    print item+' not copied - instrument parameters not commensurate'
802        finally:
803            dlg.Destroy()
804       
805    def OnInstCopy(event):
806        #need fix for dictionary
807        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
808        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
809        copyList = []
810        instType = data['Type'][0]
811        dlg = wx.MultiChoiceDialog(G2frame, 
812            'Copy parameters from\n'+histName, 'Copy parameters', 
813            histList, wx.CHOICEDLG_STYLE)
814        try:
815            if dlg.ShowModal() == wx.ID_OK:
816                result = dlg.GetSelections()
817                for i in result: 
818                    copyList.append(histList[i])
819                if 'All' in copyList: 
820                    copyList = histList[1:]
821            for item in copyList:
822                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
823                instData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'))[0]
824                if len(data) == len(instData) and instType == instData['Type'][0]:  #don't mix data types or lam & lam1/lam2 parms!
825                    instData.update(data)
826                else:
827                    print item+' not copied - instrument parameters not commensurate'
828        finally:
829            dlg.Destroy()
830       
831    def OnWaveChange(event):
832        if 'Lam' in insVal:
833            data['Lam1'] = [waves['CuKa'][0],waves['CuKa'][0],0]
834            data['Lam2'] = [waves['CuKa'][1],waves['CuKa'][1],0]
835            data['I(L2)/I(L1)'] = [0.5,0.5,0]
836            del(data['Lam'])
837        else:
838            data['Lam'] = [data['Lam1'][0],data['Lam1'][0],0]
839            del(data['Lam1'])
840        wx.CallAfter(UpdateInstrumentGrid,data)
841               
842    def OnLamPick(event):
843        lamType = lamPick.GetValue()
844        insVal['Lam1'] = waves[lamType][0]
845        insVal['Lam2'] = waves[lamType][1]
846        data = updateData(insVal,insRef)
847        UpdateInstrumentGrid(G2frame,data)
848                 
849    def OnRatValue(event):
850        try:
851            value = float(ratVal.GetValue())
852            if value < 0:
853                raise ValueError
854        except ValueError:
855            value = insVal['I(L2)/I(L1)']
856        insVal['I(L2)/I(L1)'] = value
857        ratVal.SetValue('%10.4f'%(value))
858        data = updateData(insVal,insRef)
859       
860    def OnRatRef(event):
861        insRef['I(L2)/I(L1)'] = ratRef.GetValue()
862        data = updateData(insVal,insRef)
863       
864    def OnWaveValue(event):
865        try:
866            value = float(waveVal.GetValue())
867            if value < 0:
868                raise ValueError
869        except ValueError:
870            value = insVal['Lam']
871        insVal['Lam'] = value
872        waveVal.SetValue('%10.6f'%(value))
873        data = updateData(insVal,insRef)
874       
875    def OnWaveRef(event):
876        insRef['Lam'] = waveRef.GetValue()
877        data = updateData(insVal,insRef)
878       
879    def OnItemValue(event):
880        Obj = event.GetEventObject()
881        item,fmt = ValObj[Obj.GetId()]
882        try:
883            value = float(Obj.GetValue())
884        except ValueError:
885            value = insVal[item]
886        insVal[item] = value
887        Obj.SetValue(fmt%(value))
888        data = updateData(insVal,insRef)
889        G2plt.PlotPeakWidths(G2frame)
890       
891    def OnItemRef(event):
892        Obj = event.GetEventObject()
893        item = RefObj[Obj.GetId()]
894        insRef[item] = Obj.GetValue()
895        data = updateData(insVal,insRef)
896               
897    if G2frame.dataDisplay:
898        G2frame.dataFrame.Clear()
899    try:
900        histoName = G2frame.PatternTree.GetItemPyData(G2frame.PatternId)[-1]
901        ifHisto = IsHistogramInAnyPhase(G2frame,histoName)
902    except TypeError:       #PKS data never used in a phase as data
903        ifhisto = False
904    G2gd.SetDataMenuBar(G2frame)
905    G2frame.dataFrame.SetLabel('Instrument Parameters')
906    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
907    topSizer = wx.FlexGridSizer(1,6,5,5)
908    instSizer = wx.FlexGridSizer(2,6,5,5)
909    topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Histogram Type: '+insVal['Type']),0,wx.ALIGN_CENTER_VERTICAL)
910#    topSizer.Add((5,5),0)
911    if 'P' in insVal['Type']:                   #powder data
912        G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.InstMenu)
913        if not G2frame.dataFrame.GetStatusBar():
914            Status = G2frame.dataFrame.CreateStatusBar()
915        G2frame.Bind(wx.EVT_MENU,OnLoad,id=G2gd.wxID_INSTLOAD)
916        G2frame.Bind(wx.EVT_MENU,OnSave,id=G2gd.wxID_INSTSAVE)
917        G2frame.Bind(wx.EVT_MENU,OnReset,id=G2gd.wxID_INSTPRMRESET)
918        G2frame.Bind(wx.EVT_MENU,OnInstCopy,id=G2gd.wxID_INSTCOPY)
919        G2frame.Bind(wx.EVT_MENU,OnInstFlagCopy,id=G2gd.wxID_INSTFLAGCOPY)
920        G2frame.Bind(wx.EVT_MENU,OnWaveChange,id=G2gd.wxID_CHANGEWAVETYPE)       
921        if 'C' in insVal['Type']:               #constant wavelength
922            #patch
923            if 'Azimuth' not in insVal:
924                insVal['Azimuth'] = 0.0
925                insDef['Azimuth'] = 0.0
926                insRef['Azimuth'] = False
927            #end of patch
928            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Azimuth: %7.2f'%(insVal['Azimuth'])),0,wx.ALIGN_CENTER_VERTICAL)
929            if 'Lam1' in insVal:
930                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Ka1/Ka2:'),
931                        0,wx.ALIGN_CENTER_VERTICAL)
932                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,%8.6f/%8.6f'%(insVal['Lam1'],insVal['Lam2'])),
933                        0,wx.ALIGN_CENTER_VERTICAL)
934                waveSizer = wx.BoxSizer(wx.HORIZONTAL)
935                waveSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Select: '),0,wx.ALIGN_CENTER_VERTICAL)
936                choice = ['TiKa','CrKa','FeKa','CoKa','CuKa','MoKa','AgKa']
937                lamPick = wx.ComboBox(G2frame.dataDisplay,value=' ',choices=choice,style=wx.CB_READONLY|wx.CB_DROPDOWN)
938                lamPick.Bind(wx.EVT_COMBOBOX, OnLamPick)
939                waveSizer.Add(lamPick,0)
940                topSizer.Add(waveSizer,0)
941                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' I(L2)/I(L1): (%10.4f)'%(insDef['I(L2)/I(L1)'])),
942                        0,wx.ALIGN_CENTER_VERTICAL)
943                ratVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.4f'%(insVal['I(L2)/I(L1)']),style=wx.TE_PROCESS_ENTER)
944                ratVal.Bind(wx.EVT_TEXT_ENTER,OnRatValue)
945                ratVal.Bind(wx.EVT_KILL_FOCUS,OnRatValue)
946                instSizer.Add(ratVal,0)
947                ratRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
948                ratRef.SetValue(bool(insRef['I(L2)/I(L1)']))
949                ratRef.Bind(wx.EVT_CHECKBOX, OnRatRef)
950                instSizer.Add(ratRef,0,wx.ALIGN_CENTER_VERTICAL)
951               
952            else:
953                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Lam: (%10.6f)'%(insDef['Lam'])),
954                    0,wx.ALIGN_CENTER_VERTICAL)
955                waveVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.6f'%(insVal['Lam']),style=wx.TE_PROCESS_ENTER)
956                waveVal.Bind(wx.EVT_TEXT_ENTER,OnWaveValue)
957                waveVal.Bind(wx.EVT_KILL_FOCUS,OnWaveValue)
958                topSizer.Add(waveVal,0,wx.ALIGN_CENTER_VERTICAL)
959                if ifHisto:
960                    waveRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
961                    waveRef.SetValue(bool(insRef['Lam']))
962                    waveRef.Bind(wx.EVT_CHECKBOX, OnWaveRef)
963                    topSizer.Add(waveRef,0,wx.ALIGN_CENTER_VERTICAL)
964            for item in ['Zero','Polariz.']:
965                fmt = '%10.4f'
966                Fmt = ' %s: ('+fmt+')'
967                if item in insDef:
968                    instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
969                            0,wx.ALIGN_CENTER_VERTICAL)
970                    itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
971                    ValObj[itemVal.GetId()] = [item,fmt]
972                    itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
973                    itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
974                    instSizer.Add(itemVal,0,wx.ALIGN_CENTER_VERTICAL)
975                    if ifHisto:
976                        itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
977                        itemRef.SetValue(bool(insRef[item]))
978                        RefObj[itemRef.GetId()] = item
979                        itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
980                        instSizer.Add(itemRef,0,wx.ALIGN_CENTER_VERTICAL)
981                    else:
982                        instSizer.Add((5,5),0)
983                else:                           #skip Polariz. for neutrons
984                    instSizer.Add((5,5),0)
985                    instSizer.Add((5,5),0)
986                    instSizer.Add((5,5),0)
987            for item in ['U','V','W','X','Y','SH/L']:
988                fmt = '%10.3f'
989                if item == 'SH/L':
990                    fmt = '%10.5f'
991                Fmt = ' %s: ('+fmt+')'
992                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
993                        0,wx.ALIGN_CENTER_VERTICAL)
994                itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
995                ValObj[itemVal.GetId()] = [item,fmt]
996                itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
997                itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
998                instSizer.Add(itemVal,0,wx.ALIGN_CENTER_VERTICAL)
999                itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
1000                itemRef.SetValue(bool(insRef[item]))
1001                RefObj[itemRef.GetId()] = item
1002                itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
1003                instSizer.Add(itemRef,0,wx.ALIGN_CENTER_VERTICAL)
1004        else:                                   #time of flight (neutrons)
1005            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Azimuth: %7.2f'%(insVal['Azimuth'])),0,wx.ALIGN_CENTER_VERTICAL)
1006            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' 2-theta: %7.2f'%(insVal['2-theta'])),0,wx.ALIGN_CENTER_VERTICAL)
1007            if 'Pdabc' in Inst2:
1008                Items = ['sig-0','sig-1','X','Y']
1009                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' difC: %8.2f'%(insVal['difC'])),0,wx.ALIGN_CENTER_VERTICAL)
1010                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' alpha, beta: fixed by table'),0,wx.ALIGN_CENTER_VERTICAL)
1011            else:
1012                Items = ['difC','difA','Zero','alpha','beta-0','beta-1','beta-q','sig-0','sig-1','sig-q','X','Y']
1013            for item in Items:
1014                fmt = '%10.3f'
1015                if 'beta' in item:
1016                    fmt = '%12.4g'
1017                Fmt = ' %s: ('+fmt+')'
1018                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
1019                        0,wx.ALIGN_CENTER_VERTICAL)
1020                itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
1021                ValObj[itemVal.GetId()] = [item,fmt]
1022                itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
1023                itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
1024                instSizer.Add(itemVal,0,wx.ALIGN_CENTER_VERTICAL)
1025                if not ifHisto and item in ['difC','difA','Zero',]:
1026                    instSizer.Add((5,5),0)
1027                else:
1028                    itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
1029                    itemRef.SetValue(bool(insRef[item]))
1030                    RefObj[itemRef.GetId()] = item
1031                    itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
1032                    instSizer.Add(itemRef,0,wx.ALIGN_CENTER_VERTICAL)
1033       
1034    else:                       #single crystal data
1035        if 'C' in insVal['Type']:               #constant wavelength
1036            instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Lam: (%10.6f)'%(insDef['Lam'])),
1037                0,wx.ALIGN_CENTER_VERTICAL)
1038            waveVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.6f'%(insVal['Lam']),style=wx.TE_PROCESS_ENTER)
1039            waveVal.Bind(wx.EVT_TEXT_ENTER,OnWaveValue)
1040            waveVal.Bind(wx.EVT_KILL_FOCUS,OnWaveValue)
1041            instSizer.Add(waveVal,0,wx.ALIGN_CENTER_VERTICAL)
1042        else:                                   #time of flight (neutrons)
1043            pass                                #for now
1044       
1045    mainSizer = wx.BoxSizer(wx.VERTICAL)
1046    mainSizer.Add(topSizer,0)
1047    mainSizer.Add(instSizer,0)
1048    mainSizer.Layout()   
1049    G2frame.dataDisplay.SetSizer(mainSizer)
1050    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1051   
1052################################################################################
1053#####  Sample parameters
1054################################################################################           
1055       
1056def UpdateSampleGrid(G2frame,data):
1057    '''respond to selection of PWDR Sample Parameters
1058    data tree item.
1059    '''
1060    def SetCopyNames(histName,addNames=[]):
1061        copyNames = ['Scale',]
1062        dataType = data['Type']
1063        histType = 'HKLF'
1064        if 'PWDR' in histName:          #else HKLF - only Scale
1065            histType = 'PWDR'
1066            if 'Debye' in dataType:
1067                copyNames += ['DisplaceX','DisplaceY','Absorption']
1068            else:       #Bragg-Brentano
1069                copyNames += ['Shift','Transparency']
1070        if len(addNames):
1071         copyNames += addNames
1072        return histType,copyNames
1073       
1074    def OnSampleSave(event):
1075        '''Respond to the Sample Parameters Operations/Save menu
1076        item: writes current parameters to a .samprm file
1077        '''
1078        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II sample parameters file', '.', '', 
1079            'sample parameter files (*.samprm)|*.samprm',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1080        try:
1081            if dlg.ShowModal() == wx.ID_OK:
1082                filename = dlg.GetPath()
1083                # make sure extension is .samprm
1084                filename = os.path.splitext(filename)[0]+'.samprm'
1085                File = open(filename,'w')
1086                File.write("#GSAS-II sample parameter file\n")
1087                File.write("'Type':'"+str(data['Type'])+"'\n")
1088                File.write("'Gonio. radius':"+str(data['Gonio. radius'])+"\n")
1089                if data.get('InstrName'):
1090                    File.write("'InstrName':'"+str(data['InstrName'])+"'\n")
1091                File.close()
1092        finally:
1093            dlg.Destroy()
1094                                               
1095       
1096    def OnSampleLoad(event):
1097        '''Loads sample parameters from a G2 .samprm file
1098        in response to the Sample Parameters-Operations/Load menu
1099       
1100        Note that similar code is found in ReadPowderInstprm (GSASII.py)
1101        '''
1102        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II sample parameters file', '.', '', 
1103            'sample parameter files (*.samprm)|*.samprm',wx.OPEN|wx.CHANGE_DIR)
1104        try:
1105            if dlg.ShowModal() == wx.ID_OK:
1106                filename = dlg.GetPath()
1107                File = open(filename,'r')
1108                S = File.readline()
1109                newItems = {}
1110                while S:
1111                    if S[0] == '#':
1112                        S = File.readline()
1113                        continue
1114                    [item,val] = S[:-1].split(':')
1115                    newItems[item.strip("'")] = eval(val)
1116                    S = File.readline()               
1117                File.close()
1118                data.update(newItems)
1119                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Sample Parameters'),data)
1120                UpdateSampleGrid(G2frame,data)
1121        finally:
1122            dlg.Destroy()
1123   
1124    def OnSampleCopy(event):
1125        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
1126        histType,copyNames = SetCopyNames(
1127            histName,
1128            addNames=['Omega','Chi','Phi','Gonio. radius','InstrName'])
1129        copyDict = {}
1130        for parm in copyNames:
1131            copyDict[parm] = data[parm]
1132        histList = ['All '+histType,]
1133        AllList = {}
1134        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1135        while item:
1136            name = G2frame.PatternTree.GetItemText(item)
1137            if histType in name and name != histName:
1138                allname = name.split(' Azm=')[0]
1139                if allname in AllList:
1140                    AllList[allname] += 1
1141                else:
1142                    AllList[allname] = 1
1143                histList.append(name)
1144            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1145        if len(histList) == 1:      #nothing to copy to!
1146            return
1147        nAll = 0
1148        AllNames = AllList.keys()
1149        AllNames.sort()
1150        for allname in AllNames:
1151            if AllList[allname] > 1:
1152                histList.insert(1+nAll,'All '+allname)
1153                nAll += 1
1154        copyList = []
1155        dlg = wx.MultiChoiceDialog(G2frame,'Copy parameters from\n'+histName,
1156            'Copy parameters',histList,wx.CHOICEDLG_STYLE)
1157        try:
1158            if dlg.ShowModal() == wx.ID_OK:
1159                result = dlg.GetSelections()
1160                for i in result: 
1161                    copyList.append(histList[i])
1162                for allname in AllList:
1163                    if 'All '+allname in copyList:
1164                        copyList = []
1165                        for name in histList:
1166                            if name.split(' Azm=')[0] == allname:
1167                                copyList.append(name)
1168                        break       #only one All allowed
1169                if 'All '+histType in copyList: 
1170                    copyList = histList[1+nAll:]
1171            for item in copyList:
1172                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
1173                sampleData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
1174                sampleData.update(copy.deepcopy(copyDict))
1175        finally:
1176            dlg.Destroy()
1177
1178    def OnSampleFlagCopy(event):
1179        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
1180        histType,copyNames = SetCopyNames(histName)
1181        flagDict = {}
1182        for parm in copyNames:
1183            flagDict[parm] = data[parm][1]
1184        histList = ['All '+histType,]
1185        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1186        while item:
1187            name = G2frame.PatternTree.GetItemText(item)
1188            if histType in name and name != histName:
1189                histList.append(name)
1190            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1191        if len(histList) == 1:      #nothing to copy to!
1192            return
1193        copyList = []
1194        dlg = wx.MultiChoiceDialog(G2frame,'Copy parameters from\n'+histName,
1195            'Copy refinement flags',histList,wx.CHOICEDLG_STYLE)
1196        try:
1197            if dlg.ShowModal() == wx.ID_OK:
1198                result = dlg.GetSelections()
1199                for i in result: 
1200                    copyList.append(histList[i])
1201                if 'All '+histType in copyList: 
1202                    copyList = histList[1:]
1203            for item in copyList:
1204                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
1205                sampleData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
1206                for name in copyNames:
1207                    sampleData[name][1] = copy.copy(flagDict[name])
1208        finally:
1209            dlg.Destroy()
1210
1211    if G2frame.dataDisplay:
1212        G2frame.dataFrame.Clear()
1213    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.SampleMenu)
1214    G2frame.dataFrame.SetLabel('Sample Parameters')
1215    G2frame.Bind(wx.EVT_MENU, OnSampleCopy, id=G2gd.wxID_SAMPLECOPY)
1216    G2frame.Bind(wx.EVT_MENU, OnSampleFlagCopy, id=G2gd.wxID_SAMPLEFLAGCOPY)
1217    G2frame.Bind(wx.EVT_MENU, OnSampleSave, id=G2gd.wxID_SAMPLESAVE)
1218    G2frame.Bind(wx.EVT_MENU, OnSampleLoad, id=G2gd.wxID_SAMPLELOAD)
1219    if not G2frame.dataFrame.GetStatusBar():
1220        Status = G2frame.dataFrame.CreateStatusBar()   
1221    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1222
1223#patch
1224    if 'ranId' not in data:
1225        data['ranId'] = ran.randint(0,sys.maxint)
1226    if not 'Gonio. radius' in data:
1227        data['Gonio. radius'] = 200.0
1228    if not 'Omega' in data:
1229        data.update({'Omega':0.0,'Chi':0.0,'Phi':0.0})
1230#patch end
1231   
1232    parms = [['Gonio. radius',' Goniometer radius(mm): ','%.2f',]]
1233    if data['Type'] == 'Debye-Scherrer':
1234        parms += [['DisplaceX',u' Sample X displ. perp. to beam (\xb5m): ','%.2f',],
1235            ['DisplaceY',u' Sample Y displ. || to beam (\xb5m): ','%.2f',],
1236            ['Absorption',u' Sample absorption(\xb5r): ','%.4f',],]
1237    elif data['Type'] == 'Bragg-Brentano':
1238        parms += [['Shift',u' Sample displacement(\xb5m): ','%.2f',],
1239            ['Transparency',u' Sample transparency(1/\xb5eff,cm): ','%.4f'],]
1240    parms.append(['Omega','Goniometer omega:','%.2f'])
1241    parms.append(['Chi','Goniometer chi:','%.2f'])
1242    parms.append(['Phi','Goniometer phi:','%.2f'])
1243    parms.append(['Temperature',' Sample temperature(K): ','%.2f'])
1244    parms.append(['Pressure',' Sample pressure(MPa): ','%.3f'])
1245    parms.append(['Humidity',' Sample humidity(%): ','%.1f'])
1246    parms.append(['Voltage',' Sample voltage(V): ','%.3f'])
1247    parms.append(['Force',' Applied load(MN): ','%.3f'])
1248    objList = {}
1249
1250    def OnScaleRef(event):
1251        Obj = event.GetEventObject()
1252        data['Scale'][1] = Obj.GetValue()
1253       
1254    def OnScaleVal(event):
1255        Obj = event.GetEventObject()
1256        try:
1257            scale = float(Obj.GetValue())
1258            if scale > 0:
1259                data['Scale'][0] = scale
1260        except ValueError:
1261            pass
1262        Obj.SetValue("%.4f"%(data['Scale'][0]))          #reset in case of error
1263       
1264    def OnHistoType(event):
1265        Obj = event.GetEventObject()
1266        data['Type'] = Obj.GetValue()
1267        if data['Type'] == 'Bragg-Brentano' and 'Shift' not in data:    #set up defaults for new type(s)
1268            data['Shift'] = [0.0,False]
1269            data['Transparency'] = [0.0,False]
1270        wx.CallAfter(UpdateSampleGrid,G2frame,data)
1271       
1272    def OnParmRef(event):
1273        Obj = event.GetEventObject()
1274        parm = objList[Obj.GetId()]
1275        data[parm][1] = Obj.GetValue()
1276       
1277    def OnParmVal(event):
1278        Obj = event.GetEventObject()
1279        parm = objList[Obj.GetId()]
1280        try:
1281            if 'list' in str(type(data[parm[0]])): 
1282                data[parm[0]][0] = float(Obj.GetValue())
1283            else:
1284                data[parm[0]] = float(Obj.GetValue())
1285        except ValueError:
1286            pass
1287        if 'list' in str(type(data[parm[0]])): 
1288            Obj.SetValue(parm[2]%(data[parm[0]][0]))          #reset in case of error
1289        else:
1290            Obj.SetValue(parm[2]%(data[parm[0]]))          #reset in case of error
1291
1292    def SetNameVal():
1293        inst = instNameVal.GetValue()
1294        data['InstrName'] = inst.strip()
1295        print data['InstrName']
1296    def OnNameVal(event):
1297        event.Skip()
1298        wx.CallAfter(SetNameVal)       
1299               
1300    mainSizer = wx.BoxSizer(wx.VERTICAL)
1301    topSizer = wx.BoxSizer(wx.HORIZONTAL)
1302    topSizer.Add((-1,-1),1,wx.EXPAND,1)
1303    topSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample and Experimental Parameters'))
1304    topSizer.Add((-1,-1),1,wx.EXPAND,1)
1305    mainSizer.Add(topSizer,0,wx.EXPAND,1)
1306    nameSizer = wx.BoxSizer(wx.HORIZONTAL)
1307    nameSizer.Add(wx.StaticText(G2frame.dataDisplay,wx.ID_ANY,'Instrument Name'),
1308                0,wx.ALIGN_CENTER_VERTICAL)
1309    nameSizer.Add((-1,-1),1,wx.EXPAND,1)
1310    instNameVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,data.get('InstrName',''),
1311                              size=(200,-1),style=wx.TE_PROCESS_ENTER)       
1312    nameSizer.Add(instNameVal)
1313    instNameVal.Bind(wx.EVT_CHAR,OnNameVal)
1314    mainSizer.Add(nameSizer,0,wx.EXPAND,1)
1315    mainSizer.Add((0,5),0)
1316
1317    mainSizer.Add((5,5),0)
1318    parmSizer = wx.FlexGridSizer(10,2,5,0)
1319    scaleRef = wx.CheckBox(G2frame.dataDisplay,label=' Histogram scale factor: ')
1320    scaleRef.SetValue(data['Scale'][1])
1321    scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
1322    parmSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
1323    scaleVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,
1324        '%.4f'%(data['Scale'][0]),style=wx.TE_PROCESS_ENTER)
1325    scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
1326    scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
1327    parmSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
1328    typeSizer = wx.BoxSizer(wx.HORIZONTAL)
1329    choices = ['Debye-Scherrer','Bragg-Brentano',]
1330    histoType = wx.ComboBox(G2frame.dataDisplay,wx.ID_ANY,value=data['Type'],choices=choices,
1331        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1332    histoType.Bind(wx.EVT_COMBOBOX, OnHistoType)
1333    parmSizer.Add(histoType)
1334    parmSizer.Add((5,5),0)
1335   
1336    for parm in parms:
1337        if 'list' in str(type(data[parm[0]])):
1338            parmRef = wx.CheckBox(G2frame.dataDisplay,label=parm[1])
1339            objList[parmRef.GetId()] = parm[0]
1340            parmRef.SetValue(data[parm[0]][1])
1341            parmRef.Bind(wx.EVT_CHECKBOX, OnParmRef)
1342            parmSizer.Add(parmRef,0,wx.ALIGN_CENTER_VERTICAL)
1343            parmVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,
1344                parm[2]%(data[parm[0]][0]),style=wx.TE_PROCESS_ENTER)
1345        else:
1346            parmSizer.Add(wx.StaticText(G2frame.dataDisplay,label=parm[1]),
1347                0,wx.ALIGN_CENTER_VERTICAL)
1348            parmVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,
1349                parm[2]%(data[parm[0]]),style=wx.TE_PROCESS_ENTER)       
1350        objList[parmVal.GetId()] = parm
1351        parmVal.Bind(wx.EVT_TEXT_ENTER,OnParmVal)
1352        parmVal.Bind(wx.EVT_KILL_FOCUS,OnParmVal)
1353        parmSizer.Add(parmVal,1,wx.EXPAND)
1354    mainSizer.Add(parmSizer)
1355    mainSizer.Add((0,5),0)   
1356   
1357    mainSizer.Layout()   
1358    G2frame.dataDisplay.SetSizer(mainSizer)
1359    Size = mainSizer.Fit(G2frame.dataFrame)
1360    G2frame.dataDisplay.SetSize(Size)
1361    G2frame.dataFrame.setSizePosLeft(Size)
1362               
1363################################################################################
1364#####  Indexing Peaks
1365################################################################################           
1366       
1367def UpdateIndexPeaksGrid(G2frame, data):
1368    '''respond to selection of PWDR Index Peak List data
1369    tree item.
1370    '''
1371    IndexId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Index Peak List')
1372    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[0]
1373    wave = G2mth.getWave(Inst)
1374   
1375    def RefreshIndexPeaksGrid(event):
1376        r,c =  event.GetRow(),event.GetCol()
1377        data = G2frame.IndexPeaksTable.GetData()
1378        if c == 2:
1379            if data[r][c]:
1380                data[r][c] = False
1381            else:
1382                data[r][c] = True
1383            G2frame.IndexPeaksTable.SetData(data)
1384            G2frame.PatternTree.SetItemPyData(IndexId,data)
1385            G2frame.dataDisplay.ForceRefresh()
1386           
1387    def OnReload(event):
1388        data = []
1389        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'))
1390        for peak in peaks:
1391            dsp = wave/(2.0*sind((peak[0]-Inst['Zero'][1])/2.0))
1392            data.append([peak[0],peak[2],True,False,0,0,0,dsp,0.0])
1393        G2frame.PatternTree.SetItemPyData(IndexId,data)
1394        UpdateIndexPeaksGrid(G2frame,data)
1395       
1396    def KeyEditPickGrid(event):
1397        colList = G2frame.dataDisplay.GetSelectedCols()
1398        rowList = G2frame.dataDisplay.GetSelectedRows()
1399        data = G2frame.PatternTree.GetItemPyData(IndexId)
1400        if event.GetKeyCode() == wx.WXK_RETURN:
1401            event.Skip(True)
1402        elif event.GetKeyCode() == wx.WXK_CONTROL:
1403            event.Skip(True)
1404        elif event.GetKeyCode() == wx.WXK_SHIFT:
1405            event.Skip(True)
1406        elif colList:
1407            G2frame.dataDisplay.ClearSelection()
1408            key = event.GetKeyCode()
1409            for col in colList:
1410                if G2frame.IndexPeaksTable.GetColLabelValue(col) in ['use','refine']:
1411                    if key == 89: #'Y'
1412                        for row in range(G2frame.IndexPeaksTable.GetNumberRows()): data[row][col]=True
1413                    elif key == 78:  #'N'
1414                        for row in range(G2frame.IndexPeaksTable.GetNumberRows()): data[row][col]=False
1415           
1416    if G2frame.dataDisplay:
1417        G2frame.dataFrame.Clear()
1418    if not G2frame.dataFrame.GetStatusBar():
1419        Status = G2frame.dataFrame.CreateStatusBar()
1420    if 'PWD' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1421        G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.IndPeaksMenu)
1422        G2frame.Bind(wx.EVT_MENU, OnReload, id=G2gd.wxID_INDXRELOAD)
1423    G2frame.dataFrame.IndexPeaks.Enable(False)
1424    G2frame.IndexPeaksTable = []
1425    if data:
1426        G2frame.dataFrame.IndexPeaks.Enable(True)
1427        cells = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Unit Cells List'))
1428        if cells:
1429            cellist = cells[2]
1430            dmin = cells[3]
1431            G2frame.HKL = []
1432            for i,cell in enumerate(cellist):
1433                if cell[-1]:
1434                    ibrav = cell[2]
1435                    A = G2lat.cell2A(cell[3:9])
1436                    G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,A)
1437                    G2indx.IndexPeaks(data,G2frame.HKL)
1438                    for hkl in G2frame.HKL:
1439                        hkl.append(2.0*asind(wave/(2.*hkl[3]))+Inst['Zero'][1])             
1440    rowLabels = []
1441    for i in range(len(data)): rowLabels.append(str(i+1))
1442    colLabels = ['position','intensity','use','indexed','h','k','l','d-obs','d-calc']
1443    Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
1444        wg.GRID_VALUE_BOOL,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,
1445        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5']
1446    G2frame.PatternTree.SetItemPyData(IndexId,data)
1447    G2frame.IndexPeaksTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1448    G2frame.dataFrame.SetLabel('Index Peak List')
1449    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)               
1450    G2frame.dataDisplay.SetTable(G2frame.IndexPeaksTable, True)
1451    for r in range(G2frame.dataDisplay.GetNumberRows()):
1452        for c in range(G2frame.dataDisplay.GetNumberCols()):
1453            if c == 2:
1454                G2frame.dataDisplay.SetReadOnly(r,c,isReadOnly=False)
1455            else:
1456                G2frame.dataDisplay.SetReadOnly(r,c,isReadOnly=True)
1457    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_LEFT_CLICK, RefreshIndexPeaksGrid)
1458    G2frame.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPickGrid)                 
1459    G2frame.dataDisplay.SetMargins(0,0)
1460    G2frame.dataDisplay.AutoSizeColumns(False)
1461    G2frame.dataFrame.setSizePosLeft([490,300])
1462 
1463################################################################################
1464#####  Unit cells
1465################################################################################           
1466       
1467def UpdateUnitCellsGrid(G2frame, data):
1468    '''respond to selection of PWDR Unit Cells data tree item.
1469    '''
1470    UnitCellsId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Unit Cells List')
1471    SPGlist = G2spc.spglist
1472    bravaisSymb = ['Fm3m','Im3m','Pm3m','R3-H','P6/mmm','I4/mmm',
1473        'P4/mmm','Fmmm','Immm','Cmmm','Pmmm','C2/m','P2/m','P1']
1474    spaceGroups = ['F m 3 m','I m 3 m','P m 3 m','R 3 m','P 6/m m m','I 4/m m m',
1475        'P 4/m m m','F m m m','I m m m','C m m m','P m m m','C 2/m','P 2/m','P -1']
1476    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[0]
1477    wave = G2mth.getWave(Inst)
1478   
1479    def SetLattice(controls):
1480        ibrav = bravaisSymb.index(controls[5])
1481        if ibrav in [0,1,2]:
1482            controls[7] = controls[8] = controls[6]
1483            controls[9] = controls[10] = controls[11] = 90.
1484        elif ibrav in [3,4,5,6]:
1485            controls[7] = controls[6]
1486            controls[9] = controls[10] = controls[11] = 90.
1487            if ibrav in [3,4]:
1488                controls[11] = 120.
1489        elif ibrav in [7,8,9,10]:
1490            controls[9] = controls[10] = controls[11] = 90.
1491        elif ibrav in [11,12]:
1492            controls[9] = controls[11] = 90.  # b unique
1493        if len(controls) < 13: controls.append(0)
1494        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1495        return ibrav
1496       
1497    def OnNcNo(event):
1498        controls[2] = NcNo.GetValue()
1499       
1500    def OnStartVol(event):
1501        try:
1502            stVol = int(float(startVol.GetValue()))
1503            if stVol < 25:
1504                raise ValueError
1505        except ValueError:
1506            stVol = 25
1507        controls[3] = stVol
1508        startVol.SetValue("%d"%(stVol))
1509       
1510    def OnBravais(event):
1511        Obj = event.GetEventObject()
1512        bravais[bravList.index(Obj.GetId())] = Obj.GetValue()
1513       
1514    def OnZero(event):
1515        try:
1516            Zero = min(5.0,max(-5.0,float(zero.GetValue())))
1517        except ValueError:
1518            Zero = 0.0
1519        controls[1] = Zero
1520        zero.SetValue("%.4f"%(Zero))
1521       
1522    def OnZeroVar(event):
1523        controls[0] = zeroVar.GetValue()
1524       
1525    def OnBravSel(event):
1526        brav = bravSel.GetString(bravSel.GetSelection())
1527        controls[5] = brav
1528        controls[13] = SPGlist[brav][0]       
1529        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1530       
1531    def OnSpcSel(event):
1532        controls[13] = spcSel.GetString(spcSel.GetSelection())       
1533       
1534    def OnCellChange(event):
1535        ibrav = bravaisSymb.index(controls[5])
1536        Obj = event.GetEventObject()
1537        ObjId = cellList.index(Obj.GetId())
1538        try:
1539            value = max(1.0,float(Obj.GetValue()))
1540        except ValueError:
1541            if ObjId < 3:               #bad cell edge - reset
1542                value = controls[6+ObjId]
1543            else:                       #bad angle
1544                value = 90.
1545        if ibrav in [0,1,2]:
1546            controls[6] = controls[7] = controls[8] = value
1547            controls[9] = controls[10] = controls[11] = 90.0
1548            Obj.SetValue("%.5f"%(controls[6]))
1549        elif ibrav in [3,4,5,6]:
1550            if ObjId == 0:
1551                controls[6] = controls[7] = value
1552                Obj.SetValue("%.5f"%(controls[6]))
1553            else:
1554                controls[8] = value
1555                Obj.SetValue("%.5f"%(controls[8]))
1556            controls[9] = controls[10] = controls[11] = 90.0
1557            if ibrav in [3,4]:
1558                controls[11] = 120.
1559        elif ibrav in [7,8,9,10]:
1560            controls[6+ObjId] = value
1561            Obj.SetValue("%.5f"%(controls[6+ObjId]))
1562            controls[9] = controls[10] = controls[11] = 90.0
1563        elif ibrav in [11,12]:
1564            controls[9] = controls[11] = 90.0
1565            if ObjId != 3:
1566                controls[6+ObjId] = value
1567                Obj.SetValue("%.5f"%(controls[6+ObjId]))
1568            else:
1569                controls[10] = value
1570                Obj.SetValue("%.3f"%(controls[10]))
1571        else:
1572            controls[6+ObjId] = value
1573            if ObjId < 3:
1574                Obj.SetValue("%.5f"%(controls[6+ObjId]))
1575            else:
1576                Obj.SetValue("%.3f"%(controls[6+ObjId]))
1577        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1578        volVal.SetValue("%.3f"%(controls[12]))
1579       
1580    def OnHklShow(event):
1581        PatternId = G2frame.PatternId
1582        PickId = G2frame.PickId   
1583        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
1584        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1585        cell = controls[6:12]
1586        A = G2lat.cell2A(cell)
1587        ibrav = bravaisSymb.index(controls[5])
1588        spc = controls[13]
1589        SGData = G2spc.SpcGroup(spc)[1]
1590        dmin = wave/(2.0*sind(limits[1]/2.0))
1591        G2frame.HKL = G2pwd.getHKLpeak(dmin,SGData,A)
1592        for hkl in G2frame.HKL:
1593            hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1594        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1595            G2plt.PlotPowderLines(G2frame)
1596        else:
1597            G2plt.PlotPatterns(G2frame)
1598           
1599    def OnSortCells(event):
1600        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(UnitCellsId)
1601        c =  event.GetCol()
1602        if colLabels[c] == 'M20':
1603            cells = G2indx.sortM20(cells)
1604        elif colLabels[c] == 'Volume':
1605            cells = G2indx.sortVolume(cells)
1606        else:
1607            return
1608        data = [controls,bravais,cells,dmin]
1609        G2frame.PatternTree.SetItemPyData(UnitCellsId,data)
1610        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1611       
1612    def CopyUnitCell(event):
1613        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(UnitCellsId)
1614        for Cell in cells:
1615            if Cell[-2]:
1616                break
1617        cell = Cell[2:9]
1618        controls[4] = 1
1619        controls[5] = bravaisSymb[cell[0]]
1620        controls[6:12] = cell[1:8]
1621        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1622        controls[13] = spaceGroups[bravaisSymb.index(controls[5])]
1623        G2frame.PatternTree.SetItemPyData(UnitCellsId,[controls,bravais,cells,dmin])
1624        G2frame.dataFrame.RefineCell.Enable(True)
1625        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)       
1626               
1627    def RefineCell(event):
1628        def cellPrint(ibrav,A):
1629            cell = G2lat.A2cell(A)
1630            Vol = G2lat.calc_V(A)
1631            if ibrav in [0,1,2]:
1632                print "%s%10.6f" % ('a =',cell[0])
1633            elif ibrav in [3,4,5,6]:
1634                print "%s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],' c =',cell[2],' volume =',Vol)
1635            elif ibrav in [7,8,9,10]:
1636                print "%s%10.6f %s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2],' volume =',Vol)
1637            elif ibrav in [11,12]:
1638                print "%s%10.6f %s%10.6f %s%10.6f %s%8.3f %s%12.3f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2],'beta =',cell[4],' volume =',Vol)
1639            else:
1640                print "%s%10.6f %s%10.6f %s%10.6f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2])
1641                print "%s%8.3f %s%8.3f %s%8.3f %s%12.3f" % ('alpha =',cell[3],'beta =',cell[4],'gamma =',cell[5],' volume =',Vol)
1642             
1643        PatternId = G2frame.PatternId
1644        PickId = G2frame.PickId   
1645        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List'))
1646        if not peaks:
1647            G2frame.ErrorDialog('No peaks!', 'Nothing to refine!')
1648            return       
1649        print 'Refine cell'
1650        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1651        cell = controls[6:12]
1652        A = G2lat.cell2A(cell)
1653        ibrav = bravaisSymb.index(controls[5])
1654        SGData = G2spc.SpcGroup(controls[13])[1]
1655        dmin = G2indx.getDmin(peaks)-0.005
1656        G2frame.HKL = G2pwd.getHKLpeak(dmin,SGData,A)
1657        G2indx.IndexPeaks(peaks,G2frame.HKL)
1658        Lhkl,M20,X20,Aref,Zero = G2indx.refinePeaksZ(peaks,wave,ibrav,A,controls[1],controls[0])           
1659        controls[1] = Zero
1660        controls[6:12] = G2lat.A2cell(Aref)
1661        controls[12] = G2lat.calc_V(Aref)
1662        data = [controls,bravais,cells,dmin]
1663        cells = G2frame.PatternTree.GetItemPyData(UnitCellsId)[2]
1664        for cell in cells:
1665            cell[-2] = False
1666        cells.insert(0,[M20,X20,ibrav]+controls[6:13]+[True,False])
1667        data[2] = cells
1668        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'),data)
1669        G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,Aref)
1670        print "%s%10.3f" % ('refinement M20 = ',M20)
1671        print 'unindexed lines = ',X20
1672        cellPrint(ibrav,Aref)
1673        for hkl in G2frame.HKL:
1674            hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1675        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1676            G2plt.PlotPowderLines(G2frame)
1677        else:
1678            G2plt.PlotPatterns(G2frame)
1679        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1680       
1681    def IndexPeaks(event):
1682        PatternId = G2frame.PatternId   
1683        print 'Peak Indexing'
1684        keepcells = []
1685        try:
1686            controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1687            for cell in cells:
1688                if cell[11]:
1689                    keepcells.append(cell)
1690        except IndexError:
1691            pass
1692        except ValueError:
1693            G2frame.ErrorDialog('Error','Need to set controls in Unit Cell List first')
1694            return
1695        if True not in bravais:
1696            G2frame.ErrorDialog('Error','No Bravais lattices selected')
1697            return
1698        G2frame.dataFrame.CopyCell.Enable(False)
1699        G2frame.dataFrame.RefineCell.Enable(False)
1700        OK,dmin,newcells = G2indx.DoIndexPeaks(peaks,wave,controls,bravais)
1701        cells = keepcells+newcells
1702        cells = G2indx.sortM20(cells)
1703        cells[0][10] = True
1704        if OK:
1705            data = [controls,bravais,cells,dmin]
1706            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'),data)
1707            bestCell = cells[0]
1708            if bestCell[0] > 10.:
1709                G2frame.HKL = G2lat.GenHBravais(dmin,bestCell[2],G2lat.cell2A(bestCell[3:9]))
1710                for hkl in G2frame.HKL:
1711                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1712                if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1713                    G2plt.PlotPowderLines(G2frame)
1714                else:
1715                    G2plt.PlotPatterns(G2frame)
1716            G2frame.dataFrame.CopyCell.Enable(True)
1717            G2frame.dataFrame.IndexPeaks.Enable(True)
1718            G2frame.dataFrame.MakeNewPhase.Enable(True)
1719        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1720               
1721    def RefreshUnitCellsGrid(event):
1722        data =G2frame.PatternTree.GetItemPyData(UnitCellsId)
1723        cells,dmin = data[2:]
1724        r,c =  event.GetRow(),event.GetCol()
1725        if cells:
1726            if c == 2:
1727                for i in range(len(cells)):
1728                    cells[i][-2] = False
1729                    UnitCellsTable.SetValue(i,c,False)
1730                UnitCellsTable.SetValue(r,c,True)
1731                gridDisplay.ForceRefresh()
1732                cells[r][-2] = True
1733                ibrav = cells[r][2]
1734                A = G2lat.cell2A(cells[r][3:9])
1735                G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,A)
1736                for hkl in G2frame.HKL:
1737                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1738                if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1739                    G2plt.PlotPowderLines(G2frame)
1740                else:
1741                    G2plt.PlotPatterns(G2frame)
1742            elif c == 11:
1743                if UnitCellsTable.GetValue(r,c):
1744                    UnitCellsTable.SetValue(r,c,False)
1745                    cells[r][c] = False
1746                else:
1747                    cells[r][c] = True
1748                    UnitCellsTable.SetValue(r,c,True)
1749                gridDisplay.ForceRefresh()
1750            G2frame.PatternTree.SetItemPyData(UnitCellsId,data)               
1751       
1752    def MakeNewPhase(event):
1753        if not G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases'):
1754            sub = G2frame.PatternTree.AppendItem(parent=G2frame.root,text='Phases')
1755        else:
1756            sub = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases')
1757        PhaseName = ''
1758        dlg = wx.TextEntryDialog(None,'Enter a name for this phase','Phase Name Entry','New phase',
1759            style=wx.OK)
1760        try:
1761            if dlg.ShowModal() == wx.ID_OK:
1762                PhaseName = dlg.GetValue()
1763                cells = G2frame.PatternTree.GetItemPyData(UnitCellsId)[2]
1764                for Cell in cells:
1765                    if Cell[-2]:
1766                        break
1767                cell = Cell[2:10]       
1768                sub = G2frame.PatternTree.AppendItem(parent=sub,text=PhaseName)
1769                E,SGData = G2spc.SpcGroup(controls[13])
1770                G2frame.PatternTree.SetItemPyData(sub, \
1771                    G2IO.SetNewPhase(Name=PhaseName,SGData=SGData,cell=cell[1:]))
1772                Status.SetStatusText('Change space group if needed')
1773        finally:
1774            dlg.Destroy()
1775           
1776    if G2frame.dataDisplay:
1777        G2frame.dataFrame.Clear()
1778    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.IndexMenu)
1779    if not G2frame.dataFrame.GetStatusBar():
1780        Status = G2frame.dataFrame.CreateStatusBar()
1781    G2frame.Bind(wx.EVT_MENU, IndexPeaks, id=G2gd.wxID_INDEXPEAKS)
1782    G2frame.Bind(wx.EVT_MENU, CopyUnitCell, id=G2gd.wxID_COPYCELL)
1783    G2frame.Bind(wx.EVT_MENU, RefineCell, id=G2gd.wxID_REFINECELL)
1784    G2frame.Bind(wx.EVT_MENU, MakeNewPhase, id=G2gd.wxID_MAKENEWPHASE)
1785   
1786    controls,bravais,cells,dmin = data
1787    if len(controls) < 13:              #add cell volume if missing
1788        controls.append(G2lat.calc_V(G2lat.cell2A(controls[6:12])))
1789    if len(controls) < 14:              #add space gropu used in indexing
1790        controls.append(spaceGroups[bravaisSymb.index(controls[5])])
1791    G2frame.PatternTree.SetItemPyData(UnitCellsId,data)            #update with volume
1792    bravaisNames = ['Cubic-F','Cubic-I','Cubic-P','Trigonal-R','Trigonal/Hexagonal-P',
1793        'Tetragonal-I','Tetragonal-P','Orthorhombic-F','Orthorhombic-I','Orthorhombic-C',
1794        'Orthorhombic-P','Monoclinic-C','Monoclinic-P','Triclinic']
1795    cellGUIlist = [[[0,1,2],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
1796    [[3,4,5,6],6,zip([" Unit cell: a = "," c = "," Vol = "],["%.5f","%.5f","%.3f"],[True,True,False],[0,2,0])],
1797    [[7,8,9,10],8,zip([" Unit cell: a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
1798        [True,True,True,False],[0,1,2,0])],
1799    [[11,12],10,zip([" Unit cell: a = "," b = "," c = "," beta = "," Vol = "],
1800        ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
1801    [[13,],8,zip([" Unit cell: a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
1802        ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
1803        [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
1804   
1805    G2frame.dataFrame.SetLabel('Unit Cells List')
1806    G2frame.sp = wx.SplitterWindow(G2frame.dataFrame)
1807    G2frame.dataDisplay = wx.Panel(G2frame.sp, style=wx.SUNKEN_BORDER)
1808    G2frame.dataFrame.IndexPeaks.Enable(False)
1809    peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Index Peak List'))
1810    if peaks:
1811        G2frame.dataFrame.IndexPeaks.Enable(True)
1812    G2frame.dataFrame.RefineCell.Enable(False)
1813    if controls[12] > 1.0:                               #if a "real" volume (i.e. not default)
1814        G2frame.dataFrame.RefineCell.Enable(True)   
1815    G2frame.dataFrame.CopyCell.Enable(False)
1816    G2frame.dataFrame.MakeNewPhase.Enable(False)       
1817    if cells:
1818        G2frame.bottom = wx.Panel(G2frame.sp, style=wx.SUNKEN_BORDER)
1819        G2frame.sp.SplitHorizontally(G2frame.dataDisplay,G2frame.bottom,0)
1820        G2frame.dataFrame.CopyCell.Enable(True)
1821        G2frame.dataFrame.MakeNewPhase.Enable(True)       
1822    mainSizer = wx.BoxSizer(wx.VERTICAL)
1823    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Indexing controls: '),0,wx.ALIGN_CENTER_VERTICAL)
1824    mainSizer.Add((5,5),0)
1825    littleSizer = wx.FlexGridSizer(2,5,5,5)
1826    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Max Nc/Nobs '),0,wx.ALIGN_CENTER_VERTICAL)
1827    NcNo = wx.SpinCtrl(G2frame.dataDisplay)
1828    NcNo.SetRange(1,6)
1829    NcNo.SetValue(controls[2])
1830    NcNo.Bind(wx.EVT_SPINCTRL,OnNcNo)
1831    littleSizer.Add(NcNo,0,wx.ALIGN_CENTER_VERTICAL)
1832    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Start Volume '),0,wx.ALIGN_CENTER_VERTICAL)
1833    startVol = wx.TextCtrl(G2frame.dataDisplay,value=str('%d'%(controls[3])),style=wx.TE_PROCESS_ENTER)
1834    startVol.Bind(wx.EVT_TEXT_ENTER,OnStartVol)
1835    startVol.Bind(wx.EVT_KILL_FOCUS,OnStartVol)
1836    littleSizer.Add(startVol,0,wx.ALIGN_CENTER_VERTICAL)
1837    mainSizer.Add(littleSizer,0)
1838    mainSizer.Add((5,5),0)
1839    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Select Bravais Lattices for indexing: '),
1840        0,wx.ALIGN_CENTER_VERTICAL)
1841    mainSizer.Add((5,5),0)
1842    littleSizer = wx.FlexGridSizer(2,7,5,5)
1843    bravList = []
1844    bravs = zip(bravais,bravaisNames)
1845    for brav,bravName in bravs:
1846        bravCk = wx.CheckBox(G2frame.dataDisplay,label=bravName)
1847        bravList.append(bravCk.GetId())
1848        bravCk.SetValue(brav)
1849        bravCk.Bind(wx.EVT_CHECKBOX,OnBravais)
1850        littleSizer.Add(bravCk,0,wx.ALIGN_CENTER_VERTICAL)
1851    mainSizer.Add(littleSizer,0)
1852    mainSizer.Add((5,5),0)
1853   
1854    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Cell Refinement: '),0,wx.ALIGN_CENTER_VERTICAL)
1855    mainSizer.Add((5,5),0)
1856    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
1857    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Bravais lattice "),0,wx.ALIGN_CENTER_VERTICAL)
1858    bravSel = wx.Choice(G2frame.dataDisplay,choices=bravaisSymb)
1859    bravSel.SetSelection(bravaisSymb.index(controls[5]))
1860    bravSel.Bind(wx.EVT_CHOICE,OnBravSel)
1861    littleSizer.Add(bravSel,0,wx.ALIGN_CENTER_VERTICAL)
1862    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Space group "),0,wx.ALIGN_CENTER_VERTICAL)
1863    spcSel = wx.Choice(G2frame.dataDisplay,choices=SPGlist[controls[5]])
1864    spcSel.SetSelection(SPGlist[controls[5]].index(controls[13]))
1865    spcSel.Bind(wx.EVT_CHOICE,OnSpcSel)
1866    littleSizer.Add(spcSel,0,wx.ALIGN_CENTER_VERTICAL)
1867    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Zero offset"),0,wx.ALIGN_CENTER_VERTICAL)
1868    zero = wx.TextCtrl(G2frame.dataDisplay,value="%.4f"%(controls[1]),style=wx.TE_PROCESS_ENTER)
1869    zero.Bind(wx.EVT_TEXT_ENTER,OnZero)
1870    zero.Bind(wx.EVT_KILL_FOCUS,OnZero)
1871    littleSizer.Add(zero,0,wx.ALIGN_CENTER_VERTICAL)
1872    zeroVar = wx.CheckBox(G2frame.dataDisplay,label="Refine?")
1873    zeroVar.SetValue(controls[0])
1874    zeroVar.Bind(wx.EVT_CHECKBOX,OnZeroVar)
1875    littleSizer.Add(zeroVar,0,wx.ALIGN_CENTER_VERTICAL)
1876    hklShow = wx.Button(G2frame.dataDisplay,label="Show hkl positions")
1877    hklShow.Bind(wx.EVT_BUTTON,OnHklShow)
1878    littleSizer.Add(hklShow,0,wx.ALIGN_CENTER_VERTICAL)
1879    mainSizer.Add(littleSizer,0)
1880   
1881    mainSizer.Add((5,5),0)
1882    ibrav = SetLattice(controls)
1883    for cellGUI in cellGUIlist:
1884        if ibrav in cellGUI[0]:
1885            useGUI = cellGUI
1886    cellList = []
1887    littleSizer = wx.FlexGridSizer(2,useGUI[1],5,5)
1888    for txt,fmt,ifEdit,Id in useGUI[2]:
1889        littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL)
1890        if ifEdit:          #a,b,c,etc.
1891            cellVal = wx.TextCtrl(G2frame.dataDisplay,value=(fmt%(controls[6+Id])),style=wx.TE_PROCESS_ENTER)
1892            cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
1893            cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
1894            littleSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL)
1895            cellList.append(cellVal.GetId())
1896        else:               #volume
1897            volVal = wx.TextCtrl(G2frame.dataDisplay,value=(fmt%(controls[12])),style=wx.TE_READONLY)
1898            volVal.SetBackgroundColour(VERY_LIGHT_GREY)
1899            littleSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL)
1900    mainSizer.Add(littleSizer,0)
1901       
1902    mainSizer.Layout()   
1903    G2frame.dataDisplay.SetSizer(mainSizer)
1904    topSize = mainSizer.Fit(G2frame.dataFrame)
1905    G2frame.dataDisplay.SetSize(topSize)
1906    if cells:
1907        if ibrav == 13:
1908            topSize[1] += 230
1909        else:
1910            topSize[1] += 200
1911    G2frame.dataFrame.setSizePosLeft(topSize)   
1912   
1913    if cells:
1914        bottomSize = topSize        #screwy but bottom doesn't have a size in linux!
1915        bottomSize[0] -= 20         #to reveal slider
1916        if ibrav == 13:
1917            bottomSize[1] -= 240
1918        else:
1919            bottomSize[1] -= 210
1920        wx.StaticText(parent=G2frame.bottom,label=' Indexing Result ')
1921        rowLabels = []
1922        colLabels = ['M20','X20','use','Bravais','a','b','c','alpha','beta','gamma','Volume','Keep']
1923        Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_NUMBER,wg.GRID_VALUE_BOOL,wg.GRID_VALUE_STRING,]+ \
1924            3*[wg.GRID_VALUE_FLOAT+':10,5',]+3*[wg.GRID_VALUE_FLOAT+':10,3',]+ \
1925            [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL]
1926        numRows = len(cells)
1927        table = []
1928        for cell in cells:
1929            rowLabels.append('')
1930            row = cell[0:2]+[cell[-2]]+[bravaisSymb[cell[2]]]+cell[3:10]+[cell[11],]
1931            if cell[-2]:
1932                A = G2lat.cell2A(cell[3:9])
1933                G2frame.HKL = G2lat.GenHBravais(dmin,cell[2],A)
1934                for hkl in G2frame.HKL:
1935                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1936            table.append(row)
1937        UnitCellsTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1938        gridDisplay = G2gd.GSGrid(G2frame.bottom)
1939        gridDisplay.SetPosition(wx.Point(0,20))               
1940        gridDisplay.SetTable(UnitCellsTable, True)
1941        G2frame.dataFrame.CopyCell.Enable(True)
1942        gridDisplay.Bind(wg.EVT_GRID_CELL_LEFT_CLICK,RefreshUnitCellsGrid)
1943        gridDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK,OnSortCells)
1944        gridDisplay.SetMargins(0,0)
1945        gridDisplay.SetRowLabelSize(0)
1946        gridDisplay.AutoSizeColumns(False)
1947        for r in range(gridDisplay.GetNumberRows()):
1948            for c in range(gridDisplay.GetNumberCols()):
1949                if c == 2:
1950                    gridDisplay.SetReadOnly(r,c,isReadOnly=False)
1951                else:
1952                    gridDisplay.SetReadOnly(r,c,isReadOnly=True)
1953        gridDisplay.SetSize(bottomSize)
1954
1955################################################################################
1956#####  Reflection list
1957################################################################################           
1958       
1959def UpdateReflectionGrid(G2frame,data,HKLF=False,Name=''):
1960    '''respond to selection of PWDR Reflections data tree item.
1961    '''
1962    if not data:
1963        print 'No phases, no reflections'
1964        return
1965    if HKLF:
1966        G2frame.RefList = 1
1967        phaseName = Name
1968    else:
1969        phaseName = G2frame.RefList
1970        phases = data.keys()
1971   
1972        def OnSelectPhase(event):
1973            dlg = wx.SingleChoiceDialog(G2frame,'Select','Phase',phases)
1974            try:
1975                if dlg.ShowModal() == wx.ID_OK:
1976                    sel = dlg.GetSelection()
1977                    G2frame.RefList = phases[sel]
1978                    UpdateReflectionGrid(G2frame,data)
1979            finally:
1980                dlg.Destroy()
1981            G2plt.PlotPatterns(G2frame)
1982       
1983    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            wx.CallAfter(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.