source: trunk/GSASIIpwdGUI.py @ 272

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

add slider for "Ruland" coeff.
add 'o' option for undoing offset in powder plots

  • Property svn:keywords set to Date Author Revision URL Id
File size: 71.5 KB
Line 
1#GSASII - data display routines
2########### SVN repository information ###################
3# $Date: 2011-04-29 19:20:30 +0000 (Fri, 29 Apr 2011) $
4# $Author: vondreele $
5# $Revision: 272 $
6# $URL: trunk/GSASIIpwdGUI.py $
7# $Id: GSASIIpwdGUI.py 272 2011-04-29 19:20:30Z vondreele $
8########### SVN repository information ###################
9import wx
10import wx.grid as wg
11import numpy as np
12import math
13import time
14import cPickle
15import GSASIIpath
16import GSASIIpwd as G2pwd
17import GSASIIlattice as G2lat
18import GSASIIspc as G2spc
19import GSASIIindex as G2indx
20import GSASIIplot as G2plt
21import GSASIIgrid as G2gd
22import GSASIIElem as G2elem
23
24VERY_LIGHT_GREY = wx.Colour(235,235,235)
25
26# trig functions in degrees
27sind = lambda x: math.sin(x*math.pi/180.)
28tand = lambda x: math.tan(x*math.pi/180.)
29cosd = lambda x: math.cos(x*math.pi/180.)
30asind = lambda x: 180.*math.asin(x)/math.pi
31       
32def UpdatePeakGrid(self, data):
33    if self.dataDisplay:
34        self.dataFrame.Clear()
35   
36    def OnUnDo(event):
37        DoUnDo()
38        self.dataFrame.UnDo.Enable(False)
39       
40    def DoUnDo():
41        print 'Undo last refinement'
42        file = open(self.undofile,'rb')
43        PatternId = self.PatternId
44        for item in ['Background','Instrument Parameters','Peak List']:
45            self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, item),cPickle.load(file))
46            if self.dataDisplay.GetName() == item:
47                if item == 'Background':
48                    UpdateBackgroundGrid(self,self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, item)))
49                elif item == 'Instrument Parameters':
50                    UpdateInstrumentGrid(self,self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, item)))
51                elif item == 'Peak List':
52                    UpdatePeakGrid(self,self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, item)))
53            print item,' recovered'
54        file.close()
55       
56    def SaveState():
57        self.undofile = self.dirname+'\\GSASII.save'
58        file = open(self.undofile,'wb')
59        PatternId = self.PatternId
60        for item in ['Background','Instrument Parameters','Peak List']:
61            cPickle.dump(self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId,item)),file,1)
62        file.close()
63        self.dataFrame.UnDo.Enable(True)
64               
65    def OnPeakFit(event):
66        SaveState()
67        print 'Peak Fitting - Do one cycle of peak fitting'
68        PatternId = self.PatternId
69        PickId = self.PickId
70        peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Peak List'))
71        if not peaks:
72            self.ErrorDialog('No peaks!','Nothing to fit!')
73            return
74        background = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Background'))[0]
75        limits = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Limits'))[1]
76        inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))
77        data = self.PatternTree.GetItemPyData(PatternId)[1]
78        OK,smin,Rwp,runtime,GoOn = G2pwd.DoPeakFit(peaks,background,limits,inst,data)
79        UpdatePeakGrid(self,peaks)
80        G2plt.PlotPatterns(self)
81        if not OK:
82            print 'Refinement failed'
83            dlg = wx.MessageDialog(self, 'Do you want to reload now?', 'Refinement failed',  wx.YES_NO)
84            try:
85                if dlg.ShowModal() == wx.ID_YES:
86                    DoUnDo()
87                    self.dataFrame.UnDo.Enable(False)
88            finally:
89                dlg.Destroy()
90        else:
91            self.dataFrame.UnDo.Enable(True)
92            print "%s%7.2f%s%12.6g" % ('Rwp = ',Rwp,'%, Smin = ',smin)
93            print "%s%8.3f%s " % ('fitpeak time =',runtime,'s')
94            print 'finished'
95        return
96       
97    def OnAutoPeakFit(event):
98        SaveState()
99        print 'AutoPeak Fitting - run until minimized'
100        PatternId = self.PatternId
101        PickId = self.PickId
102        peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Peak List'))
103        if not peaks:
104            self.ErrorDialog('No peaks!','Nothing to fit!')
105            return
106        background = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Background'))[0]
107        limits = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Limits'))[1]
108        inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))
109        data = self.PatternTree.GetItemPyData(PatternId)[1]
110        smin = 1.0e15
111        GoOn = True
112        while GoOn:
113            osmin = smin
114            OK,smin,Rwp,runtime,GoOn = G2pwd.DoPeakFit(peaks,background,limits,inst,data)
115            UpdatePeakGrid(self,peaks)
116            if not OK:
117                break
118            G2plt.PlotPatterns(self)
119            print "%s%7.2f%s%12.6g" % ('Rwp = ',Rwp,'%, Smin = ',smin)
120            rat = (osmin-smin)/smin
121            if rat < 1.0e-4: GoOn = False
122        if not OK:
123            print 'Refinement failed'
124            dlg = wx.MessageDialog(self, 'Do you want to reload now?', 'Refinement failed',  wx.YES_NO)
125            try:
126                if dlg.ShowModal() == wx.ID_YES:
127                    DoUnDo()
128                    self.dataFrame.UnDo.Enable(False)
129            finally:
130                dlg.Destroy()
131        else:
132            self.dataFrame.UnDo.Enable(True)
133            print "%s%8.3f%s " % ('fitpeak time =',runtime,'s per cycle')
134            print 'finished'
135        return       
136
137    def RefreshPeakGrid(event):
138        event.StopPropagation()
139        data = self.PeakTable.GetData()
140        T = []
141        for peak in data:T.append(peak[0])
142        D = dict(zip(T,data))
143        T.sort()
144        X = []
145        for key in T: X.append(D[key])
146        data = X       
147        G2plt.PlotPatterns(self)
148       
149    def setBackgroundColors():
150       for r in range(self.dataDisplay.GetNumberRows()):
151           for c in range(self.dataDisplay.GetNumberCols()):
152               if self.dataDisplay.GetColLabelValue(c) in ['position','intensity','sigma','gamma']:
153                   if float(self.dataDisplay.GetCellValue(r,c)) < 0.:
154                       self.dataDisplay.SetCellBackgroundColour(r,c,wx.RED)
155                   else:
156                       self.dataDisplay.SetCellBackgroundColour(r,c,wx.WHITE)
157                       
158    def RefineSelect(event):
159        data = self.PatternTree.GetItemPyData(self.PickId)
160        r,c =  event.GetRow(),event.GetCol()
161        if r < 0 and self.dataDisplay.GetColLabelValue(c) == 'refine':
162            self.dataDisplay.SelectCol(c,False)
163       
164                       
165    def RowSelect(event):
166        r,c =  event.GetRow(),event.GetCol()
167        if r < 0 and c < 0:
168            if self.dataDisplay.IsSelection():
169                self.dataDisplay.ClearSelection()
170        elif c < 0:                   #only row clicks
171            if event.ControlDown():                   
172                if r in self.dataDisplay.GetSelectedRows():
173                    self.dataDisplay.DeselectRow(r)
174                else:
175                    self.dataDisplay.SelectRow(r,True)
176            elif event.ShiftDown():
177                for row in range(r+1):
178                    self.dataDisplay.SelectRow(row,True)
179            else:
180                self.dataDisplay.ClearSelection()
181                self.dataDisplay.SelectRow(r,True)               
182       
183                           
184    def KeyEditPeakGrid(event):
185        rowList = self.dataDisplay.GetSelectedRows()
186        colList = self.dataDisplay.GetSelectedCols()
187        selectList = self.dataDisplay.GetSelectedCells()
188        data = self.PatternTree.GetItemPyData(self.PickId)
189        if event.GetKeyCode() == wx.WXK_RETURN:
190            event.Skip(True)
191        elif event.GetKeyCode() == wx.WXK_CONTROL:
192            event.Skip(True)
193        elif event.GetKeyCode() == wx.WXK_SHIFT:
194            event.Skip(True)
195        elif rowList:
196            self.dataDisplay.ClearSelection()
197            if event.GetKeyCode() == wx.WXK_DELETE:
198                self.dataDisplay.ClearGrid()
199                rowList.reverse()
200                nDel = 0
201                for row in rowList:
202                    self.PeakTable.DeleteRow(row)
203                    nDel += 1
204                if nDel:
205                    msg = wg.GridTableMessage(self.PeakTable, 
206                        wg.GRIDTABLE_NOTIFY_ROWS_DELETED,0,nDel)
207                    self.dataDisplay.ProcessTableMessage(msg)
208                data = self.PeakTable.GetData()
209                self.PatternTree.SetItemPyData(self.PickId,data[:-nDel])
210                self.dataDisplay.ForceRefresh()
211                setBackgroundColors()
212                if not len(self.PatternTree.GetItemPyData(self.PickId)): 
213                    self.dataFrame.PeakFit.Enable(False)
214                    self.dataFrame.AutoPeakFit.Enable(False)
215                       
216        elif colList:
217            self.dataDisplay.ClearSelection()
218            key = event.GetKeyCode()
219            for col in colList:
220                if self.PeakTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
221                    if key == 89: #'Y'
222                        for row in range(self.PeakTable.GetNumberRows()): data[row][col]=True
223                    elif key == 78:  #'N'
224                        for row in range(self.PeakTable.GetNumberRows()): data[row][col]=False
225        elif selectList:
226            self.dataDisplay.ClearSelection()
227            key = event.GetKeyCode()
228            for row,col in selectList:
229                if self.PeakTable.GetTypeName(row,col) == wg.GRID_VALUE_BOOL:
230                    if key == 89: #'Y'
231                        data[row][col]=True
232                    elif key == 78:  #'N'
233                        data[row][col]=False
234        G2plt.PlotPatterns(self)
235           
236    self.dataFrame.SetMenuBar(self.dataFrame.PeakMenu)
237    if not self.dataFrame.GetStatusBar():
238        Status = self.dataFrame.CreateStatusBar()
239    self.Bind(wx.EVT_MENU, OnUnDo, id=G2gd.wxID_UNDO)
240    self.Bind(wx.EVT_MENU, OnPeakFit, id=G2gd.wxID_PEAKFIT)
241    self.Bind(wx.EVT_MENU, OnAutoPeakFit, id=G2gd.wxID_AUTOPEAKFIT)
242    self.dataFrame.PeakFit.Enable(False)
243    self.dataFrame.AutoPeakFit.Enable(False)
244    if data:
245        self.dataFrame.PeakFit.Enable(True)
246        self.dataFrame.AutoPeakFit.Enable(True)
247    self.PickTable = []
248    rowLabels = []
249    for i in range(len(data)): rowLabels.append(str(i+1))
250    colLabels = ['position','refine','intensity','refine','sigma','refine','gamma','refine']
251    Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
252        wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
253        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
254        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
255    T = []
256    for peak in data:
257        T.append(peak[0])
258    D = dict(zip(T,data))
259    T.sort()
260    X = []
261    for key in T: X.append(D[key])
262    data = X       
263    self.PatternTree.SetItemPyData(self.PickId,data)
264    self.PeakTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
265    self.dataFrame.SetLabel('Peak List')
266    self.dataDisplay = G2gd.GSGrid(parent=self.dataFrame)
267    self.dataDisplay.SetTable(self.PeakTable, True)
268    setBackgroundColors()                         
269    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshPeakGrid)
270    self.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
271    self.dataDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)                 
272    self.dataDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefineSelect)
273    self.dataDisplay.SetMargins(0,0)
274    self.dataDisplay.AutoSizeColumns(False)
275    self.dataFrame.setSizePosLeft([535,350])
276       
277def UpdateBackgroundGrid(self,data):
278    if self.dataDisplay:
279        self.dataFrame.Clear()
280    BackId = G2gd.GetPatternTreeItemId(self,self.PatternId, 'Background')
281    maxTerm = 9
282    Types = [wg.GRID_VALUE_CHOICE+':chebyschev,another,more',
283        wg.GRID_VALUE_BOOL,
284        wg.GRID_VALUE_NUMBER+':1,'+str(maxTerm)]
285    for i in range(maxTerm):
286        Types.append(wg.GRID_VALUE_FLOAT+':10,3')
287   
288    def RefreshBackgroundGrid(event):
289        data = self.BackTable.GetData()
290        M = len(data[0])
291        N = data[0][2]+3
292        item = data[0]
293        if N > M:       #add terms
294            for i in range(M,N): 
295                item.append(0.0)
296                self.BackTable.SetColLabelValue(i,str(i-2))
297            data = [item]
298            msg = wg.GridTableMessage(self.BackTable, 
299                wg.GRIDTABLE_NOTIFY_COLS_APPENDED,0,N-M)
300            self.dataDisplay.ProcessTableMessage(msg)                         
301        elif N < M:     #delete terms
302            new = []
303            for i in range(N):
304                new.append(item[i])
305            data = [new]
306            msg = wg.GridTableMessage(self.BackTable, 
307                wg.GRIDTABLE_NOTIFY_COLS_DELETED,0,M-N)
308            self.dataDisplay.ProcessTableMessage(msg)
309        self.PatternTree.SetItemPyData(BackId,data)
310        event.StopPropagation()
311                 
312    self.BackTable = []
313    N = len(data[0])
314    M = data[0][2]
315    colLabels = ['function','refine','Nterms']
316    rowLabels=['background']
317    for i in range(M): colLabels.append(str(i+1))
318    self.BackTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
319    self.dataFrame.SetLabel('Background')
320    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
321    gridPanel = wx.Panel(self.dataFrame)
322    self.dataDisplay = G2gd.GSGrid(gridPanel)               
323    self.dataDisplay.SetTable(self.BackTable, True)
324    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshBackgroundGrid)               
325    self.dataDisplay.SetMargins(0,0)
326    self.dataDisplay.AutoSizeColumns(False)
327    mainSizer = wx.BoxSizer(wx.VERTICAL)
328    mainSizer.Add(self.dataDisplay,0)
329    mainSizer.Layout()   
330    self.dataDisplay.SetSizer(mainSizer)
331    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
332       
333def UpdateLimitsGrid(self, data):
334    if self.dataDisplay:
335        self.dataFrame.Clear()
336       
337    def RefreshLimitsGrid(event):
338        event.StopPropagation()
339        data = self.LimitsTable.GetData()
340        old = data[0]
341        new = data[1]
342        new[0] = max(old[0],new[0])
343        new[1] = max(new[0],min(old[1],new[1]))
344        data = [old,new]
345        G2plt.PlotPatterns(self)
346       
347    self.LimitsTable = []
348    colLabels = ['Tmin','Tmax']
349    rowLabels = ['original','changed']
350    Types = [wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3']
351    self.LimitsTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
352    self.dataFrame.SetLabel('Limits')
353    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
354    self.dataDisplay = G2gd.GSGrid(parent=self.dataFrame)
355    self.dataDisplay.SetTable(self.LimitsTable, True)
356    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshLimitsGrid)               
357    self.dataDisplay.SetMargins(0,0)
358    self.dataDisplay.AutoSizeColumns(False)
359    self.dataFrame.setSizePosLeft([230,120])
360   
361def UpdateInstrumentGrid(self, data):
362    if self.dataDisplay:
363        self.dataFrame.Clear()
364    Ka2 = False
365    if len(data[0]) == 13: 
366        Ka2 = True
367    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
368   
369    def RefreshInstrumentGrid(event,doAnyway=False):
370        if doAnyway or event.GetRow() == 1:
371            peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,self.PatternId, 'Peak List'))
372            ins = data[1]
373            if 'P' in ins[0]:                                       #update powder peak parameters
374                for peak in peaks:
375                    if Ka2:
376                        peak[4] = ins[6]*tand(peak[0]/2.0)**2+ins[7]*tand(peak[0]/2.0)+ins[8]
377                        peak[6] = ins[9]/cosd(peak[0]/2.0)+ins[10]*tand(peak[0]/2.0)
378                    else:
379                        peak[4] = ins[4]*tand(peak[0]/2.0)**2+ins[5]*tand(peak[0]/2.0)+ins[6]
380                        peak[6] = ins[7]/cosd(peak[0]/2.0)+ins[8]*tand(peak[0]/2.0)
381                       
382    def OnReset(event):
383        if Ka2:
384            data[1][6:12] = data[0][6:12]
385        else:
386            data[1][4:10] = data[0][4:10]
387        RefreshInstrumentGrid(event,doAnyway=True)          #to get peaks updated
388        UpdateInstrumentGrid(self, data)
389       
390    self.InstrumentTable = []
391    if 'P' in data[1][0]:                   #powder data
392        self.dataFrame.SetMenuBar(self.dataFrame.InstMenu)
393        if not self.dataFrame.GetStatusBar():
394            Status = self.dataFrame.CreateStatusBar()
395        self.Bind(wx.EVT_MENU, OnReset, id=G2gd.wxID_INSTPRMRESET)
396        if Ka2:
397            Types = [wg.GRID_VALUE_CHOICE+":PXC,PNC,PNT",wg.GRID_VALUE_FLOAT+':10,6',wg.GRID_VALUE_FLOAT+':10,6',               #type, lam-1 & lam-2
398                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3', #zero, ratio, pola
399                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3', #u,v,w
400                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,2']
401        else:
402            Types = [wg.GRID_VALUE_CHOICE+":PXC,PNC,PNT",wg.GRID_VALUE_FLOAT+':10,6',               #type & lam-1
403                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3', #zero, pola
404                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3', #u,v,w
405                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,2']
406        colLabels = data[3]
407        rowLabels = ['default','changed','refine']
408        self.InstrumentTable = G2gd.Table(data[:-1],rowLabels=rowLabels,colLabels=colLabels,types=Types)
409        self.dataFrame.SetLabel('Instrument Parameters')
410        gridPanel = wx.Panel(self.dataFrame)
411        self.dataDisplay = G2gd.GSGrid(gridPanel)               
412        self.dataDisplay.SetTable(self.InstrumentTable, True)
413        self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshInstrumentGrid)               
414        self.dataDisplay.SetMargins(0,0)
415        self.dataDisplay.AutoSizeColumns(False)
416        beg = 4
417        if Ka2: beg = 6
418        for i in range(len(data[2])):
419            if i < beg or i == beg+6:
420                self.dataDisplay.SetCellRenderer(2,i,wg.GridCellStringRenderer())
421                self.dataDisplay.SetCellValue(2,i,'')
422                self.dataDisplay.SetReadOnly(2,i,isReadOnly=True)
423            else:
424                self.dataDisplay.SetCellRenderer(2,i,wg.GridCellBoolRenderer())
425                self.dataDisplay.SetCellEditor(2,i,wg.GridCellBoolEditor())
426    else:                       #single crystal data
427        Types = [wg.GRID_VALUE_CHOICE+":SXC,SNC,SNT",wg.GRID_VALUE_FLOAT+':10,6']
428        colLabels = data[2]
429        rowLabels = ['original','changed']
430        self.InstrumentTable = G2gd.Table(data[:-1],rowLabels=rowLabels,colLabels=colLabels,types=Types)
431        self.dataFrame.SetLabel('Instrument Parameters')
432        gridPanel = wx.Panel(self.dataFrame)
433        self.dataDisplay = G2gd.GSGrid(gridPanel)               
434        self.dataDisplay.SetTable(self.InstrumentTable, True)
435        self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshInstrumentGrid)               
436        self.dataDisplay.SetMargins(0,0)
437        self.dataDisplay.AutoSizeColumns(False)
438    mainSizer = wx.BoxSizer(wx.VERTICAL)
439    mainSizer.Add(self.dataDisplay,0)
440    mainSizer.Layout()   
441    self.dataDisplay.SetSizer(mainSizer)
442    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
443   
444def UpdateSampleGrid(self,data):
445    if self.dataDisplay:
446        self.dataFrame.Clear()
447    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
448    if not self.dataFrame.GetStatusBar():
449        Status = self.dataFrame.CreateStatusBar()   
450    self.dataDisplay = wx.Panel(self.dataFrame)
451   
452    if data['Type'] == 'Debye-Scherrer':
453        parms = [['DisplaceX',' Sample X displacement: ','%.4f',],
454            ['DisplaceY',' Sample Y displacement: ','%.4f',],
455            ['Absorption',' Sample absorption: ','%.4f',],]
456    elif data['Type'] == 'Bragg-Brentano':
457        parms = [['Shift',' Sample displacement: ','%.4f',],
458            ['Transparency',' Sample transparency: ','%.4f'],]
459    parms.append(['Temperature',' Sample temperature: ','%.2f'])
460    parms.append(['Pressure',' Sample pressure: ','%.3f'])
461    parms.append(['Humidity',' Sample humidity: ','%.1f'])
462    parms.append(['Voltage',' Sample voltage: ','%.3f'])
463    parms.append(['Force',' Applied load: ','%.3f'])
464    objList = {}
465
466    def OnScaleRef(event):
467        Obj = event.GetEventObject()
468        data['Scale'][1] = Obj.GetValue()
469       
470    def OnScaleVal(event):
471        Obj = event.GetEventObject()
472        try:
473            scale = float(Obj.GetValue())
474            if scale > 0:
475                data['Scale'][0] = scale
476        except ValueError:
477            pass
478        Obj.SetValue("%.4f"%(data['Scale'][0]))          #reset in case of error
479       
480    def OnHistoType(event):
481        Obj = event.GetEventObject()
482        data['Type'] = Obj.GetValue()
483        if data['Type'] == 'Bragg-Brentano' and 'Shift' not in data:    #set up defaults for new type(s)
484            data['Shift'] = [0.0,False]
485            data['Transparency'] = [0.0,False]
486        self.dataDisplay.Destroy()
487        UpdateSampleGrid(self,data)
488       
489    def OnParmRef(event):
490        Obj = event.GetEventObject()
491        parm = objList[Obj.GetId()]
492        data[parm][1] = Obj.GetValue()
493       
494    def OnParmVal(event):
495        Obj = event.GetEventObject()
496        parm = objList[Obj.GetId()]
497        try:
498            if 'list' in str(type(data[parm[0]])): 
499                data[parm[0]][0] = float(Obj.GetValue())
500            else:
501                data[parm[0]] = float(Obj.GetValue())
502        except ValueError:
503            pass
504        if 'list' in str(type(data[parm[0]])): 
505            Obj.SetValue(parm[2]%(data[parm[0]][0]))          #reset in case of error
506        else:
507            Obj.SetValue(parm[2]%(data[parm[0]]))          #reset in case of error
508               
509    mainSizer = wx.BoxSizer(wx.VERTICAL)
510    mainSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Sample parameters: '),0,wx.ALIGN_CENTER_VERTICAL)
511    mainSizer.Add((5,5),0)
512    scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
513    scaleRef = wx.CheckBox(self.dataDisplay,label=' Histogram scale factor: ')
514    scaleRef.SetValue(data['Scale'][1])
515    scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
516    scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
517    scaleVal = wx.TextCtrl(self.dataDisplay,wx.ID_ANY,
518        '%.4f'%(data['Scale'][0]),style=wx.TE_PROCESS_ENTER)
519    scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
520    scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
521    scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
522    mainSizer.Add(scaleSizer)
523    mainSizer.Add((0,5),0)
524    typeSizer = wx.BoxSizer(wx.HORIZONTAL)
525    choices = ['Debye-Scherrer','Bragg-Brentano',]
526    histoType = wx.ComboBox(self.dataDisplay,wx.ID_ANY,value=data['Type'],choices=choices,
527        style=wx.CB_READONLY|wx.CB_DROPDOWN)
528    histoType.Bind(wx.EVT_COMBOBOX, OnHistoType)
529    typeSizer.Add(histoType)
530    mainSizer.Add(typeSizer)
531    mainSizer.Add((0,5),0)
532   
533    for parm in parms:
534        parmSizer = wx.BoxSizer(wx.HORIZONTAL)
535        if 'list' in str(type(data[parm[0]])):
536            parmRef = wx.CheckBox(self.dataDisplay,label=parm[1])
537            objList[parmRef.GetId()] = parm[0]
538            parmRef.SetValue(data[parm[0]][1])
539            parmRef.Bind(wx.EVT_CHECKBOX, OnParmRef)
540            parmSizer.Add(parmRef,0,wx.ALIGN_CENTER_VERTICAL)
541            parmVal = wx.TextCtrl(self.dataDisplay,wx.ID_ANY,
542                parm[2]%(data[parm[0]][0]),style=wx.TE_PROCESS_ENTER)
543        else:
544            parmSizer.Add(wx.StaticText(self.dataDisplay,label=parm[1]),
545                0,wx.ALIGN_CENTER_VERTICAL)
546            parmVal = wx.TextCtrl(self.dataDisplay,wx.ID_ANY,
547                parm[2]%(data[parm[0]]),style=wx.TE_PROCESS_ENTER)       
548        objList[parmVal.GetId()] = parm
549        parmVal.Bind(wx.EVT_TEXT_ENTER,OnParmVal)
550        parmVal.Bind(wx.EVT_KILL_FOCUS,OnParmVal)
551        parmSizer.Add(parmVal,0,wx.ALIGN_CENTER_VERTICAL)
552        mainSizer.Add(parmSizer)
553        mainSizer.Add((0,5),0)   
554   
555    mainSizer.Layout()   
556    self.dataDisplay.SetSizer(mainSizer)
557    Size = mainSizer.Fit(self.dataFrame)
558    self.dataDisplay.SetSize(Size)
559    self.dataFrame.setSizePosLeft(Size)
560               
561def UpdateIndexPeaksGrid(self, data):
562    IndexId = G2gd.GetPatternTreeItemId(self,self.PatternId, 'Index Peak List')
563   
564    def RefreshIndexPeaksGrid(event):
565        data = self.IndexPeaksTable.GetData()
566        self.PatternTree.SetItemPyData(IndexId,data)
567       
568    def OnReload(event):
569        data = []
570        peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,self.PatternId, 'Peak List'))
571        for peak in peaks:
572            dsp = inst[1]/(2.0*sind(peak[0]/2.0))
573            data.append([peak[0],peak[2],True,False,0,0,0,dsp,0.0])
574        self.PatternTree.SetItemPyData(IndexId,data)
575        UpdateIndexPeaksGrid(self,data)
576       
577    def KeyEditPickGrid(event):
578        colList = self.dataDisplay.GetSelectedCols()
579        rowList = self.dataDisplay.GetSelectedRows()
580        data = self.PatternTree.GetItemPyData(IndexId)
581        if event.GetKeyCode() == wx.WXK_RETURN:
582            event.Skip(True)
583        elif event.GetKeyCode() == wx.WXK_CONTROL:
584            event.Skip(True)
585        elif event.GetKeyCode() == wx.WXK_SHIFT:
586            event.Skip(True)
587        elif colList:
588            self.dataDisplay.ClearSelection()
589            key = event.GetKeyCode()
590            for col in colList:
591                if self.IndexPeaksTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
592                    if key == 89: #'Y'
593                        for row in range(self.IndexPeaksTable.GetNumberRows()): data[row][col]=True
594                    elif key == 78:  #'N'
595                        for row in range(self.IndexPeaksTable.GetNumberRows()): data[row][col]=False
596           
597    if self.dataDisplay:
598        self.dataFrame.Clear()
599    self.dataFrame.SetMenuBar(self.dataFrame.IndPeaksMenu)
600    if not self.dataFrame.GetStatusBar():
601        Status = self.dataFrame.CreateStatusBar()
602    self.Bind(wx.EVT_MENU, OnReload, id=G2gd.wxID_INDXRELOAD)
603    inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,self.PatternId, 'Instrument Parameters'))[1]
604    self.dataFrame.IndexPeaks.Enable(False)
605    self.IndexPeaksTable = []
606    if data:
607        self.dataFrame.IndexPeaks.Enable(True)
608        cells = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,self.PatternId, 'Unit Cells List'))
609        if cells:
610            cellist = cells[2]
611            dmin = cells[3]
612            self.HKL = []
613            for i,cell in enumerate(cellist):
614                if cell[-1]:
615                    ibrav = cell[2]
616                    A = G2lat.cell2A(cell[3:9])
617                    self.HKL = G2lat.GenHBravais(dmin,ibrav,A)
618                    G2indx.IndexPeaks(data,self.HKL)
619                    for hkl in self.HKL:
620                        hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))             
621    rowLabels = []
622    for i in range(len(data)): rowLabels.append(str(i+1))
623    colLabels = ['position','intensity','use','indexed','h','k','l','d-obs','d-calc']
624    Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
625        wg.GRID_VALUE_BOOL,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,
626        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5']
627    self.PatternTree.SetItemPyData(IndexId,data)
628    self.IndexPeaksTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
629    self.dataFrame.SetLabel('Index Peak List')
630    self.dataDisplay = G2gd.GSGrid(parent=self.dataFrame)               
631    self.dataDisplay.SetTable(self.IndexPeaksTable, True)
632    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshIndexPeaksGrid)
633    self.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPickGrid)                 
634    self.dataDisplay.SetMargins(0,0)
635    self.dataDisplay.AutoSizeColumns(False)
636    self.dataFrame.setSizePosLeft([490,300])
637 
638def UpdateUnitCellsGrid(self, data):
639    UnitCellsId = G2gd.GetPatternTreeItemId(self,self.PatternId, 'Unit Cells List')
640    bravaisSymb = ['Fm3m','Im3m','Pm3m','R3-H','P6/mmm','I4/mmm',
641        'P4/mmm','Fmmm','Immm','Cmmm','Pmmm','C2/m','P2/m','P1']
642    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',
643        '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']
644       
645    def SetLattice(controls):
646        ibrav = bravaisSymb.index(controls[5])
647        if ibrav in [0,1,2]:
648            controls[7] = controls[8] = controls[6]
649            controls[9] = controls[10] = controls[11] = 90.
650        elif ibrav in [3,4,5,6]:
651            controls[7] = controls[6]
652            controls[9] = controls[10] = controls[11] = 90.
653            if ibrav in [3,4]:
654                controls[11] = 120.
655        elif ibrav in [7,8,9,10]:
656            controls[9] = controls[10] = controls[11] = 90.
657        elif ibrav in [11,12]:
658            controls[9] = controls[11] = 90.  # b unique
659        if len(controls) < 13: controls.append(0)
660        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
661        return ibrav
662       
663    def OnNcNo(event):
664        controls[2] = NcNo.GetValue()
665       
666    def OnStartVol(event):
667        try:
668            stVol = int(startVol.GetValue())
669        except ValueError:
670            stVol = 25
671        controls[3] = stVol
672        startVol.SetValue("%d"%(stVol))
673       
674    def OnBravais(event):
675        Obj = event.GetEventObject()
676        bravais[bravList.index(Obj.GetId())] = Obj.GetValue()
677       
678    def OnZero(event):
679        try:
680            Zero = min(0.1,max(-0.1,float(zero.GetValue())))
681        except ValueError:
682            Zero = 0.1
683        controls[1] = Zero
684        zero.SetValue("%.2f"%(Zero))
685       
686    def OnZeroVar(event):
687        controls[0] = zeroVar.GetValue()
688       
689    def OnBravSel(event):
690        controls[5] = bravSel.GetString(bravSel.GetSelection())       
691        UpdateUnitCellsGrid(self,data)
692       
693    def OnCellChange(event):
694        ibrav = bravaisSymb.index(controls[5])
695        Obj = event.GetEventObject()
696        ObjId = cellList.index(Obj.GetId())
697        try:
698            value = max(1.0,float(Obj.GetValue()))
699        except ValueError:
700            if ObjId < 3:               #bad cell edge - reset
701                value = controls[6+ObjId]
702            else:                       #bad angle
703                value = 90.
704        if ibrav in [0,1,2]:
705            controls[6] = controls[7] = controls[8] = value
706            controls[9] = controls[10] = controls[11] = 90.0
707            Obj.SetValue("%.5f"%(controls[6]))
708        elif ibrav in [3,4,5,6]:
709            if ObjId == 0:
710                controls[6] = controls[7] = value
711                Obj.SetValue("%.5f"%(controls[6]))
712            else:
713                controls[8] = value
714                Obj.SetValue("%.5f"%(controls[8]))
715            controls[9] = controls[10] = controls[11] = 90.0
716            if ibrav in [3,4]:
717                controls[11] = 120.
718        elif ibrav in [7,8,9,10]:
719            controls[6+ObjId] = value
720            Obj.SetValue("%.5f"%(controls[6+ObjId]))
721            controls[9] = controls[10] = controls[11] = 90.0
722        elif ibrav in [11,12]:
723            controls[9] = controls[11] = 90.0
724            if ObjId != 3:
725                controls[6+ObjId] = value
726                Obj.SetValue("%.5f"%(controls[6+ObjId]))
727            else:
728                controls[10] = value
729                Obj.SetValue("%.3f"%(controls[10]))
730        else:
731            controls[6+ObjId] = value
732            if ObjId < 3:
733                Obj.SetValue("%.5f"%(controls[6+ObjId]))
734            else:
735                Obj.SetValue("%.3f"%(controls[6+ObjId]))
736        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
737        volVal.SetValue("%.3f"%(controls[12]))
738       
739    def OnHklShow(event):
740        hklShow.SetValue(False)
741        PatternId = self.PatternId
742        PickId = self.PickId   
743        limits = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Limits'))[1]
744        controls,bravais,cells,dmin = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Unit Cells List'))
745        cell = controls[6:12]
746        A = G2lat.cell2A(cell)
747        ibrav = bravaisSymb.index(controls[5])
748        inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))
749        inst = dict(zip(inst[3],inst[1]))
750        if 'Lam' in inst:
751            wave = inst['Lam']
752        else:
753            wave = inst['Lam1']
754        dmin = wave/(2.0*sind(limits[1]/2.0))
755        self.HKL = G2lat.GenHBravais(dmin,ibrav,A)
756        for hkl in self.HKL:
757            hkl.append(2.0*asind(wave/(2.*hkl[3])))             
758        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
759            G2plt.PlotPowderLines(self)
760        else:
761            G2plt.PlotPatterns(self)
762       
763       
764    def RefineCell(event):
765        def cellPrint(ibrav,A):
766            cell = G2lat.A2cell(A)
767            Vol = G2lat.calc_V(A)
768            if ibrav in [0,1,2]:
769                print "%s%10.6f" % ('a =',cell[0])
770            elif ibrav in [3,4,5,6]:
771                print "%s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],' c =',cell[2],' volume =',Vol)
772            elif ibrav in [7,8,9,10]:
773                print "%s%10.6f %s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2],' volume =',Vol)
774            elif ibrav in [11,12]:
775                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)
776            else:
777                print "%s%10.6f %s%10.6f %s%10.6f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2])
778                print "%s%8.3f %s%8.3f %s%8.3f %s%12.3f" % ('alpha =',cell[3],'beta =',cell[4],'gamma =',cell[5],' volume =',Vol)
779             
780        PatternId = self.PatternId
781        PickId = self.PickId   
782        peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Index Peak List'))
783        if not peaks:
784            self.ErrorDialog('No peaks!', 'Nothing to refine!')
785            return       
786        print 'Refine cell'
787        inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))[1]
788        controls,bravais,cells,dmin = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Unit Cells List'))
789        cell = controls[6:12]
790        A = G2lat.cell2A(cell)
791        print controls[5]
792        ibrav = bravaisSymb.index(controls[5])
793        dmin = G2indx.getDmin(peaks)-0.005
794        Lhkl,M20,X20 = G2indx.refinePeaks(peaks,ibrav,A)
795        controls[6:12] = G2lat.A2cell(A)
796        controls[12] = G2lat.calc_V(A)
797        data = [controls,bravais,cells,dmin]
798        self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Unit Cells List'),data)
799        self.HKL = G2lat.GenHBravais(dmin,ibrav,A)
800        UpdateUnitCellsGrid(self,data)
801        print "%s%10.3f" % ('refinement M20 = ',M20)
802        print 'unindexed lines = ',X20
803        cellPrint(ibrav,A)
804        for hkl in self.HKL:
805            hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))             
806        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
807            G2plt.PlotPowderLines(self)
808        else:
809            G2plt.PlotPatterns(self)
810       
811    def IndexPeaks(event):
812        PatternId = self.PatternId   
813#        peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Index Peak List'))
814#        if not peaks:
815#            self.ErrorDialog('No peaks!', 'Nothing to index!')
816#            return
817        inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))[1]
818        print 'Peak Indexing'
819        try:
820            controls,bravais,cells,dmin = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Unit Cells List'))
821            cells = []
822        except ValueError:
823            self.ErrorDialog('Error','Need to set controls in Unit Cell List first')
824            return
825        if True not in bravais:
826            self.ErrorDialog('Error','No Bravais lattices selected')
827            return
828        self.dataFrame.CopyCell.Enable(False)
829        OK,dmin,cells = G2indx.DoIndexPeaks(peaks,inst,controls,bravais)
830        if OK:
831            data = [controls,bravais,cells,dmin]
832            self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Unit Cells List'),data)
833            UpdateUnitCellsGrid(self,data)
834            bestCell = cells[0]
835            if bestCell[0] > 10.:
836                self.HKL = G2lat.GenHBravais(dmin,bestCell[2],G2lat.cell2A(bestCell[3:9]))
837                for hkl in self.HKL:
838                    hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))             
839                if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
840                    G2plt.PlotPowderLines(self)
841                else:
842                    G2plt.PlotPatterns(self)
843        self.dataFrame.CopyCell.Enable(True)
844        self.dataFrame.IndexPeaks.Enable(True)
845        self.dataFrame.MakeNewPhase.Enable(True)
846        UpdateUnitCellsGrid(self,data)
847               
848    def CopyUnitCell(event):
849        controls,bravais,cells,dmin = self.PatternTree.GetItemPyData(UnitCellsId)
850        for Cell in cells:
851            if Cell[-1]:
852                break
853        cell = Cell[2:9]
854        controls[4] = 1
855        controls[5] = bravaisSymb[cell[0]]
856        controls[6:12] = cell[1:8]
857        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
858        self.PatternTree.SetItemPyData(UnitCellsId,[controls,bravais,cells,dmin])
859        UpdateUnitCellsGrid(self,data)
860        self.dataFrame.RefineCell.Enable(True)
861       
862    def MakeNewPhase(event):
863        if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
864            sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
865        else:
866            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
867        PhaseName = ''
868        dlg = wx.TextEntryDialog(None,'Enter a name for this phase','Phase Name Entry','New phase',
869            style=wx.OK)
870        if dlg.ShowModal() == wx.ID_OK:
871            PhaseName = dlg.GetValue()
872        dlg.Destroy()
873        cells = self.PatternTree.GetItemPyData(UnitCellsId)[2]
874        for Cell in cells:
875            if Cell[-1]:
876                break
877        cell = Cell[2:10]       
878        sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
879        E,SGData = G2spc.SpcGroup(spaceGroups[cell[0]])
880        self.PatternTree.SetItemPyData(sub, \
881            {'General':{'Name':'phase name','Type':'nuclear','SGData':SGData,
882            'Cell':[False,]+cell[1:],
883            'Pawley dmin':0.25},'Atoms':[],'Drawing':{},'Histograms':{}})
884        Status.SetStatusText('Change space group if needed')
885           
886    def RefreshUnitCellsGrid(event):
887        cells,dmin = self.PatternTree.GetItemPyData(UnitCellsId)[2:]
888        r,c =  event.GetRow(),event.GetCol()
889        if cells:
890            if c == 2:
891                for i in range(len(cells)):
892                    cells[i][-1] = False
893                    UnitCellsTable.SetValue(i,c,False)
894                UnitCellsTable.SetValue(r,c,True)
895                cells[r][-1] = True
896                ibrav = cells[r][2]
897                A = G2lat.cell2A(cells[r][3:9])
898                self.HKL = G2lat.GenHBravais(dmin,ibrav,A)
899                for hkl in self.HKL:
900                    hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))
901                if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
902                    G2plt.PlotPowderLines(self)
903                else:
904                    G2plt.PlotPatterns(self)
905       
906    if self.dataDisplay:
907        self.dataFrame.Clear()
908    self.dataFrame.SetMenuBar(self.dataFrame.IndexMenu)
909    if not self.dataFrame.GetStatusBar():
910        Status = self.dataFrame.CreateStatusBar()
911    self.Bind(wx.EVT_MENU, IndexPeaks, id=G2gd.wxID_INDEXPEAKS)
912    self.Bind(wx.EVT_MENU, CopyUnitCell, id=G2gd.wxID_COPYCELL)
913    self.Bind(wx.EVT_MENU, RefineCell, id=G2gd.wxID_REFINECELL)
914    self.Bind(wx.EVT_MENU, MakeNewPhase, id=G2gd.wxID_MAKENEWPHASE)
915   
916    controls,bravais,cells,dmin = data
917    if len(controls) < 13:              #add cell volume if missing
918        controls.append(G2lat.calc_V(G2lat.cell2A(controls[6:12])))
919    self.PatternTree.SetItemPyData(UnitCellsId,data)            #update with volume
920    inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,self.PatternId, 'Instrument Parameters'))[1]
921    bravaisNames = ['Cubic-F','Cubic-I','Cubic-P','Trigonal-R','Trigonal/Hexagonal-P',
922        'Tetragonal-I','Tetragonal-P','Orthorhombic-F','Orthorhombic-I','Orthorhombic-C',
923        'Orthorhombic-P','Monoclinic-C','Monoclinic-P','Triclinic']
924    cellGUIlist = [[[0,1,2],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
925    [[3,4,5,6],6,zip([" Unit cell: a = "," c = "," Vol = "],["%.5f","%.5f","%.3f"],[True,True,False],[0,2,0])],
926    [[7,8,9,10],8,zip([" Unit cell: a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
927        [True,True,True,False],[0,1,2,0])],
928    [[11,12],10,zip([" Unit cell: a = "," b = "," c = "," beta = "," Vol = "],
929        ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
930    [[13,],8,zip([" Unit cell: a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
931        ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
932        [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
933   
934    self.dataFrame.SetLabel('Unit Cells List')
935    self.sp = wx.SplitterWindow(self.dataFrame)
936    self.dataDisplay = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)
937    self.dataFrame.IndexPeaks.Enable(False)
938    peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,self.PatternId, 'Index Peak List'))
939    if peaks:
940        self.dataFrame.IndexPeaks.Enable(True)
941    self.dataFrame.RefineCell.Enable(False)
942    if controls[12] > 1.0:                               #if a "real" volume (i.e. not default)
943        self.dataFrame.RefineCell.Enable(True)   
944    self.dataFrame.CopyCell.Enable(False)
945    self.dataFrame.MakeNewPhase.Enable(False)       
946    if cells:
947        self.bottom = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)
948        self.sp.SplitHorizontally(self.dataDisplay,self.bottom,0)
949        self.dataFrame.CopyCell.Enable(True)
950        self.dataFrame.MakeNewPhase.Enable(True)       
951    mainSizer = wx.BoxSizer(wx.VERTICAL)
952    mainSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Indexing controls: '),0,wx.ALIGN_CENTER_VERTICAL)
953    mainSizer.Add((5,5),0)
954    littleSizer = wx.FlexGridSizer(2,5,5,5)
955    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Max Nc/Nobs '),0,wx.ALIGN_CENTER_VERTICAL)
956    NcNo = wx.SpinCtrl(self.dataDisplay)
957    NcNo.SetRange(1,6)
958    NcNo.SetValue(controls[2])
959    NcNo.Bind(wx.EVT_SPINCTRL,OnNcNo)
960    littleSizer.Add(NcNo,0,wx.ALIGN_CENTER_VERTICAL)
961    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Start Volume '),0,wx.ALIGN_CENTER_VERTICAL)
962    startVol = wx.TextCtrl(self.dataDisplay,value=str(controls[3]),style=wx.TE_PROCESS_ENTER)
963    startVol.Bind(wx.EVT_TEXT_ENTER,OnStartVol)
964    startVol.Bind(wx.EVT_KILL_FOCUS,OnStartVol)
965    littleSizer.Add(startVol,0,wx.ALIGN_CENTER_VERTICAL)
966    mainSizer.Add(littleSizer,0)
967    mainSizer.Add((5,5),0)
968    mainSizer.Add(wx.StaticText(self.dataDisplay,label=' Select Bravais Lattices for indexing: '),
969        0,wx.ALIGN_CENTER_VERTICAL)
970    mainSizer.Add((5,5),0)
971    littleSizer = wx.FlexGridSizer(2,7,5,5)
972    bravList = []
973    bravs = zip(bravais,bravaisNames)
974    for brav,bravName in bravs:
975        bravCk = wx.CheckBox(self.dataDisplay,label=bravName)
976        bravList.append(bravCk.GetId())
977        bravCk.SetValue(brav)
978        bravCk.Bind(wx.EVT_CHECKBOX,OnBravais)
979        littleSizer.Add(bravCk,0,wx.ALIGN_CENTER_VERTICAL)
980    mainSizer.Add(littleSizer,0)
981    mainSizer.Add((5,5),0)
982    littleSizer = wx.FlexGridSizer(1,3,5,5)
983    littleSizer.Add(wx.StaticText(self.dataDisplay,label=" Zero offset"),0,wx.ALIGN_CENTER_VERTICAL)
984    zero = wx.TextCtrl(self.dataDisplay,value="%.2f"%(controls[1]),style=wx.TE_PROCESS_ENTER)
985    zero.Bind(wx.EVT_TEXT_ENTER,OnZero)
986    zero.Bind(wx.EVT_KILL_FOCUS,OnZero)
987    littleSizer.Add(zero,0,wx.ALIGN_CENTER_VERTICAL)
988    zeroVar = wx.CheckBox(self.dataDisplay,label="Vary? (not implemented)")
989    zeroVar.Bind(wx.EVT_CHECKBOX,OnZeroVar)
990    littleSizer.Add(zeroVar,0,wx.ALIGN_CENTER_VERTICAL)
991    mainSizer.Add(littleSizer,0)
992    mainSizer.Add((5,5),0)
993    mainSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Cell Refinement: '),0,wx.ALIGN_CENTER_VERTICAL)
994    mainSizer.Add((5,5),0)
995    littleSizer = wx.FlexGridSizer(1,3,5,5)
996    littleSizer.Add(wx.StaticText(self.dataDisplay,label=" Bravais lattice "),0,wx.ALIGN_CENTER_VERTICAL)
997    bravSel = wx.Choice(self.dataDisplay,choices=bravaisSymb)
998    bravSel.SetSelection(bravaisSymb.index(controls[5]))
999    bravSel.Bind(wx.EVT_CHOICE,OnBravSel)
1000    littleSizer.Add(bravSel,0,wx.ALIGN_CENTER_VERTICAL)
1001    hklShow = wx.CheckBox(self.dataDisplay,label="Show starting hkl positions")
1002    hklShow.Bind(wx.EVT_CHECKBOX,OnHklShow)
1003    littleSizer.Add(hklShow,0,wx.ALIGN_CENTER_VERTICAL)
1004    mainSizer.Add(littleSizer,0)
1005    mainSizer.Add((5,5),0)
1006    ibrav = SetLattice(controls)
1007    for cellGUI in cellGUIlist:
1008        if ibrav in cellGUI[0]:
1009            useGUI = cellGUI
1010    cellList = []
1011    littleSizer = wx.FlexGridSizer(2,useGUI[1],5,5)
1012    for txt,fmt,ifEdit,Id in useGUI[2]:
1013        littleSizer.Add(wx.StaticText(self.dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL)
1014        if ifEdit:          #a,b,c,etc.
1015            cellVal = wx.TextCtrl(self.dataDisplay,value=(fmt%(controls[6+Id])),style=wx.TE_PROCESS_ENTER)
1016            cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
1017            cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
1018            littleSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL)
1019            cellList.append(cellVal.GetId())
1020        else:               #volume
1021            volVal = wx.TextCtrl(self.dataDisplay,value=(fmt%(controls[12])),style=wx.TE_READONLY)
1022            volVal.SetBackgroundColour(VERY_LIGHT_GREY)
1023            littleSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL)
1024    mainSizer.Add(littleSizer,0)
1025    mainSizer.Layout()   
1026    self.dataDisplay.SetSizer(mainSizer)
1027    topSize = mainSizer.Fit(self.dataFrame)
1028    self.dataDisplay.SetSize(topSize)
1029    if cells:
1030        if ibrav == 13:
1031            topSize[1] += 230
1032        else:
1033            topSize[1] += 200
1034    self.dataFrame.setSizePosLeft(topSize)
1035   
1036   
1037    if cells:
1038        bottomSize = self.bottom.GetSize()
1039        if ibrav == 13:
1040            bottomSize[1] -= 240
1041        else:
1042            bottomSize[1] -= 210
1043        wx.StaticText(parent=self.bottom,label=' Indexing Result ')
1044        rowLabels = []
1045        colLabels = ['M20','X20','use','Bravais','a','b','c','alpha','beta','gamma','Volume']
1046        Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_NUMBER,wg.GRID_VALUE_BOOL,wg.GRID_VALUE_STRING,
1047            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',
1048            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',
1049            wg.GRID_VALUE_FLOAT+':10,2']
1050        numRows = len(cells)
1051        table = []
1052        for cell in cells:
1053            rowLabels.append('')
1054            row = cell[0:2]+[cell[-1]]+[bravaisSymb[cell[2]]]+cell[3:10]
1055            if cell[-1]:
1056                A = G2lat.cell2A(cell[3:9])
1057                self.HKL = G2lat.GenHBravais(dmin,cell[2],A)
1058                for hkl in self.HKL:
1059                    hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))
1060            table.append(row)
1061        UnitCellsTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1062        gridDisplay = G2gd.GSGrid(self.bottom)
1063        gridDisplay.SetPosition(wx.Point(0,20))               
1064        gridDisplay.SetTable(UnitCellsTable, True)
1065        self.dataFrame.CopyCell.Enable(True)
1066        gridDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshUnitCellsGrid)
1067        gridDisplay.SetMargins(0,0)
1068        gridDisplay.SetRowLabelSize(0)
1069        gridDisplay.AutoSizeColumns(False)
1070        for r in range(gridDisplay.GetNumberRows()):
1071            for c in range(gridDisplay.GetNumberCols()):
1072                if c == 2:
1073                    gridDisplay.SetReadOnly(r,c,isReadOnly=False)
1074                else:
1075                    gridDisplay.SetReadOnly(r,c,isReadOnly=True)
1076        gridDisplay.SetSize(bottomSize)
1077
1078def UpdatePDFGrid(self,data):
1079    global inst
1080    tth2q = lambda t,w:4.0*math.pi*sind(t/2.0)/w
1081    dataFile = self.PatternTree.GetItemText(self.PatternId)
1082    powName = 'PWDR'+dataFile[4:]
1083    powId = G2gd.GetPatternTreeItemId(self,self.root, powName)
1084    fullLimits,limits = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,powId, 'Limits'))
1085    inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,powId, 'Instrument Parameters'))
1086    inst = dict(zip(inst[3],inst[1]))
1087    if 'Lam' in inst:
1088        keV = 12.397639/inst['Lam']
1089    else:
1090        keV = 12.397639/inst['Lam1']
1091    wave = 12.397639/keV
1092    qLimits = [tth2q(fullLimits[0],wave),tth2q(fullLimits[1],wave)]
1093    data['QScaleLim'][0] = max(qLimits[0],data['QScaleLim'][0])
1094    data['QScaleLim'][1] = min(qLimits[1],data['QScaleLim'][1])
1095    polariz = inst['Polariz.']
1096    azimuth = inst['Azimuth']
1097    itemDict = {}
1098   
1099    def FillFileSizer(fileSizer,key):
1100        #fileSizer is a FlexGridSizer(3,6)
1101       
1102        def OnSelectFile(event):
1103            Obj = event.GetEventObject()
1104            fileKey,itemKey,fmt = itemDict[Obj.GetId()]
1105            if itemKey == 'Name':
1106                value = Obj.GetValue()
1107            Obj.SetValue(fmt%(value))
1108            data[fileKey][itemKey] = value
1109            UpdatePDFGrid(self,data)
1110       
1111        def OnValueChange(event):
1112            Obj = event.GetEventObject()
1113            fileKey,itemKey,fmt = itemDict[Obj.GetId()]
1114            try:
1115                value = float(Obj.GetValue())
1116            except ValueError:
1117                value = -1.0
1118            Obj.SetValue(fmt%(value))
1119            data[fileKey][itemKey] = value
1120            auxPlot = ComputePDF(data)
1121            G2plt.PlotISFG(self,newPlot=True)
1122                       
1123        item = data[key]
1124        fileList = np.array(GetFileList('PWDR')).T[1]
1125        fileSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' '+key+' file:'),0,wx.ALIGN_CENTER_VERTICAL)
1126        fileName = wx.ComboBox(self.dataDisplay,value=item['Name'],choices=fileList,
1127            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1128        itemDict[fileName.GetId()] = [key,'Name','%s']
1129        fileName.Bind(wx.EVT_COMBOBOX,OnSelectFile)       
1130        fileSizer.Add(fileName,0,)
1131        fileSizer.Add(wx.StaticText(parent=self.dataDisplay,label='Multiplier:'),0,wx.ALIGN_CENTER_VERTICAL)
1132        mult = wx.TextCtrl(self.dataDisplay,value='%.3f'%(item['Mult']),style=wx.TE_PROCESS_ENTER)
1133        itemDict[mult.GetId()] = [key,'Mult','%.3f']
1134        mult.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
1135        mult.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
1136        fileSizer.Add(mult,0,)
1137        fileSizer.Add(wx.StaticText(parent=self.dataDisplay,label='Add:'),0,wx.ALIGN_CENTER_VERTICAL)
1138        add = wx.TextCtrl(self.dataDisplay,value='%.0f'%(item['Add']),style=wx.TE_PROCESS_ENTER)
1139        itemDict[add.GetId()] = [key,'Add','%.0f']
1140        add.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
1141        add.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
1142        fileSizer.Add(add,0,)
1143       
1144    def SumElementVolumes():
1145        sumVol = 0.
1146        ElList = data['ElList']
1147        for El in ElList:
1148            Avol = (4.*math.pi/3.)*ElList[El]['Drad']**3
1149            sumVol += Avol*ElList[El]['FormulaNo']
1150        return sumVol
1151        auxPlot = ComputePDF(data)
1152        G2plt.PlotISFG(self,newPlot=True)       
1153       
1154    def FillElemSizer(elemSizer,ElData):
1155       
1156        def OnFractionChange(event):
1157            try:
1158                value = max(0.0,float(num.GetValue()))
1159            except ValueError:
1160                value = 0.0
1161            num.SetValue('%.3f'%(value))
1162            ElData['FormulaNo'] = value
1163            data['Form Vol'] = max(10.0,SumElementVolumes())
1164            formVol.SetValue('%.2f'%(data['Form Vol']))
1165            UpdatePDFGrid(self,data)
1166            auxPlot = ComputePDF(data)
1167            G2plt.PlotISFG(self,newPlot=True)       
1168       
1169        elemSizer.Add(wx.StaticText(parent=self.dataDisplay,
1170            label=' Element: '+'%2s'%(ElData['Symbol'])+' * '),0,wx.ALIGN_CENTER_VERTICAL)
1171        num = wx.TextCtrl(self.dataDisplay,value='%.3f'%(ElData['FormulaNo']),style=wx.TE_PROCESS_ENTER)
1172        num.Bind(wx.EVT_TEXT_ENTER,OnFractionChange)       
1173        num.Bind(wx.EVT_KILL_FOCUS,OnFractionChange)
1174        elemSizer.Add(num,0,wx.ALIGN_CENTER_VERTICAL)
1175        elemSizer.Add(wx.StaticText(parent=self.dataDisplay,
1176            label="f': %.3f"%(ElData['fp'])+' f": %.3f'%(ElData['fpp'])+' mu: %.2f barns'%(ElData['mu']) ),
1177            0,wx.ALIGN_CENTER_VERTICAL)
1178           
1179    def OnGeometry(event):
1180        data['Geometry'] = geometry.GetValue()
1181        UpdatePDFGrid(self,data)
1182        auxPlot = ComputePDF(data)
1183        G2plt.PlotISFG(self,newPlot=True)       
1184       
1185    def OnDetType(event):
1186        data['DetType'] = detType.GetValue()
1187        UpdatePDFGrid(self,data)
1188        auxPlot = ComputePDF(data)
1189        G2plt.PlotISFG(self,newPlot=True)       
1190       
1191    def OnFormVol(event):
1192        try:
1193            value = float(formVol.GetValue())
1194            if value <= 0.0:
1195                raise ValueError
1196        except ValueError:
1197            value = data['Form Vol']
1198        data['Form Vol'] = value
1199        UpdatePDFGrid(self,data)
1200        auxPlot = ComputePDF(data)
1201        G2plt.PlotISFG(self,newPlot=False)       
1202       
1203    def OnDiameter(event):
1204        try:
1205            value = float(diam.GetValue())
1206            if value <= 0.0:
1207                raise ValueError
1208        except ValueError:
1209            value = data['Diam']
1210        data['Diam'] = value
1211        UpdatePDFGrid(self,data)
1212        auxPlot = ComputePDF(data)
1213        G2plt.PlotISFG(self,newPlot=False)
1214       
1215    def OnPolaVal(event):
1216        try:
1217            value = float(polaVal.GetValue())
1218            if not (0.0 <= value <= 1.0):
1219                raise ValueError
1220        except ValueError:
1221            value = inst['Polariz.']
1222        inst['Polariz.'] = value
1223        polaVal.SetValue('%.2f'%(inst['Polariz.']))
1224        UpdatePDFGrid(self,data)
1225        auxPlot = ComputePDF(data)
1226        G2plt.PlotISFG(self,newPlot=False)
1227               
1228    def OnAzimVal(event):
1229        try:
1230            value = float(azimVal.GetValue())
1231            if not (0. <= value <= 360.):
1232                raise ValueError
1233        except ValueError:
1234            value = inst['Azimuth']
1235        inst['Azimuth'] = value
1236        azimVal.SetValue('%.1f'%(inst['Azimuth']))
1237        UpdatePDFGrid(self,data)
1238        auxPlot = ComputePDF(data)
1239        G2plt.PlotISFG(self,newPlot=False)
1240                       
1241    def OnObliqCoeff(event):
1242        try:
1243            value = float(obliqCoeff.GetValue())
1244            if value < 0.0:
1245                raise ValueError
1246            elif value > 1.0:
1247                value = 1.0
1248        except ValueError:
1249            value = data['ObliqCoeff']
1250        data['ObliqCoeff'] = value
1251        obliqCoeff.SetValue('%.3f'%(value))
1252        auxPlot = ComputePDF(data)
1253        G2plt.PlotISFG(self,newPlot=False)
1254       
1255    def OnRulandWdt(event):
1256        try:
1257            value = float(rulandWdt.GetValue())
1258            if value <= 0.001:
1259                raise ValueError
1260            elif value > 1.0:
1261                value = 1.0
1262        except ValueError:
1263            value = data['Ruland']
1264        data['Ruland'] = value
1265        rulandWdt.SetValue('%.3f'%(value))
1266        auxPlot = ComputePDF(data)
1267        G2plt.PlotISFG(self,newPlot=False)
1268       
1269    def OnRulSlider(event):
1270        value = int(rulandSldr.GetValue())/1000.
1271        data['Ruland'] = max(0.001,value)
1272        rulandWdt.SetValue('%.3f'%(data['Ruland']))
1273        auxPlot = ComputePDF(data)
1274        G2plt.PlotISFG(self,newPlot=False)
1275       
1276    def OnLorch(event):
1277        data['Lorch'] = lorch.GetValue()
1278        auxPlot = ComputePDF(data)
1279        G2plt.PlotISFG(self,newPlot=False)       
1280                       
1281    def OnPacking(event):
1282        try:
1283            value = float(pack.GetValue())
1284            if value <= 0.0:
1285                raise ValueError
1286        except ValueError:
1287            value = data['Pack']
1288        data['Pack'] = value
1289        UpdatePDFGrid(self,data)
1290        auxPlot = ComputePDF(data)
1291        G2plt.PlotISFG(self,newPlot=False)       
1292               
1293    def OnSQmin(event):
1294        try:
1295            value = float(SQmin.GetValue())
1296            if value < qLimits[0]:
1297                raise ValueError
1298        except ValueError:
1299            value = max(qLimits[0],data['QScaleLim'][0])
1300        data['QScaleLim'][0] = value
1301        SQmin.SetValue('%.1f'%(value))
1302        auxPlot = ComputePDF(data)
1303        G2plt.PlotISFG(self,newPlot=True)       
1304       
1305    def OnSQmax(event):
1306        try:
1307            value = float(SQmax.GetValue())
1308            if value > qLimits[1]:
1309                raise ValueError
1310        except ValueError:
1311            value = min(qLimits[1],data['QScaleLim'][1])
1312        data['QScaleLim'][1] = value
1313        if value < data['QScaleLim'][0]:
1314            data['QScaleLim'][0] = 0.90*value
1315            SQmin.SetValue('%.1f'%(data['QScaleLim'][0]))
1316        SQmax.SetValue('%.1f'%(value))
1317        auxPlot = ComputePDF(data)
1318        G2plt.PlotISFG(self,newPlot=True)
1319       
1320    def OnResetQ(event):
1321        resetQ.SetValue(False)
1322        data['QScaleLim'][1] = qLimits[1]
1323        SQmax.SetValue('%.1f'%(data['QScaleLim'][1]))
1324        data['QScaleLim'][0] = 0.9*qLimits[1]
1325        SQmin.SetValue('%.1f'%(data['QScaleLim'][0]))
1326        auxPlot = ComputePDF(data)
1327        G2plt.PlotISFG(self,newPlot=True)       
1328
1329    def GetFileList(fileType,skip=None):
1330        fileList = [[False,'',0]]
1331        Source = ''
1332        id, cookie = self.PatternTree.GetFirstChild(self.root)
1333        while id:
1334            name = self.PatternTree.GetItemText(id)
1335            if fileType in name:
1336                if id == skip:
1337                    Source = name
1338                else:
1339                    fileList.append([False,name,id])
1340            id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1341        if skip:
1342            return fileList,Source
1343        else:
1344            return fileList
1345       
1346    def OnCopyPDFControls(event):
1347        import copy
1348        TextList,Source = GetFileList('PDF',skip=self.PatternId)
1349        TextList[0] = [False,'All PDF',0]
1350        if len(TextList) == 1:
1351            self.ErrorDialog('Nothing to copy controls to','There must be more than one "PDF" pattern')
1352            return
1353        dlg = self.CopyDialog(self,'Copy PDF controls','Copy controls from '+Source+' to:',TextList)
1354        try:
1355            if dlg.ShowModal() == wx.ID_OK:
1356                result = dlg.GetData()
1357                if result[0][0]:
1358                    result = TextList[1:]
1359                    for item in result: item[0] = True
1360                for i,item in enumerate(result):
1361                    ifcopy,name,id = item
1362                    if ifcopy:
1363                        olddata = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'PDF Controls'))
1364                        sample = olddata['Sample']
1365                        olddata.update(data)
1366                        olddata['Sample'] = sample
1367                        self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'PDF Controls'),olddata)
1368                Status.SetStatusText('PDF controls copied')
1369        finally:
1370            dlg.Destroy()
1371               
1372    def OnSavePDFControls(event):
1373        print 'save PDF controls?'
1374       
1375    def OnLoadPDFControls(event):
1376        print 'Load PDF controls?'
1377       
1378    def OnAddElement(event):
1379        ElList = data['ElList']
1380        PE = G2elem.PickElement(self,oneOnly=True)
1381        if PE.ShowModal() == wx.ID_OK:
1382            El = PE.Elem
1383            if El not in ElList:
1384                ElemSym = El.strip().upper()               
1385                FpMu = G2elem.FPcalc(G2elem.GetXsectionCoeff(ElemSym), keV)
1386                ElData = G2elem.GetFormFactorCoeff(ElemSym)[0]
1387                ElData['FormulaNo'] = 0.0
1388                ElData.update(G2elem.GetAtomInfo(ElemSym))
1389                ElData.update(dict(zip(['fp','fpp','mu'],FpMu)))
1390                ElData.update(G2elem.GetFFC5(El))
1391                data['ElList'][El] = ElData
1392            data['Form Vol'] = max(10.0,SumElementVolumes())
1393        PE.Destroy()
1394        UpdatePDFGrid(self,data)
1395       
1396    def OnDeleteElement(event):
1397        ElList = data['ElList']
1398        choice = ElList.keys()
1399        dlg = G2elem.DeleteElement(self,choice=choice)
1400        if dlg.ShowModal() == wx.ID_OK:
1401            del ElList[dlg.GetDeleteElement()]
1402        dlg.Destroy()
1403        UpdatePDFGrid(self,data)
1404               
1405    def ComputePDF(Data):
1406        xydata = {}
1407        for key in ['Sample','Sample Bkg.','Container','Container Bkg.']:
1408            name = Data[key]['Name']
1409            if name:
1410                xydata[key] = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,self.root,name))
1411                PDFname = name
1412        powName = xydata['Sample'][2]
1413        powId = G2gd.GetPatternTreeItemId(self,self.root,powName)
1414        inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,powId,'Instrument Parameters'))
1415        inst = dict(zip(inst[3],inst[1]))
1416        auxPlot = G2pwd.CalcPDF(data,inst,xydata)
1417        PDFId = G2gd.GetPatternTreeItemId(self,self.root,'PDF '+powName[4:])
1418        self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,PDFId,'I(Q)'+powName[4:]),xydata['IofQ'])
1419        self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,PDFId,'S(Q)'+powName[4:]),xydata['SofQ'])
1420        self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,PDFId,'F(Q)'+powName[4:]),xydata['FofQ'])
1421        self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,PDFId,'G(R)'+powName[4:]),xydata['GofR'])
1422        return auxPlot
1423       
1424    def OnComputePDF(event):
1425        print 'Calculating PDF:'
1426        auxPlot = ComputePDF(data)
1427        Status.SetStatusText('PDF computed')
1428        for plot in auxPlot:
1429            G2plt.PlotXY(self,plot[:2],type=plot[2])
1430       
1431        G2plt.PlotISFG(self,newPlot=True,type='I(Q)')
1432        G2plt.PlotISFG(self,newPlot=True,type='S(Q)')
1433        G2plt.PlotISFG(self,newPlot=True,type='F(Q)')
1434        G2plt.PlotISFG(self,newPlot=True,type='G(R)')
1435       
1436    def OnComputeAllPDF(event):
1437        print 'Calculating PDFs:'
1438        if self.PatternTree.GetCount():
1439            id, cookie = self.PatternTree.GetFirstChild(self.root)
1440            while id:
1441                Name = self.PatternTree.GetItemText(id)
1442                if 'PDF' in Name:
1443                    Data = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,id,'PDF Controls'))
1444                    auxPlot = ComputePDF(Data)                   
1445                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1446            Status.SetStatusText('All PDFs computed')
1447            G2plt.PlotISFG(self,newPlot=True,type='G(R)')
1448       
1449    def OnShowTip(self,tip):
1450        print tip   
1451               
1452    if self.dataDisplay:
1453        self.dataFrame.Clear()
1454    self.dataFrame.SetMenuBar(self.dataFrame.PDFMenu)
1455    if not self.dataFrame.GetStatusBar():
1456        Status = self.dataFrame.CreateStatusBar()   
1457    self.dataDisplay = wx.Panel(self.dataFrame)
1458    self.dataFrame.Bind(wx.EVT_MENU, OnCopyPDFControls, id=G2gd.wxID_PDFCOPYCONTROLS)
1459    self.dataFrame.Bind(wx.EVT_MENU, OnSavePDFControls, id=G2gd.wxID_PDFSAVECONTROLS)
1460    self.dataFrame.Bind(wx.EVT_MENU, OnLoadPDFControls, id=G2gd.wxID_PDFLOADCONTROLS)
1461    self.dataFrame.Bind(wx.EVT_MENU, OnAddElement, id=G2gd.wxID_PDFADDELEMENT)
1462    self.dataFrame.Bind(wx.EVT_MENU, OnDeleteElement, id=G2gd.wxID_PDFDELELEMENT)
1463    self.dataFrame.Bind(wx.EVT_MENU, OnComputePDF, id=G2gd.wxID_PDFCOMPUTE)
1464    self.dataFrame.Bind(wx.EVT_MENU, OnComputeAllPDF, id=G2gd.wxID_PDFCOMPUTEALL)
1465    mainSizer = wx.BoxSizer(wx.VERTICAL)
1466    mainSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' PDF data files: '),0,wx.ALIGN_CENTER_VERTICAL)
1467    mainSizer.Add((5,5),0)
1468    str = ' Sample file: PWDR %s   Wavelength, A: %.5f  Energy, keV: %.3f  Polariz.: %.2f '%(dataFile[3:],wave,keV,polariz)
1469    mainSizer.Add(wx.StaticText(parent=self.dataDisplay,label=str),0,wx.ALIGN_CENTER_VERTICAL)
1470#    dataSizer = wx.BoxSizer(wx.HORIZONTAL)
1471#    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label='Azimuth'),0,wx.ALIGN_CENTER_VERTICAL)
1472#    azimVal = wx.TextCtrl(self.dataDisplay,value='%.2f'%(inst['Azimuth']))
1473#    azimVal.Bind(wx.EVT_TEXT_ENTER,OnAzimVal)       
1474#    azimVal.Bind(wx.EVT_KILL_FOCUS,OnAzimVal)
1475#    dataSizer.Add(azimVal,0)   
1476#    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label='Polarization'),0,wx.ALIGN_CENTER_VERTICAL)
1477#    polaVal = wx.TextCtrl(self.dataDisplay,value='%.2f'%(inst['Polariz.']))
1478#    polaVal.Bind(wx.EVT_TEXT_ENTER,OnPolaVal)       
1479#    polaVal.Bind(wx.EVT_KILL_FOCUS,OnPolaVal)
1480#    dataSizer.Add(polaVal,0)   
1481#    mainSizer.Add(dataSizer,0)
1482    mainSizer.Add((5,5),0)
1483    fileSizer = wx.FlexGridSizer(3,6,5,1)
1484    select = ['Sample Bkg.','Container']
1485    if data['Container']['Name']:
1486        select.append('Container Bkg.')
1487    for key in select:
1488        FillFileSizer(fileSizer,key)
1489    mainSizer.Add(fileSizer,0)
1490    mainSizer.Add((5,5),0)
1491    mainSizer.Add(wx.StaticText(self.dataDisplay,label=' Sample information: '),0,wx.ALIGN_CENTER_VERTICAL)
1492    mainSizer.Add((5,5),0)   
1493
1494    ElList = data['ElList']
1495    Abs = G2lat.CellAbsorption(ElList,data['Form Vol'])
1496    Trans = G2pwd.Transmission(data['Geometry'],Abs*data['Pack'],data['Diam'])
1497    elemSizer = wx.FlexGridSizer(3,3,5,1)
1498    for El in ElList:
1499        FillElemSizer(elemSizer,ElList[El])
1500    mainSizer.Add(elemSizer,0)
1501    mainSizer.Add((5,5),0)   
1502    midSizer = wx.BoxSizer(wx.HORIZONTAL)
1503    midSizer.Add(wx.StaticText(self.dataDisplay,label=' Formula volume: '),0,wx.ALIGN_CENTER_VERTICAL)
1504    formVol = wx.TextCtrl(self.dataDisplay,value='%.2f'%(data['Form Vol']))
1505    formVol.Bind(wx.EVT_TEXT_ENTER,OnFormVol)       
1506    formVol.Bind(wx.EVT_KILL_FOCUS,OnFormVol)
1507    midSizer.Add(formVol,0)
1508    midSizer.Add(wx.StaticText(self.dataDisplay,
1509        label=' Theoretical absorption: %.4f cm-1 Sample absorption: %.4f cm-1'%(Abs,Abs*data['Pack'])),
1510        0,wx.ALIGN_CENTER_VERTICAL)
1511    mainSizer.Add(midSizer,0)
1512    mainSizer.Add((5,5),0)   
1513
1514    geoBox = wx.BoxSizer(wx.HORIZONTAL)
1515    geoBox.Add(wx.StaticText(self.dataDisplay,label=' Sample geometry: '),0,wx.ALIGN_CENTER_VERTICAL)
1516    choice = ['Cylinder','Bragg-Brentano','Tilting flat plate in transmission','Fixed flat plate']
1517    geometry = wx.ComboBox(self.dataDisplay,value=data['Geometry'],choices=choice,
1518            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1519    geometry.Bind(wx.EVT_COMBOBOX, OnGeometry)
1520    geoBox.Add(geometry,0)
1521    geoBox.Add(wx.StaticText(self.dataDisplay,label=' Sample diameter/thickness, mm: '),0,wx.ALIGN_CENTER_VERTICAL)
1522    diam = wx.TextCtrl(self.dataDisplay,value='%.3f'%(data['Diam']))
1523    diam.Bind(wx.EVT_TEXT_ENTER,OnDiameter)       
1524    diam.Bind(wx.EVT_KILL_FOCUS,OnDiameter)
1525#    diam.Bind(wx.EVT_SET_FOCUS,OnShowTip(self,'tip')) #this doesn't work - what would????
1526    geoBox.Add(diam,0)
1527    mainSizer.Add(geoBox,0)
1528    mainSizer.Add((5,5),0)   
1529    geoBox = wx.BoxSizer(wx.HORIZONTAL)
1530    geoBox.Add(wx.StaticText(self.dataDisplay,label=' Packing: '),0,wx.ALIGN_CENTER_VERTICAL)
1531    pack = wx.TextCtrl(self.dataDisplay,value='%.2f'%(data['Pack']))
1532    pack.Bind(wx.EVT_TEXT_ENTER,OnPacking)       
1533    pack.Bind(wx.EVT_KILL_FOCUS,OnPacking)
1534    geoBox.Add(pack,0)
1535    geoBox.Add(wx.StaticText(self.dataDisplay,label=' Sample transmission: %.3f %%'%(Trans)),0,wx.ALIGN_CENTER_VERTICAL)   
1536    mainSizer.Add(geoBox,0)
1537    mainSizer.Add((5,5),0)   
1538       
1539    mainSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' S(Q)->F(Q)->G(R) controls: '),0,wx.ALIGN_CENTER_VERTICAL)
1540    mainSizer.Add((5,5),0)
1541    sqBox = wx.BoxSizer(wx.HORIZONTAL)
1542    sqBox.Add(wx.StaticText(self.dataDisplay,label=' Detector type: '),0,wx.ALIGN_CENTER_VERTICAL)
1543    choice = ['Image plate','Point detector']
1544    detType = wx.ComboBox(self.dataDisplay,value=data['DetType'],choices=choice,
1545            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1546    detType.Bind(wx.EVT_COMBOBOX, OnDetType)
1547    sqBox.Add(detType,0)
1548    if data['DetType'] == 'Image plate':
1549        sqBox.Add(wx.StaticText(self.dataDisplay,label=' IP transmission coeff.: '),0,wx.ALIGN_CENTER_VERTICAL)
1550        obliqCoeff = wx.TextCtrl(self.dataDisplay,value='%.3f'%(data['ObliqCoeff']))
1551        obliqCoeff.Bind(wx.EVT_TEXT_ENTER,OnObliqCoeff)       
1552        obliqCoeff.Bind(wx.EVT_KILL_FOCUS,OnObliqCoeff)
1553        sqBox.Add(obliqCoeff,0)
1554    mainSizer.Add(sqBox,0)
1555       
1556    sqBox = wx.BoxSizer(wx.HORIZONTAL)
1557    sqBox.Add(wx.StaticText(self.dataDisplay,label=' Ruland width: '),0,wx.ALIGN_CENTER_VERTICAL)   
1558    rulandSldr = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
1559        value=int(1000*data['Ruland']))
1560    sqBox.Add(rulandSldr,1,wx.EXPAND)
1561    rulandSldr.Bind(wx.EVT_SLIDER, OnRulSlider)
1562    rulandWdt = wx.TextCtrl(self.dataDisplay,value='%.3f'%(data['Ruland']))
1563    rulandWdt.Bind(wx.EVT_TEXT_ENTER,OnRulandWdt)       
1564    rulandWdt.Bind(wx.EVT_KILL_FOCUS,OnRulandWdt)
1565    sqBox.Add(rulandWdt,0,wx.ALIGN_CENTER_VERTICAL)   
1566    mainSizer.Add(sqBox,0,wx.ALIGN_LEFT|wx.EXPAND)
1567   
1568    sqBox = wx.BoxSizer(wx.HORIZONTAL)
1569    lorch = wx.CheckBox(parent=self.dataDisplay,label='Lorch damping?')
1570    lorch.SetValue(data['Lorch'])
1571    lorch.Bind(wx.EVT_CHECKBOX, OnLorch)
1572    sqBox.Add(lorch,0,wx.ALIGN_CENTER_VERTICAL)
1573    sqBox.Add(wx.StaticText(self.dataDisplay,label=' Scaling q-range: '),0,wx.ALIGN_CENTER_VERTICAL)
1574    SQmin = wx.TextCtrl(self.dataDisplay,value='%.1f'%(data['QScaleLim'][0]))
1575    SQmin.Bind(wx.EVT_TEXT_ENTER,OnSQmin)       
1576    SQmin.Bind(wx.EVT_KILL_FOCUS,OnSQmin)   
1577    sqBox.Add(SQmin,0)
1578    sqBox.Add(wx.StaticText(self.dataDisplay,label=' to '),0,wx.ALIGN_CENTER_VERTICAL)
1579    SQmax = wx.TextCtrl(self.dataDisplay,value='%.1f'%(data['QScaleLim'][1]))
1580    SQmax.Bind(wx.EVT_TEXT_ENTER,OnSQmax)       
1581    SQmax.Bind(wx.EVT_KILL_FOCUS,OnSQmax)
1582    sqBox.Add(SQmax,0)
1583    resetQ = wx.CheckBox(parent=self.dataDisplay,label='Reset?')
1584    sqBox.Add(resetQ,0)
1585    resetQ.Bind(wx.EVT_CHECKBOX, OnResetQ)
1586   
1587    mainSizer.Add(sqBox,0)
1588
1589    mainSizer.Layout()   
1590    self.dataDisplay.SetSizer(mainSizer)
1591    Size = mainSizer.Fit(self.dataFrame)
1592    self.dataDisplay.SetSize(Size)
1593    self.dataFrame.setSizePosLeft(Size)
1594   
Note: See TracBrowser for help on using the repository browser.