source: trunk/GSASIIpwdGUI.py @ 1147

Last change on this file since 1147 was 1147, checked in by toby, 9 years ago

Complete initial ISODISPLACE implementation; mod. phase initialization; change atom pointer init.; rework parameter display window

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