source: trunk/GSASIIpwdGUI.py @ 1213

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

begin modification of SASD Sample to include materials & thickness

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