source: trunk/GSASIIpwdGUI.py @ 447

Last change on this file since 447 was 447, checked in by vondreele, 11 years ago

Add another variation on background - individual peaks (not finished)
fix image calibration problem

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