source: trunk/GSASIIpwdGUI.py @ 443

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

make sum powder profiles numpy arrays
change name UpdateBackgroundGrid? to UpdateBackground?
min size is 1 nanometer = 10A
implement diffuse scattering model for background
iso/aniso Size & Mustrain are now Size:i/a instead of 0/1

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