source: trunk/GSASIIgrid.py @ 72

Last change on this file since 72 was 72, checked in by vondreel, 15 years ago

add "Integrate all" option for integrating a set of images

File size: 97.3 KB
Line 
1#GSASII - data display routines
2import wx
3import wx.grid as wg
4import matplotlib as mpl
5import math
6import time
7import cPickle
8import GSASIIpath
9import GSASIIcomp as G2cmp
10import GSASIIspc as G2spc
11import GSASIIElem as G2elem
12import GSASIIplot as G2plt
13import GSASIIIO as G2IO
14
15# trig functions in degrees
16sind = lambda x: math.sin(x*math.pi/180.)
17tand = lambda x: math.tan(x*math.pi/180.)
18cosd = lambda x: math.cos(x*math.pi/180.)
19asind = lambda x: 180.*math.asin(x)/math.pi
20       
21[ wxID_ATOMSEDITADD, wxID_ATOMSEDITINSERT, 
22] = [wx.NewId() for _init_coll_Atom_Items in range(2)]
23
24[ wxID_IMCALIBRATE, wxID_IMINTEGRATE, wxID_IMCLEARCALIB, wxID_SAVEINTG, 
25    wxID_IMCOPYCONTROLS, wxID_INTEGRATEALL,
26] = [wx.NewId() for _init_coll_IMAGE_Items in range(6)]
27
28[ wxID_INSTPRMRESET,
29] = [wx.NewId() for _init_coll_INST_Items in range(1)]
30
31[ wxID_MASKCOPY,
32] = [wx.NewId() for _init_coll_MASK_Items in range(1)]
33
34[ wxID_UNDO,wxID_PEAKFIT,wxID_AUTOPEAKFIT,
35] = [wx.NewId() for _init_coll_PEAK_Items in range(3)]
36
37[  wxID_INDEXPEAKS, wxID_REFINECELL, wxID_COPYCELL,
38] = [wx.NewId() for _init_coll_INDEX_Items in range(3)]
39
40class DataFrame(wx.Frame):
41    def _init_coll_BlankMenu(self,parent):
42        parent.Append(menu=self.Blank,title='')
43       
44    def _init_coll_AtomsMenu(self,parent):
45        parent.Append(menu=self.AtomEdit, title='Add atom')
46                   
47    def _init_coll_ImageMenu(self,parent):
48        parent.Append(menu=self.ImageEdit, title='Image Operations')
49       
50    def _init_coll_InstMenu(self,parent):
51        parent.Append(menu=self.InstEdit, title='Inst. Parm. Operations')
52       
53    def _init_coll_MaskMenu(self,parent):
54        parent.Append(menu=self.MaskEdit, title='Mask Operations')
55       
56    def _init_coll_PeakMenu(self,parent):
57        parent.Append(menu=self.PeakEdit, title='Peak Fitting')
58
59    def _init_coll_IndexMenu(self,parent):
60        parent.Append(menu=self.IndexEdit, title='Cell Index/Refine')
61       
62    def _init_coll_Atom_Items(self,parent):
63        parent.Append(help='',id=wxID_ATOMSEDITADD, kind=wx.ITEM_NORMAL,text='Append empty atom')
64        parent.Append(id=wxID_ATOMSEDITINSERT, kind=wx.ITEM_NORMAL,text='Insert empty atom',
65            help='Double left click on atom row to Insert before')
66           
67    def _init_coll_Image_Items(self,parent):
68        parent.Append(help='Calibrate detector by fitting to calibrant lines', 
69            id=wxID_IMCALIBRATE, kind=wx.ITEM_NORMAL,text='Calibrate')
70        parent.Append(help='Clear calibration data points and rings',id=wxID_IMCLEARCALIB, 
71            kind=wx.ITEM_NORMAL,text='Clear calibration')
72        parent.Append(help='Integrate selected image',id=wxID_IMINTEGRATE, 
73            kind=wx.ITEM_NORMAL,text='Integrate')
74        parent.Append(help='Integrate all images selected from list',id=wxID_INTEGRATEALL,
75            kind=wx.ITEM_NORMAL,text='Integrate all')
76        parent.Append(help='Save integration results as a series of 1-D powder patterns', 
77            id=wxID_SAVEINTG, kind=wx.ITEM_NORMAL,text='Save Integration')
78        parent.Append(help='Copy image controls to other images', 
79            id=wxID_IMCOPYCONTROLS, kind=wx.ITEM_NORMAL,text='Copy Controls')
80                   
81    def _init_coll_Mask_Items(self,parent):
82        parent.Append(help='Copy mask to other images', 
83            id=wxID_MASKCOPY, kind=wx.ITEM_NORMAL,text='Copy mask')
84
85    def _init_coll_Inst_Items(self,parent):
86        parent.Append(help='Reset instrument profile parameters to default', 
87            id=wxID_INSTPRMRESET, kind=wx.ITEM_NORMAL,text='Reset profile')
88
89    def _init_coll_Peak_Items(self,parent):
90        self.UnDo = parent.Append(help='Undo last least squares refinement', 
91            id=wxID_UNDO, kind=wx.ITEM_NORMAL,text='UnDo')
92        self.PeakFit = parent.Append(id=wxID_PEAKFIT, kind=wx.ITEM_NORMAL,text='PeakFit', 
93            help='Do single cycle of peak fitting least-squares refinement' )
94        self.AutoPeakFit = parent.Append(id=wxID_AUTOPEAKFIT, kind=wx.ITEM_NORMAL, 
95            text='AutoPeakFit',help='Do peak fitting least-squares to convergence' )
96           
97    def _init_coll_Index_Items(self,parent):
98        self.IndexPeaks = parent.Append(help='', id=wxID_INDEXPEAKS, kind=wx.ITEM_NORMAL,
99            text='Index Cell')
100        self.CopyCell = parent.Append( id=wxID_COPYCELL, kind=wx.ITEM_NORMAL,text='Copy Cell', 
101            help='Copy selected unit cell from indexing to cell refinement fields')
102        self.RefineCell = parent.Append( id=wxID_REFINECELL, kind=wx.ITEM_NORMAL, 
103            text='Refine Cell',help='Refine unit cell parameters from indexed peaks')
104
105    def _init_utils(self):
106        self.BlankMenu = wx.MenuBar()
107       
108        self.AtomsMenu = wx.MenuBar()
109        self.ImageMenu = wx.MenuBar()
110        self.MaskMenu = wx.MenuBar()
111        self.InstMenu = wx.MenuBar()
112        self.PeakMenu = wx.MenuBar()
113        self.IndexMenu = wx.MenuBar()
114        self.AtomEdit = wx.Menu(title='')
115        self.ImageEdit = wx.Menu(title='')
116        self.MaskEdit = wx.Menu(title='')
117        self.InstEdit = wx.Menu(title='')
118        self.PeakEdit = wx.Menu(title='')
119        self.IndexEdit = wx.Menu(title='')
120        self._init_coll_AtomsMenu(self.AtomsMenu)
121        self._init_coll_Atom_Items(self.AtomEdit)
122        self._init_coll_ImageMenu(self.ImageMenu)
123        self._init_coll_Image_Items(self.ImageEdit)
124        self._init_coll_MaskMenu(self.MaskMenu)
125        self._init_coll_Mask_Items(self.MaskEdit)
126        self._init_coll_InstMenu(self.InstMenu)
127        self._init_coll_Inst_Items(self.InstEdit)
128        self._init_coll_PeakMenu(self.PeakMenu)
129        self._init_coll_Peak_Items(self.PeakEdit)
130        self._init_coll_IndexMenu(self.IndexMenu)
131        self._init_coll_Index_Items(self.IndexEdit)
132        self.UnDo.Enable(False)
133        self.PeakFit.Enable(False)
134        self.AutoPeakFit.Enable(False)
135        self.IndexPeaks.Enable(False)
136        self.CopyCell.Enable(False)
137        self.RefineCell.Enable(False)
138               
139    def _init_ctrls(self, parent,name=None,size=None,pos=None):
140        wx.Frame.__init__(self,parent=parent,style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX,
141            size=size,pos=pos,title='GSAS-II data display')
142        self._init_utils()
143        if name:
144            self.SetLabel(name)
145        self.Show()
146       
147    def __init__(self,parent,data=None,name=None, size=None,pos=None):
148        self._init_ctrls(parent,name,size,pos)
149        self.data = data
150        self.screenSize = wx.DisplaySize()
151        Size = self.GetSize()
152        xPos = self.screenSize[0]-Size[0]
153        self.SetPosition(wx.Point(xPos,250))
154        self.dirname = ''
155        self.AtomGrid = []
156        self.selectedRow = 0
157       
158    def setSizePosLeft(self,Width):
159        screenSize = wx.DisplaySize()
160        self.SetSize(Width)
161        self.SetPosition(wx.Point(screenSize[0]-Width[0],250))
162       
163    def Clear(self):
164        self.ClearBackground()
165        self.DestroyChildren()
166                   
167class GSGrid(wg.Grid):
168    def __init__(self, parent, name=''):
169        wg.Grid.__init__(self,parent,-1,name=name)                   
170        self.SetSize(parent.GetClientSize())
171           
172    def Clear(self):
173        wg.Grid.ClearGrid(self)
174       
175    def SetCellStyle(self,r,c,color="white",readonly=True):
176        self.SetCellBackgroundColour(r,c,color)
177        self.SetReadOnly(r,c,isReadOnly=readonly)
178       
179class GSNoteBook(wx.Notebook):
180    def __init__(self, parent, name='',size = None):
181        wx.Notebook.__init__(self, parent, -1, name=name, style= wx.BK_TOP)
182        if size: self.SetSize(size)
183                                                     
184    def Clear(self):       
185        GSNoteBook.DeleteAllPages(self)
186       
187class Table(wg.PyGridTableBase):
188    def __init__(self, data=[], rowLabels=None, colLabels=None, types = None):
189        wg.PyGridTableBase.__init__(self)
190        self.colLabels = colLabels
191        self.rowLabels = rowLabels
192        self.dataTypes = types
193        self.data = data
194       
195    def AppendRows(self, numRows=1):
196        self.data.append([])
197        return True
198       
199    def CanGetValueAs(self, row, col, typeName):
200        if self.dataTypes:
201            colType = self.dataTypes[col].split(':')[0]
202            if typeName == colType:
203                return True
204            else:
205                return False
206        else:
207            return False
208
209    def CanSetValueAs(self, row, col, typeName):
210        return self.CanGetValueAs(row, col, typeName)
211
212    def DeleteRow(self,pos):
213        data = self.GetData()
214        self.SetData([])
215        new = []
216        for irow,row in enumerate(data):
217            if irow <> pos:
218                new.append(row)
219        self.SetData(new)
220       
221    def GetColLabelValue(self, col):
222        if self.colLabels:
223            return self.colLabels[col]
224           
225    def GetData(self):
226        data = []
227        for row in range(self.GetNumberRows()):
228            data.append(self.GetRowValues(row))
229        return data
230       
231    def GetNumberCols(self):
232        try:
233            return len(self.colLabels)
234        except TypeError:
235            return None
236       
237    def GetNumberRows(self):
238        return len(self.data)
239       
240    def GetRowLabelValue(self, row):
241        if self.rowLabels:
242            return self.rowLabels[row]
243       
244    def GetRowValues(self, row):
245        data = []
246        for col in range(self.GetNumberCols()):
247            data.append(self.GetValue(row, col))
248        return data
249       
250    def GetTypeName(self, row, col):
251        try:
252            return self.dataTypes[col]
253        except TypeError:
254            return None
255
256    def GetValue(self, row, col):
257        try:
258            return self.data[row][col]
259        except IndexError:
260            return None
261           
262    def InsertRows(self, pos, rows):
263        for row in range(rows):
264            self.data.insert(pos,[])
265            pos += 1
266       
267    def IsEmptyCell(self,row,col):
268        try:
269            return not self.data[row][col]
270        except IndexError:
271            return True
272       
273    def OnKeyPress(self, event):
274        dellist = self.GetSelectedRows()
275        if event.GetKeyCode() == wx.WXK_DELETE and dellist:
276            grid = self.GetView()
277            for i in dellist: grid.DeleteRow(i)
278               
279    def SetColLabelValue(self, col, label):
280        numcols = self.GetNumberCols()
281        if col > numcols-1:
282            self.colLabels.append(label)
283        else:
284            self.colLabels[col]=label
285       
286    def SetData(self,data):
287        for row in range(len(data)):
288            self.SetRowValues(row,data[row])
289               
290    def SetRowLabelValue(self, row, label):
291        self.rowLabels[row]=label
292           
293    def SetRowValues(self,row,data):
294        self.data[row] = data
295           
296    def SetValue(self, row, col, value):
297        def innerSetValue(row, col, value):
298            try:
299                self.data[row][col] = value
300            except TypeError:
301                return
302            except IndexError:
303                print row,col,value
304                # add a new row
305                if row > self.GetNumberRows():
306                    self.data.append([''] * self.GetNumberCols())
307                elif col > self.GetNumberCols():
308                    for row in range(self.GetNumberRows):
309                        self.data[row].append('')
310                print self.data
311                self.data[row][col] = value
312        innerSetValue(row, col, value)
313       
314def UpdateNotebook(self,data):       
315    if data:
316        self.dataFrame.SetLabel('Notebook')
317        self.dataDisplay = wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
318            style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
319        for line in data:
320            self.dataDisplay.AppendText(line+"\n")
321            self.dataDisplay.AppendText('Notebook entry @ '+time.ctime()+"\n")
322           
323def UpdateControls(self,data):
324    if data:
325        self.dataFrame.SetLabel('Controls')
326       
327     
328def UpdateComments(self,data):                   
329    if data:
330        self.dataFrame.SetLabel('Comments')
331        self.dataDisplay = wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
332            style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
333        for line in data:
334            self.dataDisplay.AppendText(line+"\n")
335     
336def UpdatePeakGrid(self, data):
337    if self.dataDisplay:
338        self.dataDisplay.Destroy()
339   
340    def OnUnDo(event):
341        DoUnDo()
342        self.dataFrame.UnDo.Enable(False)
343       
344    def DoUnDo():
345        print 'Undo last refinement'
346        file = open('GSASII.save','rb')
347        PatternId = self.PatternId
348        for item in ['Background','Instrument Parameters','Peak List']:
349            self.PatternTree.SetItemPyData(GetPatternTreeItemId(self,PatternId, item),cPickle.load(file))
350            if self.dataDisplay.GetName() == item:
351                if item == 'Background':
352                    UpdateBackgroundGrid(self,self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, item)))
353                elif item == 'Instrument Parameters':
354                    UpdateInstrumentGrid(self,self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, item)))
355                elif item == 'Peak List':
356                    UpdatePeakGrid(self,self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, item)))
357            print item,' recovered'
358        file.close()
359       
360    def OnPeakFit(event):
361        self.SaveState()
362        print 'Peak Fitting - Do one cycle of peak fitting'
363        PatternId = self.PatternId
364        PickId = self.PickId
365        peaks = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Peak List'))
366        if not peaks:
367            self.ErrorDialog('No peaks!','Nothing to fit!')
368            return
369        background = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Background'))[0]
370        limits = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Limits'))[1]
371        inst = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))
372        data = self.PatternTree.GetItemPyData(PatternId)[1]
373        OK,smin,Rwp,runtime,GoOn = G2cmp.DoPeakFit(peaks,background,limits,inst,data)
374        UpdatePeakGrid(self,peaks)
375        G2plt.PlotPatterns(self)
376        if not OK:
377            print 'Refinement failed'
378            dlg = wx.MessageDialog(self, 'Do you want to reload now?', 'Refinement failed',  wx.YES_NO)
379            try:
380                if dlg.ShowModal() == wx.ID_YES:
381                    DoUnDo()
382                    self.dataFrame.UnDo.Enable(False)
383            finally:
384                dlg.Destroy()
385        else:
386            self.dataFrame.UnDo.Enable(True)
387            print "%s%7.2f%s%12.6g" % ('Rwp = ',Rwp,'%, Smin = ',smin)
388            print "%s%8.3f%s " % ('fitpeak time =',runtime,'s')
389            print 'finished'
390        return
391       
392    def OnAutoPeakFit(event):
393        self.SaveState()
394        print 'AutoPeak Fitting - run until minimized'
395        PatternId = self.PatternId
396        PickId = self.PickId
397        peaks = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Peak List'))
398        if not peaks:
399            self.ErrorDialog('No peaks!','Nothing to fit!')
400            return
401        background = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Background'))[0]
402        limits = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Limits'))[1]
403        inst = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))
404        data = self.PatternTree.GetItemPyData(PatternId)[1]
405        smin = 1.0e15
406        GoOn = True
407        while GoOn:
408            osmin = smin
409            OK,smin,Rwp,runtime,GoOn = G2cmp.DoPeakFit(peaks,background,limits,inst,data)
410            UpdatePeakGrid(self,peaks)
411            if not OK:
412                break
413            G2plt.PlotPatterns(self)
414            print "%s%7.2f%s%12.6g" % ('Rwp = ',Rwp,'%, Smin = ',smin)
415            rat = (osmin-smin)/smin
416            if rat < 1.0e-4: GoOn = False
417        if not OK:
418            print 'Refinement failed'
419            dlg = wx.MessageDialog(self, 'Do you want to reload now?', 'Refinement failed',  wx.YES_NO)
420            try:
421                if dlg.ShowModal() == wx.ID_YES:
422                    DoUnDo()
423                    self.dataFrame.UnDo.Enable(False)
424            finally:
425                dlg.Destroy()
426        else:
427            self.dataFrame.UnDo.Enable(True)
428            print "%s%8.3f%s " % ('fitpeak time =',runtime,'s per cycle')
429            print 'finished'
430        return       
431
432    def RefreshPeakGrid(event):
433        event.StopPropagation()
434        data = self.PeakTable.GetData()
435        T = []
436        for peak in data:T.append(peak[0])
437        D = dict(zip(T,data))
438        T.sort()
439        X = []
440        for key in T: X.append(D[key])
441        data = X       
442        G2plt.PlotPatterns(self)
443       
444    def setBackgroundColors():
445       for r in range(self.dataDisplay.GetNumberRows()):
446           for c in range(self.dataDisplay.GetNumberCols()):
447               if self.dataDisplay.GetColLabelValue(c) in ['position','intensity','sigma','gamma']:
448                   if float(self.dataDisplay.GetCellValue(r,c)) < 0.:
449                       self.dataDisplay.SetCellBackgroundColour(r,c,wx.RED)
450                   else:
451                       self.dataDisplay.SetCellBackgroundColour(r,c,wx.WHITE)
452                           
453    def KeyEditPeakGrid(event):
454        rowList = self.dataDisplay.GetSelectedRows()
455        colList = self.dataDisplay.GetSelectedCols()
456        selectList = self.dataDisplay.GetSelectedCells()
457        data = self.PatternTree.GetItemPyData(self.PickId)
458        if event.GetKeyCode() == wx.WXK_RETURN:
459            event.Skip(True)
460        elif event.GetKeyCode() == wx.WXK_CONTROL:
461            event.Skip(True)
462        elif event.GetKeyCode() == wx.WXK_SHIFT:
463            event.Skip(True)
464        elif rowList:
465            self.dataDisplay.ClearSelection()
466            if event.GetKeyCode() == wx.WXK_DELETE:
467                self.dataDisplay.ClearGrid()
468                rowList.reverse()
469                nDel = 0
470                for row in rowList:
471                    self.PeakTable.DeleteRow(row)
472                    nDel += 1
473                if nDel:
474                    msg = wg.GridTableMessage(self.PeakTable, 
475                        wg.GRIDTABLE_NOTIFY_ROWS_DELETED,0,nDel)
476                    self.dataDisplay.ProcessTableMessage(msg)
477                data = self.PeakTable.GetData()
478                self.PatternTree.SetItemPyData(self.PickId,data[:-nDel])
479                self.dataDisplay.ForceRefresh()
480                setBackgroundColors()
481                if not len(self.PatternTree.GetItemPyData(self.PickId)): 
482                    self.dataFrame.PeakFit.Enable(False)
483                    self.dataFrame.AutoPeakFit.Enable(False)
484                       
485        elif colList:
486            self.dataDisplay.ClearSelection()
487            key = event.GetKeyCode()
488            for col in colList:
489                if self.PeakTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
490                    if key == 89: #'Y'
491                        for row in range(self.PeakTable.GetNumberRows()): data[row][col]=True
492                    elif key == 78:  #'N'
493                        for row in range(self.PeakTable.GetNumberRows()): data[row][col]=False
494        elif selectList:
495            self.dataDisplay.ClearSelection()
496            key = event.GetKeyCode()
497            for row,col in selectList:
498                if self.PeakTable.GetTypeName(row,col) == wg.GRID_VALUE_BOOL:
499                    if key == 89: #'Y'
500                        data[row][col]=True
501                    elif key == 78:  #'N'
502                        data[row][col]=False
503        G2plt.PlotPatterns(self)
504           
505    self.dataFrame.SetMenuBar(self.dataFrame.PeakMenu)
506    if not self.dataFrame.GetStatusBar():
507        Status = self.dataFrame.CreateStatusBar()
508    self.Bind(wx.EVT_MENU, OnUnDo, id=wxID_UNDO)
509    self.Bind(wx.EVT_MENU, OnPeakFit, id=wxID_PEAKFIT)
510    self.Bind(wx.EVT_MENU, OnAutoPeakFit, id=wxID_AUTOPEAKFIT)
511    self.dataFrame.PeakFit.Enable(False)
512    self.dataFrame.AutoPeakFit.Enable(False)
513    if data:
514        self.dataFrame.PeakFit.Enable(True)
515        self.dataFrame.AutoPeakFit.Enable(True)
516    self.PickTable = []
517    rowLabels = []
518    for i in range(len(data)): rowLabels.append(str(i+1))
519    colLabels = ['position','refine','intensity','refine','sigma','refine','gamma','refine']
520    Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
521        wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
522        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
523        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
524    T = []
525    for peak in data:
526        T.append(peak[0])
527    D = dict(zip(T,data))
528    T.sort()
529    X = []
530    for key in T: X.append(D[key])
531    data = X       
532    self.PatternTree.SetItemPyData(self.PickId,data)
533    self.PeakTable = Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
534    self.dataFrame.SetLabel('Peak List')
535    self.dataDisplay = GSGrid(parent=self.dataFrame)
536    self.dataDisplay.SetTable(self.PeakTable, True)
537    setBackgroundColors()                         
538    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshPeakGrid)
539    self.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)                 
540    self.dataDisplay.SetMargins(0,0)
541    self.dataDisplay.AutoSizeColumns(False)
542    self.dataFrame.setSizePosLeft([550,350])
543       
544def UpdateBackgroundGrid(self,data):
545    BackId = GetPatternTreeItemId(self,self.PatternId, 'Background')
546   
547    def RefreshBackgroundGrid(event):
548        data = self.BackTable.GetData()
549        M = len(data[0])
550        N = data[0][2]+3
551        item = data[0]
552        if N > M:       #add terms
553            for i in range(M,N): 
554                item.append(0.0)
555                self.BackTable.SetColLabelValue(i,str(i-2))
556            data = [item]
557            msg = wg.GridTableMessage(self.BackTable, 
558                wg.GRIDTABLE_NOTIFY_COLS_APPENDED,0,N-M)
559            self.dataDisplay.ProcessTableMessage(msg)                         
560        elif N < M:     #delete terms
561            new = []
562            for i in range(N):
563                new.append(item[i])
564            data = [new]
565            msg = wg.GridTableMessage(self.BackTable, 
566                wg.GRIDTABLE_NOTIFY_COLS_DELETED,0,M-N)
567            self.dataDisplay.ProcessTableMessage(msg)                         
568        self.PatternTree.SetItemPyData(BackId,data)
569                 
570    self.dataFrame.setSizePosLeft([700,150])
571    maxTerm = 7
572    self.BackTable = []
573    N = len(data[0])
574    M = data[0][2]
575    colLabels = ['function','refine','Nterms']
576    rowLabels=['background']
577    for i in range(M): colLabels.append(str(i+1))
578    Types = [wg.GRID_VALUE_CHOICE+':chebyschev,another,more',
579        wg.GRID_VALUE_BOOL,
580        wg.GRID_VALUE_NUMBER+':1,'+str(maxTerm)]
581    for i in range(maxTerm):
582        Types.append(wg.GRID_VALUE_FLOAT+':10,3')
583    self.BackTable = Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
584    self.dataFrame.SetLabel('Background')
585    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
586    self.dataDisplay = GSGrid(parent=self.dataFrame)
587    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshBackgroundGrid)               
588    self.dataDisplay.SetTable(self.BackTable, True)
589    self.dataDisplay.SetMargins(0,0)
590    self.dataDisplay.AutoSizeColumns(False)
591       
592def UpdateLimitsGrid(self, data):
593    if self.dataDisplay:
594        self.dataDisplay.Destroy()
595    self.dataFrame.setSizePosLeft([250,150])
596    LimitId = GetPatternTreeItemId(self,self.PatternId, 'Limits')
597    def RefreshLimitsGrid(event):
598        data = self.LimitsTable.GetData()
599        old = data[0]
600        new = data[1]
601        new[0] = max(old[0],new[0])
602        new[1] = max(new[0],min(old[1],new[1]))
603        data = [old,new]
604        G2plt.PlotPatterns(self)
605       
606    self.LimitsTable = []
607    colLabels = ['Tmin','Tmax']
608    rowLabels = ['original','changed']
609    Types = [wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3']
610    self.LimitsTable = Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
611    self.dataFrame.SetLabel('Limits')
612    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
613    self.dataDisplay = GSGrid(parent=self.dataFrame)               
614    self.dataDisplay.SetTable(self.LimitsTable, True)
615    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshLimitsGrid)               
616    self.dataDisplay.SetMargins(0,0)
617    self.dataDisplay.AutoSizeColumns(False)
618   
619def UpdateInstrumentGrid(self, data):
620    if self.dataDisplay:
621        self.dataDisplay.Destroy()
622    Ka2 = False
623    Xwid = 700
624    if len(data[0]) == 13: 
625        Ka2 = True
626        Xwid = 840       
627    self.dataFrame.setSizePosLeft([Xwid,170])
628    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
629    InstId = GetPatternTreeItemId(self,self.PatternId, 'Instrument Parameters')
630   
631    def RefreshInstrumentGrid(event,doAnyway=False):
632        if doAnyway or event.GetRow() == 1:
633            peaks = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,self.PatternId, 'Peak List'))
634            ins = data[1]
635            if 'P' in ins[0]:                                       #update powder peak parameters
636                for peak in peaks:
637                    if Ka2:
638                        peak[4] = ins[6]*tand(peak[0]/2.0)**2+ins[7]*tand(peak[0]/2.0)+ins[8]
639                        peak[6] = ins[9]/cosd(peak[0]/2.0)+ins[10]*tand(peak[0]/2.0)
640                    else:
641                        peak[4] = ins[4]*tand(peak[0]/2.0)**2+ins[5]*tand(peak[0]/2.0)+ins[6]
642                        peak[6] = ins[7]/cosd(peak[0]/2.0)+ins[8]*tand(peak[0]/2.0)
643                       
644    def OnReset(event):
645        if Ka2:
646            data[1][6:12] = data[0][6:12]
647        else:
648            data[1][4:10] = data[0][4:10]
649        RefreshInstrumentGrid(event,doAnyway=True)          #to get peaks updated
650        UpdateInstrumentGrid(self, data)
651       
652    self.InstrumentTable = []
653    if 'P' in data[1][0]:                   #powder data
654        self.dataFrame.SetMenuBar(self.dataFrame.InstMenu)
655        if not self.dataFrame.GetStatusBar():
656            Status = self.dataFrame.CreateStatusBar()
657        self.Bind(wx.EVT_MENU, OnReset, id=wxID_INSTPRMRESET)
658        if Ka2:
659            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
660                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3', #zero, ratio, pola
661                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3', #u,v,w
662                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,2']
663        else:
664            Types = [wg.GRID_VALUE_CHOICE+":PXC,PNC,PNT",wg.GRID_VALUE_FLOAT+':10,6',               #type & lam-1
665                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3', #zero, pola
666                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3', #u,v,w
667                wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,2']
668        colLabels = data[3]
669        rowLabels = ['default','changed','refine']
670        self.InstrumentTable = Table(data[:-1],rowLabels=rowLabels,colLabels=colLabels,types=Types)
671        self.dataFrame.SetLabel('Instrument Parameters')
672        self.dataDisplay = GSGrid(parent=self.dataFrame)               
673        self.dataDisplay.SetTable(self.InstrumentTable, True)
674        self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshInstrumentGrid)               
675        self.dataDisplay.SetMargins(0,0)
676        self.dataDisplay.AutoSizeColumns(False)
677        beg = 4
678        if Ka2: beg = 6
679        for i in range(len(data[2])):
680            if i < beg or i == beg+6:
681                self.dataDisplay.SetCellRenderer(2,i,wg.GridCellStringRenderer())
682                self.dataDisplay.SetCellValue(2,i,'')
683                self.dataDisplay.SetReadOnly(2,i,isReadOnly=True)
684            else:
685                self.dataDisplay.SetCellRenderer(2,i,wg.GridCellBoolRenderer())
686                self.dataDisplay.SetCellEditor(2,i,wg.GridCellBoolEditor())
687    else:                       #single crystal data
688        Types = [wg.GRID_VALUE_CHOICE+":SXC,SNC,SNT",wg.GRID_VALUE_FLOAT+':10,6']
689        colLabels = data[2]
690        rowLabels = ['original','changed']
691        self.InstrumentTable = Table(data[:-1],rowLabels=rowLabels,colLabels=colLabels,types=Types)
692        self.dataFrame.SetLabel('Instrument Parameters')
693        self.dataDisplay = GSGrid(parent=self.dataFrame)               
694        self.dataDisplay.SetTable(self.InstrumentTable, True)
695        self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshInstrumentGrid)               
696        self.dataDisplay.SetMargins(0,0)
697        self.dataDisplay.AutoSizeColumns(False)
698               
699def UpdateIndexPeaksGrid(self, data):
700    IndexId = GetPatternTreeItemId(self,self.PatternId, 'Index Peak List')
701   
702    def RefreshIndexPeaksGrid(event):
703        data = self.IndexPeaksTable.GetData()
704        self.PatternTree.SetItemPyData(IndexId,data)
705       
706    def KeyEditPickGrid(event):
707        colList = self.dataDisplay.GetSelectedCols()
708        rowList = self.dataDisplay.GetSelectedRows()
709        data = self.PatternTree.GetItemPyData(IndexId)
710        if event.GetKeyCode() == wx.WXK_RETURN:
711            event.Skip(True)
712        elif event.GetKeyCode() == wx.WXK_CONTROL:
713            event.Skip(True)
714        elif event.GetKeyCode() == wx.WXK_SHIFT:
715            event.Skip(True)
716        elif event.GetKeyCode() == wx.WXK_DELETE:
717            dlg = wx.MessageDialog(self, 'Delete Index Peak List?', ' ', wx.YES | wx.NO)
718            try:
719                result = dlg.ShowModal()
720                if result == wx.ID_YES:
721                    oldlen = len(data)
722                    data = []
723                    self.PatternTree.SetItemPyData(IndexId,data)
724                    self.dataDisplay.Clear() 
725                    self.dataDisplay.Destroy()
726                    self.IndexPeaksTable = []
727            finally:
728                dlg.Destroy()
729        elif colList:
730            self.dataDisplay.ClearSelection()
731            key = event.GetKeyCode()
732            for col in colList:
733                if self.IndexPeaksTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
734                    if key == 89: #'Y'
735                        for row in range(self.IndexPeaksTable.GetNumberRows()): data[row][col]=True
736                    elif key == 78:  #'N'
737                        for row in range(self.IndexPeaksTable.GetNumberRows()): data[row][col]=False
738           
739    if self.dataDisplay:
740        self.dataDisplay.Destroy()
741    self.dataFrame.setSizePosLeft([500,300])
742    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
743    inst = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,self.PatternId, 'Instrument Parameters'))[1]
744    self.IndexPeaksTable = []
745    if not data:
746        peaks = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,self.PatternId, 'Peak List'))
747        for peak in peaks:
748            dsp = inst[1]/(2.0*sind(peak[0]/2.0))
749            data.append([peak[0],peak[2],True,False,0,0,0,dsp,0.0])
750    else:
751        cells = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,self.PatternId, 'Unit Cells List'))
752        if cells:
753            cellist = cells[2]
754            dmin = cells[3]
755            self.HKL = []
756            for i,cell in enumerate(cellist):
757                if cell[-1]:
758                    ibrav = cell[2]
759                    A = G2cmp.cell2A(cell[3:9])
760                    self.HKL = G2cmp.GenHBravais(dmin,ibrav,A)
761                    G2cmp.IndexPeaks(data,self.HKL)
762                    for hkl in self.HKL:
763                        hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))             
764    rowLabels = []
765    for i in range(len(data)): rowLabels.append(str(i+1))
766    colLabels = ['position','intensity','use','indexed','h','k','l','d-obs','d-calc']
767    Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
768        wg.GRID_VALUE_BOOL,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,
769        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5']
770    self.PatternTree.SetItemPyData(IndexId,data)
771    self.IndexPeaksTable = Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
772    self.dataFrame.SetLabel('Index Peak List')
773    self.dataDisplay = GSGrid(parent=self.dataFrame)               
774    self.dataDisplay.SetTable(self.IndexPeaksTable, True)
775    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshIndexPeaksGrid)
776    self.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPickGrid)                 
777    self.dataDisplay.SetMargins(0,0)
778    self.dataDisplay.AutoSizeColumns(False)
779
780def UpdateUnitCellsGrid(self, data):
781    UnitCellsId = GetPatternTreeItemId(self,self.PatternId, 'Unit Cells List')
782    bravaisSymb = ['Fm3m','Im3m','Pm3m','R3-H','P6/mmm','I4/mmm',
783        'P4/mmm','Fmmm','Immm','Cmmm','Pmmm','C2/m','P2/m','P1']
784       
785    def OnRefineCell(event):
786        def cellPrint(ibrav,A):
787            cell = G2cmp.A2cell(A)
788            Vol = G2cmp.calc_V(A)
789            if ibrav in [0,1,2]:
790                print "%s%10.6f" % ('a =',cell[0])
791            elif ibrav in [3,4,5,6]:
792                print "%s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],' c =',cell[2],' volume =',Vol)
793            elif ibrav in [7,8,9,10]:
794                print "%s%10.6f %s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2],' volume =',Vol)
795            elif ibrav in [11,12]:
796                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)
797            else:
798                print "%s%10.6f %s%10.6f %s%10.6f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2])
799                print "%s%8.3f %s%8.3f %s%8.3f %s%12.3f" % ('alpha =',cell[3],'beta =',cell[4],'gamma =',cell[5],' volume =',Vol)
800             
801        bravaisSymb = ['Fm3m','Im3m','Pm3m','R3-H','P6/mmm','I4/mmm',
802            'P4/mmm','Fmmm','Immm','Cmmm','Pmmm','C2/m','P2/m','P1']
803        PatternId = self.PatternId
804        PickId = self.PickId   
805        peaks = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Index Peak List'))
806        if not peaks:
807            self.ErrorDialog('No peaks!', 'Nothing to refine!')
808            return       
809        print 'Refine cell'
810        inst = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))[1]
811        controls,bravais,cells,dmin = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Unit Cells List'))
812        cell = controls[6:12]
813        A = G2cmp.cell2A(cell)
814        print controls[5]
815        ibrav = bravaisSymb.index(controls[5])
816        dmin = G2cmp.getDmin(peaks)-0.005
817        Lhkl,M20,X20 = G2cmp.refinePeaks(peaks,ibrav,A)
818        controls[6:12] = G2cmp.A2cell(A)
819        controls[12] = G2cmp.calc_V(A)
820        data = [controls,bravais,cells,dmin]
821        self.PatternTree.SetItemPyData(GetPatternTreeItemId(self,PatternId, 'Unit Cells List'),data)
822        self.HKL = G2cmp.GenHBravais(dmin,ibrav,A)
823        UpdateUnitCellsGrid(self,data)
824        print "%s%10.3f" % ('refinement M20 = ',M20)
825        print 'unindexed lines = ',X20
826        cellPrint(ibrav,A)
827        for hkl in self.HKL:
828            hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))             
829        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
830            G2plt.PlotPowderLines(self)
831        else:
832            G2plt.PlotPatterns(self)
833       
834    def OnIndexPeaks(event):
835        PatternId = self.PatternId   
836        peaks = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Index Peak List'))
837        if not peaks:
838            self.ErrorDialog('No peaks!', 'Nothing to index!')
839            return
840        inst = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))[1]
841        print 'Peak Indexing'
842        try:
843            controls,bravais,cells,dmin = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,PatternId, 'Unit Cells List'))
844            cells = []
845        except ValueError:
846            self.ErrorDialog('Error','Need to set controls in Unit Cell List first')
847            return
848        if True not in bravais:
849            self.ErrorDialog('Error','No Bravais lattices selected')
850            return
851        self.dataFrame.IndexPeaks.Enable(False)
852        self.dataFrame.CopyCell.Enable(False)
853        OK,dmin,cells = G2cmp.DoIndexPeaks(peaks,inst,controls,bravais)
854        if OK:
855            data = [controls,bravais,cells,dmin]
856            self.PatternTree.SetItemPyData(GetPatternTreeItemId(self,PatternId, 'Unit Cells List'),data)
857            UpdateUnitCellsGrid(self,data)
858            bestCell = cells[0]
859            if bestCell[0] > 10.:
860                self.HKL = G2cmp.GenHBravais(dmin,bestCell[2],G2cmp.cell2A(bestCell[3:9]))
861                for hkl in self.HKL:
862                    hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))             
863                if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
864                    G2plt.PlotPowderLines(self)
865                else:
866                    G2plt.PlotPatterns(self)
867        self.dataFrame.CopyCell.Enable(True)
868        self.dataFrame.IndexPeaks.Enable(True)
869               
870    def CopyUnitCell(event):
871        controls,bravais,cells,dmin = self.PatternTree.GetItemPyData(UnitCellsId)
872        for Cell in cells:
873            if Cell[-1]:
874                break
875        cell = Cell[2:9]
876        controls[4] = 1
877        controls[5] = bravaisSymb[cell[0]]
878        controls[6:12] = cell[1:8]
879        controls[12] = G2cmp.calc_V(G2cmp.cell2A(controls[6:12]))
880        for i in range(4,13):
881            self.UnitCellsTable.SetValue(i,1,controls[i])
882        self.PatternTree.SetItemPyData(UnitCellsId,[controls,bravais,cells,dmin])
883        self.dataDisplay.ForceRefresh()
884        self.dataFrame.RefineCell.Enable(True)
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 == 6:
891                for i in range(min(self.UnitCellsTable.GetNumberRows(),len(cells))):
892                    cells[i][-1] = False
893                    self.UnitCellsTable.SetValue(i,c,0)
894                self.UnitCellsTable.SetValue(r,c,1)
895                cells[r][-1] = True
896                ibrav = cells[r][2]
897                A = G2cmp.cell2A(cells[r][3:9])
898                self.HKL = G2cmp.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        controls = []
906        bravais = [0,0,0,0,0,0,0, 0,0,0,0,0,0,0]
907        table = self.UnitCellsTable.GetData()
908        for i,row in enumerate(table):
909            if i in [0,4]:
910                if row[1]:
911                    controls.append(1)
912                else:
913                    controls.append(0)
914            elif i in [1,3]:
915                controls.append(float(row[1]))
916            elif i in [2]:
917                controls.append(int(row[1]))
918            elif i in [5]:
919                controls.append(row[1])
920            elif i in [6,7,8,9,10,11]:
921                if controls[5] in bravaisSymb[:3]:              #cubic
922                    if i in [6]:
923                        controls.append(float(row[1]))
924                        controls.append(float(row[1]))
925                        controls.append(float(row[1]))
926                        controls.append(90.)
927                        controls.append(90.)
928                        controls.append(90.)
929                elif controls[5] in bravaisSymb[3:7]:           #hexagonal & tetragonal
930                    if i in [6]:
931                        controls.append(float(row[1]))
932                        controls.append(float(row[1]))
933                    elif i in [8]:
934                        controls.append(float(row[1]))
935                        controls.append(90.)
936                        controls.append(90.)
937                        if controls[5] in bravaisSymb[3:5]:     #hexagonal
938                            controls.append(120.)
939                        else:                                   #tetragonal
940                            controls.append(90.)
941                elif controls[5] in bravaisSymb[7:13]:          #orthorhombic & monoclinic
942                    if i in [6,7,8]:
943                        controls.append(float(row[1]))
944                    if i in [9,10,11]:
945                        if controls[5] in bravaisSymb[7:11]:
946                            controls.append(90.)
947                            controls.append(90.)
948                            controls.append(90.)
949                            break
950                        else:
951                            if i in [9,11]:
952                                controls.append(90.)
953                            else:
954                                controls.append(float(row[1]))
955                else:                                           #triclinic
956                    controls.append(float(row[1]))
957        controls.append(G2cmp.calc_V(G2cmp.cell2A(controls[6:12])))        #volume       
958        for i,row in enumerate(table):
959            if i < 14:
960                bravais[i] = int(row[2])
961            else:
962                break
963        if controls[4]:
964            for i in range(6,13):
965                self.UnitCellsTable.SetValue(i,1,controls[i])
966        self.dataDisplay.ForceRefresh()
967        if controls[4] and not False in controls[6:12]:
968            self.dataFrame.RefineCell.Enable(True)
969        else:
970            self.dataFrame.RefineCell.Enable(False)
971        data = [controls,bravais,cells,dmin]                   
972        self.PatternTree.SetItemPyData(UnitCellsId,data)
973       
974    if self.dataDisplay:
975        self.dataDisplay.Destroy()
976    self.dataFrame.SetMenuBar(self.dataFrame.IndexMenu)
977    if not self.dataFrame.GetStatusBar():
978        Status = self.dataFrame.CreateStatusBar()
979    self.Bind(wx.EVT_MENU, OnIndexPeaks, id=wxID_INDEXPEAKS)
980    self.Bind(wx.EVT_MENU, CopyUnitCell, id=wxID_COPYCELL)
981    self.Bind(wx.EVT_MENU, OnRefineCell, id=wxID_REFINECELL)
982    self.UnitCellsTable = []
983    controls,bravais,cells,dmin = data
984    if cells:
985        self.dataFrame.setSizePosLeft([900,320])
986    else:
987        self.dataFrame.setSizePosLeft([280,320])
988    if len(controls) < 13:
989        controls.append(G2cmp.calc_V(G2cmp.cell2A(controls[6:12])))
990    self.PatternTree.SetItemPyData(UnitCellsId,data)
991    inst = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,self.PatternId, 'Instrument Parameters'))[1]
992    if cells:
993        colLabels = ['controls','value','try','Bravais cells',
994            'M20','X20','use','Bravais','a','b','c','alpha','beta','gamma','Volume']
995        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_FLOAT+":10,1",
996            wg.GRID_VALUE_BOOL,wg.GRID_VALUE_STRING,wg.GRID_VALUE_FLOAT+':10,2',
997            wg.GRID_VALUE_NUMBER,wg.GRID_VALUE_BOOL,wg.GRID_VALUE_STRING,
998            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',
999            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_FLOAT+':10,3',
1000            wg.GRID_VALUE_FLOAT+':10,2']
1001    else:
1002        colLabels = ['controls','value','try','Bravais cells']
1003        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,
1004            wg.GRID_VALUE_BOOL,wg.GRID_VALUE_STRING]
1005    controlNames = ['Vary zero?','Max zero error','Max Nc/Nobs','Start volume','refine cell?',
1006        'bravais','a=','b=','c=','alpha=','beta=','gamma=','Volume=']
1007    bravaisNames = ['Cubic-F','Cubic-I','Cubic-P','Trigonal-R','Trigonal/Hexagonal-P',
1008        'Tetragonal-I','Tetragonal-P','Orthorhombic-F','Orthorhombic-I','Orthorhombic-C',
1009        'Orthorhombic-P','Monoclinic-C','Monoclinic-P','Triclinic']
1010    rowLabels = []
1011    table = []
1012    numRows = max(len(bravais),len(cells))
1013    for i in range(numRows):
1014        rowLabels.append('')
1015        if i < 13:
1016            row = [controlNames[i],controls[i],bravais[i],bravaisSymb[i]]
1017        elif i < 14:
1018            row = ['','',bravais[i],bravaisSymb[i]]
1019        else:
1020            row = ['','','','']
1021        if cells:
1022            if i < len(cells):
1023                cell = cells[i]
1024                row += cell[0:2]+[cell[-1]]+[bravaisSymb[cell[2]]]+cell[3:10]
1025                if cell[-1]:
1026                    A = G2cmp.cell2A(cell[3:9])
1027                    self.HKL = G2cmp.GenHBravais(dmin,cell[2],A)
1028                    for hkl in self.HKL:
1029                        hkl.append(2.0*asind(inst[1]/(2.*hkl[3])))
1030            else:
1031                row += 14*['',]
1032        table.append(row)
1033    self.UnitCellsTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1034    self.dataFrame.SetLabel('Unit Cells List')
1035    self.dataDisplay = GSGrid(parent=self.dataFrame)               
1036    self.dataDisplay.SetTable(self.UnitCellsTable, True)
1037    self.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshUnitCellsGrid)
1038    self.dataDisplay.SetMargins(0,0)
1039    self.dataDisplay.SetRowLabelSize(0)
1040    self.dataDisplay.SetCellRenderer(0,1,wg.GridCellBoolRenderer())
1041    self.dataDisplay.SetCellEditor(0,1,wg.GridCellBoolEditor())
1042    self.dataDisplay.SetCellRenderer(1,1,wg.GridCellFloatRenderer(5,2))
1043    self.dataDisplay.SetCellEditor(1,1,wg.GridCellFloatEditor(5,0))
1044    self.dataDisplay.SetCellRenderer(2,1,wg.GridCellNumberRenderer())
1045    self.dataDisplay.SetCellEditor(2,1,wg.GridCellNumberEditor(1,10))
1046    self.dataDisplay.SetCellRenderer(3,1,wg.GridCellFloatRenderer(5,0))
1047    self.dataDisplay.SetCellEditor(3,1,wg.GridCellFloatEditor(5,2))
1048    self.dataDisplay.SetCellRenderer(4,1,wg.GridCellBoolRenderer())
1049    self.dataDisplay.SetCellEditor(4,1,wg.GridCellBoolEditor())
1050    self.dataDisplay.SetCellRenderer(5,1,wg.GridCellStringRenderer())
1051    self.dataDisplay.SetCellEditor(5,1,wg.GridCellChoiceEditor(bravaisSymb,False))
1052    for i in range(6,9):
1053        self.dataDisplay.SetCellRenderer(i,1,wg.GridCellFloatRenderer(10,5))
1054        self.dataDisplay.SetCellEditor(i,1,wg.GridCellFloatEditor(10,5))
1055    for i in range(9,13):
1056        self.dataDisplay.SetCellRenderer(i,1,wg.GridCellFloatRenderer(10,3))
1057        self.dataDisplay.SetCellEditor(i,1,wg.GridCellFloatEditor(10,3))
1058    for i in range(14):
1059        self.dataDisplay.SetReadOnly(i,0,isReadOnly=True)
1060        self.dataDisplay.SetReadOnly(i,3,isReadOnly=True)
1061    if cells:
1062        self.dataFrame.CopyCell.Enable(True)
1063        for r in range(max(len(cells),14)):
1064            if r > 12:
1065                self.dataDisplay.SetCellRenderer(r,0,wg.GridCellStringRenderer())                   
1066                self.dataDisplay.SetCellRenderer(r,1,wg.GridCellStringRenderer())
1067            if r > 13:
1068                self.dataDisplay.SetCellRenderer(r,2,wg.GridCellStringRenderer())
1069            for c in range(4,15):
1070                if r >= len(cells):
1071                    self.dataDisplay.SetCellRenderer(r,c,wg.GridCellStringRenderer())
1072                if c != 6:
1073                    self.dataDisplay.SetReadOnly(r,c,isReadOnly=True)
1074    self.dataDisplay.AutoSizeColumns(False)
1075    if controls[4] and not False in controls[6:12]:
1076        self.dataFrame.RefineCell.Enable(True)
1077    else:
1078        self.dataFrame.RefineCell.Enable(False)
1079       
1080def UpdateHKLControls(self,data):
1081   
1082    def OnScaleSlider(event):
1083        scale = int(scaleSel.GetValue())/1000.
1084        scaleSel.SetValue(int(scale*1000.))
1085        data['Scale'] = scale*10.
1086        G2plt.PlotSngl(self)
1087       
1088    def OnLayerSlider(event):
1089        layer = layerSel.GetValue()
1090        data['Layer'] = layer
1091        G2plt.PlotSngl(self)
1092       
1093    def OnSelZone(event):
1094        data['Zone'] = zoneSel.GetValue()
1095        G2plt.PlotSngl(self,newPlot=True)
1096       
1097    def OnSelType(event):
1098        data['Type'] = typeSel.GetValue()
1099        G2plt.PlotSngl(self)
1100       
1101    def SetStatusLine():
1102        Status.SetStatusText("look at me!!!")
1103                                     
1104    if self.dataDisplay:
1105        self.dataDisplay.Destroy()
1106    if not self.dataFrame.GetStatusBar():
1107        Status = self.dataFrame.CreateStatusBar()
1108    SetStatusLine()
1109    zones = ['100','010','001']
1110    HKLmax = data['HKLmax']
1111    HKLmin = data['HKLmin']
1112    if data['ifFc']:
1113        typeChoices = ['Fosq','Fo','|DFsq|/sig','|DFsq|>sig','|DFsq|>3sig']
1114    else:
1115        typeChoices = ['Fosq','Fo']
1116    self.dataDisplay = wx.Panel(self.dataFrame)
1117    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1118    mainSizer = wx.BoxSizer(wx.VERTICAL)
1119    mainSizer.Add((5,10),0)
1120   
1121    scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
1122    scaleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Scale'),0,
1123        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1124    scaleSel = wx.Slider(parent=self.dataDisplay,maxValue=1000,minValue=100,
1125        style=wx.SL_HORIZONTAL,value=int(data['Scale']*100))
1126    scaleSizer.Add(scaleSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1127    scaleSel.SetLineSize(100)
1128    scaleSel.SetPageSize(900)
1129    scaleSel.Bind(wx.EVT_SLIDER, OnScaleSlider)
1130    mainSizer.Add(scaleSizer,1,wx.EXPAND|wx.RIGHT)
1131   
1132    zoneSizer = wx.BoxSizer(wx.HORIZONTAL)
1133    zoneSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Zone  '),0,
1134        wx.ALIGN_CENTER_VERTICAL)
1135    zoneSel = wx.ComboBox(parent=self.dataDisplay,value=data['Zone'],choices=['100','010','001'],
1136        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1137    zoneSel.Bind(wx.EVT_COMBOBOX, OnSelZone)
1138    zoneSizer.Add(zoneSel,0,wx.ALIGN_CENTER_VERTICAL)
1139    zoneSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Plot type  '),0,
1140        wx.ALIGN_CENTER_VERTICAL)       
1141    typeSel = wx.ComboBox(parent=self.dataDisplay,value=data['Type'],choices=typeChoices,
1142        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1143    typeSel.Bind(wx.EVT_COMBOBOX, OnSelType)
1144    zoneSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
1145    zoneSizer.Add((10,0),0)   
1146    mainSizer.Add(zoneSizer,1,wx.EXPAND|wx.RIGHT)
1147       
1148    izone = zones.index(data['Zone'])
1149    layerSizer = wx.BoxSizer(wx.HORIZONTAL)
1150    layerSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Layer'),0,
1151        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1152    layerSel = wx.Slider(parent=self.dataDisplay,maxValue=HKLmax[izone],minValue=HKLmin[izone],
1153        style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS,value=0)
1154    layerSel.SetLineSize(1)
1155    layerSel.SetLineSize(5)
1156    layerSel.Bind(wx.EVT_SLIDER, OnLayerSlider)   
1157    layerSizer.Add(layerSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1158    layerSizer.Add((10,0),0)   
1159    mainSizer.Add(layerSizer,1,wx.EXPAND|wx.RIGHT)
1160
1161       
1162    mainSizer.Layout()   
1163    self.dataDisplay.SetSizer(mainSizer)
1164    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
1165    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
1166       
1167def UpdateImageControls(self,data):
1168    import ImageCalibrants as calFile
1169   
1170    def OnNewColorBar(event):
1171        data['color'] = colSel.GetValue()
1172        G2plt.PlotExposedImage(self)
1173       
1174    def OnNewCalibrant(event):
1175        data['calibrant'] = calSel.GetValue()
1176       
1177    def OnPixLimit(event):
1178        data['pixLimit'] = int(pixLimit.GetValue())
1179       
1180    def OnMaxSlider(event):
1181        logDeltZero = math.log(data['range'][0][1]-data['range'][0][0])
1182        imax = int(maxSel.GetValue())*logDeltZero/100.
1183        data['range'][1][1] = math.exp(imax)+data['range'][0][0]
1184        data['range'][1][0] = min(data['range'][1][1]-1,data['range'][1][0])
1185        G2plt.PlotExposedImage(self)
1186       
1187    def OnMinSlider(event):
1188        DeltOne = data['range'][1][1]-data['range'][0][0]
1189        imin = int(minSel.GetValue())*DeltOne/100.
1190        data['range'][1][0] = min(data['range'][1][1]-1,imin+data['range'][0][0])
1191        G2plt.PlotExposedImage(self)
1192       
1193    def OnNumOutChans(event):
1194        try:
1195            numChans = int(outChan.GetValue())
1196            if numChans < 1:
1197                raise ValueError
1198            data['outChannels'] = numChans
1199        except ValueError:
1200            pass
1201        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
1202        outChan.SetValue(str(data['outChannels']))          #reset in case of error       
1203       
1204    def OnNumOutAzms(event):
1205        try:
1206            numAzms = int(outAzim.GetValue())
1207            if numAzms < 1:
1208                raise ValueError
1209            data['outAzimuths'] = numAzms           
1210        except ValueError:
1211            pass
1212        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
1213        outAzim.SetValue(str(data['outAzimuths']))          #reset in case of error       
1214       
1215    def OnWavelength(event):
1216        try:
1217            wave = float(waveSel.GetValue())
1218            if wave < .01:
1219                raise ValueError
1220            data['wavelength'] = wave
1221        except ValueError:
1222            pass
1223        waveSel.SetValue("%6.5f" % (data['wavelength']))          #reset in case of error         
1224       
1225    def OnCutOff(event):
1226        try:
1227            cutoff = float(cutOff.GetValue())
1228            data['cutoff'] = cutoff
1229        except ValueError:
1230            pass
1231        cutOff.SetValue("%.1f"%(data['cutoff']))          #reset in case of error 
1232       
1233    def OnShowLines(event):
1234        if data['showLines']:
1235            data['showLines'] = False
1236        else:
1237            data['showLines'] = True
1238        G2plt.PlotExposedImage(self)
1239       
1240    def OnFullIntegrate(event):
1241        if data['fullIntegrate']:
1242            data['fullIntegrate'] = False
1243            self.Lazim.SetEditable(True)           
1244            self.Razim.SetEditable(True)           
1245        else:
1246            data['fullIntegrate'] = True
1247            self.Lazim.SetEditable(False)           
1248            self.Razim.SetEditable(False)           
1249        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
1250        G2plt.PlotExposedImage(self)
1251       
1252    def OnSetDefault(event):
1253        import copy
1254        if data['setDefault']:
1255            self.imageDefault = {}
1256            data['setDefault'] = False
1257        else:
1258            self.imageDefault = copy.copy(data)
1259            data['setDefault'] = True
1260           
1261    def OnIOtth(event):
1262        Ltth = float(self.InnerTth.GetValue())
1263        Utth = float(self.OuterTth.GetValue())
1264        if Ltth > Utth:
1265            G2cmp.SwapXY(Ltth,Utth)
1266        data['IOtth'] = [Ltth,Utth]
1267        self.InnerTth.SetValue("%8.2f" % (Ltth))
1268        self.OuterTth.SetValue("%8.2f" % (Utth))
1269        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
1270        G2plt.PlotExposedImage(self)
1271       
1272    def OnLRazim(event):
1273        Lazm = int(self.Lazim.GetValue())
1274        Razm = int(self.Razim.GetValue())
1275        data['LRazimuth'] = [Lazm,Razm]
1276        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
1277        G2plt.PlotExposedImage(self)
1278           
1279    def OnSetRings(event):
1280        if data['setRings']:
1281            data['setRings'] = False
1282        else:
1283            data['setRings'] = True
1284        setRings.SetValue(data['setRings'])
1285        G2plt.PlotExposedImage(self)
1286           
1287    def OnClearCalib(event):
1288        data['ring'] = []
1289        data['rings'] = []
1290        data['ellipses'] = []
1291        self.dataFrame.ImageEdit.Enable(id=wxID_IMCLEARCALIB,enable=False)   
1292        G2plt.PlotExposedImage(self)
1293           
1294    def OnCalibrate(event):       
1295        data['setRings'] = False
1296        setRings.SetValue(data['setRings'])
1297        msg = \
1298        '''Select > 4 points on inner ring of image pattern.
1299        Click right mouse button to select point.
1300          Use left mouse button to delete point.
1301                 Press OK when done'''
1302        dlg = wx.MessageDialog(self,msg,'Pick inner ring',wx.OK)
1303        self.ifGetRing = True
1304        dlg.ShowModal()
1305        self.ifGetRing = False
1306       
1307        if G2cmp.ImageCalibrate(self,data):
1308            Status.SetStatusText('Calibration successful')
1309            cent = data['center']
1310            centText.SetValue(("%8.3f,%8.3f" % (cent[0],cent[1])))
1311            distSel.SetValue("%8.3f"%(data['distance']))
1312            tiltSel.SetValue("%9.3f"%(data['tilt']))           
1313            rotSel.SetValue("%9.3f"%(data['rotation']))
1314            self.dataFrame.ImageEdit.Enable(id=wxID_IMCLEARCALIB,enable=True)   
1315        else:
1316            Status.SetStatusText('Calibration failed')
1317                   
1318    def OnIntegrate(event):
1319        G2cmp.ImageIntegrate(self,data)
1320        G2plt.PlotIntegration(self,newPlot=True)
1321        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=True)
1322       
1323    def OnIntegrateAll(event):
1324        print 'integrate all'
1325        TextList = []
1326        Names = []
1327        if self.PatternTree.GetCount():
1328            id, cookie = self.PatternTree.GetFirstChild(self.root)
1329            while id:
1330                name = self.PatternTree.GetItemText(id)
1331                Names.append(name)
1332                if 'IMG' in name:
1333                    TextList.append([False,name,id])
1334                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1335            if not len(TextList):
1336                self.ErrorDialog('Nothing to integrate','There must some "IMG" patterns')
1337                return
1338            dlg = self.CopyDialog(self,'Image integration controls','Select images to integrate:',TextList)
1339            try:
1340                if dlg.ShowModal() == wx.ID_OK:
1341                    result = dlg.GetData()
1342                    for item in result:
1343                        ifintegrate,name,id = item
1344                        if ifintegrate:
1345                            id = GetPatternTreeItemId(self, self.root, name)
1346                            size,imagefile = self.PatternTree.GetItemPyData(id)
1347                            self.ImageZ = G2IO.GetImageData(imagefile,imageOnly=True)
1348                            Id = GetPatternTreeItemId(self,id, 'Image Controls')
1349                            Data = self.PatternTree.GetItemPyData(Id)
1350                            G2cmp.ImageIntegrate(self,Data)
1351                            G2plt.PlotIntegration(self,newPlot=True)
1352                            self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=True)
1353                            G2IO.SaveIntegration(self,Id,Data)
1354            finally:
1355                dlg.Destroy()
1356       
1357    def OnSaveIntegrate(event):
1358        print 'save integration'
1359        G2IO.SaveIntegration(self,self.PickId,data)
1360           
1361    def OnCopyControls(event):
1362        TextList = []
1363        Names = []
1364        if self.PatternTree.GetCount():
1365            id, cookie = self.PatternTree.GetFirstChild(self.root)
1366            while id:
1367                name = self.PatternTree.GetItemText(id)
1368                Names.append(name)
1369                if 'IMG' in name:
1370                    if id == self.Image:
1371                        Source = name
1372                        Data = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,id, 'Image Controls'))
1373                        Data['showLines'] = True
1374                        Data['ring'] = []
1375                        Data['rings'] = []
1376                        Data['cutoff'] = 10
1377                        Data['pixLimit'] = 20
1378                        Data['ellipses'] = []
1379                        Data['calibrant'] = ''
1380                        Data['setDefault'] = False
1381                    else:
1382                        TextList.append([False,name,id])
1383                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1384            if not len(TextList):
1385                self.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
1386                return
1387            dlg = self.CopyDialog(self,'Copy image controls','Copy controls from '+Source+' to:',TextList)
1388            try:
1389                if dlg.ShowModal() == wx.ID_OK:
1390                    result = dlg.GetData()
1391                    for i,item in enumerate(result[:-1]):
1392                        ifcopy,name,id = item
1393                        if ifcopy:
1394                            oldData = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,id, 'Image Controls'))
1395                            Data['range'] = oldData['range']                               
1396                            self.PatternTree.SetItemPyData(GetPatternTreeItemId(self,id, 'Image Controls'),Data)
1397            finally:
1398                dlg.Destroy()
1399                                       
1400    colorList = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
1401    calList = [m for m in calFile.Calibrants.keys()]
1402    if self.dataDisplay:
1403        self.dataDisplay.Destroy()
1404    self.dataFrame.SetMenuBar(self.dataFrame.ImageMenu)
1405    if not self.dataFrame.GetStatusBar():
1406        Status = self.dataFrame.CreateStatusBar()
1407    self.dataFrame.Bind(wx.EVT_MENU, OnCalibrate, id=wxID_IMCALIBRATE)
1408    self.dataFrame.Bind(wx.EVT_MENU, OnClearCalib, id=wxID_IMCLEARCALIB)
1409    if not data['rings']:
1410        self.dataFrame.ImageEdit.Enable(id=wxID_IMCLEARCALIB,enable=False)   
1411    self.dataFrame.Bind(wx.EVT_MENU, OnIntegrate, id=wxID_IMINTEGRATE)
1412    self.dataFrame.Bind(wx.EVT_MENU, OnIntegrateAll, id=wxID_INTEGRATEALL)
1413    self.dataFrame.Bind(wx.EVT_MENU, OnSaveIntegrate, id=wxID_SAVEINTG)
1414    self.dataFrame.Bind(wx.EVT_MENU, OnCopyControls, id=wxID_IMCOPYCONTROLS)
1415    self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
1416    self.dataDisplay = wx.Panel(self.dataFrame)
1417    mainSizer = wx.BoxSizer(wx.VERTICAL)
1418    mainSizer.Add((5,10),0)
1419   
1420    maxSizer = wx.FlexGridSizer(2,2,0,5)
1421    maxSizer.AddGrowableCol(1,1)
1422    logDeltZero = math.log(data['range'][0][1]-data['range'][0][0])
1423    DeltOne = data['range'][1][1]-data['range'][0][0]
1424    logDeltOne = math.log(DeltOne)
1425    maxSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Max intensity'),0,
1426        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1427    maxSel = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
1428        value=int(100*logDeltOne/logDeltZero))
1429    maxSizer.Add(maxSel,1,wx.EXPAND|wx.RIGHT)
1430    maxSel.Bind(wx.EVT_SLIDER, OnMaxSlider)   
1431    maxSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min intensity'),0,
1432        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1433    minSel = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
1434        value=int(100*data['range'][1][0]/DeltOne))
1435    maxSizer.Add(minSel,1,wx.EXPAND|wx.RIGHT)
1436    minSel.Bind(wx.EVT_SLIDER, OnMinSlider)
1437    mainSizer.Add(maxSizer,1,wx.EXPAND|wx.RIGHT)
1438   
1439    comboSizer = wx.BoxSizer(wx.HORIZONTAL)
1440    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Color bar '),0,
1441        wx.ALIGN_CENTER_VERTICAL)
1442    colSel = wx.ComboBox(parent=self.dataDisplay,value=data['color'],choices=colorList,
1443        style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
1444    colSel.Bind(wx.EVT_COMBOBOX, OnNewColorBar)
1445    comboSizer.Add(colSel,0,wx.ALIGN_CENTER_VERTICAL)
1446   
1447    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibrant '),0,
1448        wx.ALIGN_CENTER_VERTICAL)
1449    calSel = wx.ComboBox(parent=self.dataDisplay,value=data['calibrant'],choices=calList,
1450        style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
1451    calSel.Bind(wx.EVT_COMBOBOX, OnNewCalibrant)
1452    comboSizer.Add(calSel,0,wx.ALIGN_CENTER_VERTICAL)
1453    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Pixel search range '),0,
1454        wx.ALIGN_CENTER_VERTICAL)
1455    pixLimit = wx.ComboBox(parent=self.dataDisplay,value=str(data['pixLimit']),choices=['1','2','5','10','15','20'],
1456        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1457    pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
1458    comboSizer.Add(pixLimit,0,wx.ALIGN_CENTER_VERTICAL)
1459    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min ring I/Ib '),0,
1460        wx.ALIGN_CENTER_VERTICAL)
1461    cutOff = wx.TextCtrl(parent=self.dataDisplay,value=("%.1f" % (data['cutoff'])),
1462        style=wx.TE_PROCESS_ENTER)
1463    cutOff.Bind(wx.EVT_TEXT,OnCutOff)
1464    comboSizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL)
1465
1466    mainSizer.Add(comboSizer,0,wx.ALIGN_CENTER_HORIZONTAL)
1467    mainSizer.Add((5,5),0)
1468         
1469    dataSizer = wx.FlexGridSizer(6,4,5,5)
1470    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibration coefficients'),0,
1471        wx.ALIGN_CENTER_VERTICAL)   
1472    dataSizer.Add((5,0),0)
1473    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Integration coefficients'),0,
1474        wx.ALIGN_CENTER_VERTICAL)   
1475    dataSizer.Add((5,0),0)
1476   
1477    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Beam center X,Y'),0,
1478        wx.ALIGN_CENTER_VERTICAL)
1479    cent = data['center']
1480    centText = wx.TextCtrl(parent=self.dataDisplay,value=("%8.3f,%8.3f" % (cent[0],cent[1])),style=wx.TE_READONLY)
1481    dataSizer.Add(centText,0,wx.ALIGN_CENTER_VERTICAL)
1482   
1483    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Inner/Outer 2-theta'),0,
1484        wx.ALIGN_CENTER_VERTICAL)
1485       
1486    IOtth = data['IOtth']
1487    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
1488    self.InnerTth = wx.TextCtrl(parent=self.dataDisplay,
1489        value=("%8.2f" % (IOtth[0])),style=wx.TE_PROCESS_ENTER)
1490    self.InnerTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
1491    littleSizer.Add(self.InnerTth,0,wx.ALIGN_CENTER_VERTICAL)
1492    self.OuterTth = wx.TextCtrl(parent=self.dataDisplay,
1493        value=("%8.2f" % (IOtth[1])),style=wx.TE_PROCESS_ENTER)
1494    self.OuterTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
1495    littleSizer.Add(self.OuterTth,0,wx.ALIGN_CENTER_VERTICAL)
1496    dataSizer.Add(littleSizer,0,)
1497       
1498    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Wavelength'),0,
1499        wx.ALIGN_CENTER_VERTICAL)
1500    waveSel = wx.TextCtrl(parent=self.dataDisplay,value=("%6.5f" % (data['wavelength'])),
1501        style=wx.TE_PROCESS_ENTER)
1502    waveSel.Bind(wx.EVT_TEXT_ENTER,OnWavelength)
1503    dataSizer.Add(waveSel,0,wx.ALIGN_CENTER_VERTICAL)
1504         
1505    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Start/End azimuth'),0,
1506        wx.ALIGN_CENTER_VERTICAL)
1507    LRazim = data['LRazimuth']
1508    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
1509    self.Lazim = wx.TextCtrl(parent=self.dataDisplay,
1510        value=("%6d" % (LRazim[0])),style=wx.TE_PROCESS_ENTER)
1511    self.Lazim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
1512    littleSizer.Add(self.Lazim,0,wx.ALIGN_CENTER_VERTICAL)
1513    self.Razim = wx.TextCtrl(parent=self.dataDisplay,
1514        value=("%6d" % (LRazim[1])),style=wx.TE_PROCESS_ENTER)
1515    self.Razim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
1516    littleSizer.Add(self.Razim,0,wx.ALIGN_CENTER_VERTICAL)
1517    dataSizer.Add(littleSizer,0,)
1518       
1519    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Distance'),0,
1520        wx.ALIGN_CENTER_VERTICAL)
1521    distSel = wx.TextCtrl(parent=self.dataDisplay,value=("%8.3f"%(data['distance'])),style=wx.TE_READONLY)
1522    dataSizer.Add(distSel,0,wx.ALIGN_CENTER_VERTICAL)
1523
1524    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' No. 2-theta/azimuth bins'),0,
1525        wx.ALIGN_CENTER_VERTICAL)
1526    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
1527    outChan = wx.TextCtrl(parent=self.dataDisplay,value=str(data['outChannels']),style=wx.TE_PROCESS_ENTER)
1528    outChan.Bind(wx.EVT_TEXT_ENTER,OnNumOutChans)
1529    littleSizer.Add(outChan,0,wx.ALIGN_CENTER_VERTICAL)
1530    outAzim = wx.TextCtrl(parent=self.dataDisplay,value=str(data['outAzimuths']),style=wx.TE_PROCESS_ENTER)
1531    outAzim.Bind(wx.EVT_TEXT_ENTER,OnNumOutAzms)
1532    littleSizer.Add(outAzim,0,wx.ALIGN_CENTER_VERTICAL)
1533    dataSizer.Add(littleSizer,0,)
1534
1535    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Tilt angle'),0,
1536        wx.ALIGN_CENTER_VERTICAL)
1537    tiltSel = wx.TextCtrl(parent=self.dataDisplay,value=("%9.3f"%(data['tilt'])),style=wx.TE_READONLY)
1538    dataSizer.Add(tiltSel,0,wx.ALIGN_CENTER_VERTICAL)
1539    showLines = wx.CheckBox(parent=self.dataDisplay,label='Show integration limits?')
1540    dataSizer.Add(showLines,0)
1541    showLines.Bind(wx.EVT_CHECKBOX, OnShowLines)
1542    showLines.SetValue(data['showLines'])
1543    fullIntegrate = wx.CheckBox(parent=self.dataDisplay,label='Do full integration?')
1544    dataSizer.Add(fullIntegrate,0)
1545    fullIntegrate.Bind(wx.EVT_CHECKBOX, OnFullIntegrate)
1546    fullIntegrate.SetValue(data['fullIntegrate'])
1547   
1548    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Tilt rotation'),0,
1549        wx.ALIGN_CENTER_VERTICAL)
1550    rotSel = wx.TextCtrl(parent=self.dataDisplay,value=("%9.3f"%(data['rotation'])),style=wx.TE_READONLY)
1551    dataSizer.Add(rotSel,0,wx.ALIGN_CENTER_VERTICAL)
1552    setDefault = wx.CheckBox(parent=self.dataDisplay,label='Use as default for all images?')
1553    dataSizer.Add(setDefault,0)
1554    setDefault.Bind(wx.EVT_CHECKBOX, OnSetDefault)
1555    setDefault.SetValue(data['setDefault'])
1556    setRings = wx.CheckBox(parent=self.dataDisplay,label='Show ring picks?')
1557    dataSizer.Add(setRings,0)
1558    setRings.Bind(wx.EVT_CHECKBOX, OnSetRings)
1559    setRings.SetValue(data['setRings'])
1560       
1561    mainSizer.Add(dataSizer,0)
1562   
1563    mainSizer.Layout()   
1564    self.dataDisplay.SetSizer(mainSizer)
1565    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
1566    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
1567   
1568def UpdateMasks(self,data):
1569   
1570    def OnThreshold(event):
1571        lower = max(int(self.lowerThreshold.GetValue()),thresh[0][0])
1572        upper = min(int(self.upperThreshold.GetValue()),thresh[0][1])
1573        data['Thresholds'][1] = [lower,upper]
1574        self.lowerThreshold.SetValue("%8d" % (lower))
1575        self.upperThreshold.SetValue("%8d" % (upper))
1576        G2plt.PlotExposedImage(self)
1577       
1578    def OnCopyMask(event):
1579        TextList = []
1580        Names = []
1581        if self.PatternTree.GetCount():
1582            id, cookie = self.PatternTree.GetFirstChild(self.root)
1583            while id:
1584                name = self.PatternTree.GetItemText(id)
1585                Names.append(name)
1586                if 'IMG' in name:
1587                    if id == self.Image:
1588                        Source = name
1589                        mask = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,id, 'Masks'))
1590                    else:
1591                        TextList.append([False,name,id])
1592                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1593            if not len(TextList):
1594                self.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
1595                return
1596            dlg = self.CopyDialog(self,'Copy mask information','Copy mask from '+Source+' to:',TextList)
1597            try:
1598                if dlg.ShowModal() == wx.ID_OK:
1599                    result = dlg.GetData()
1600                    for i,item in enumerate(result[:-1]):
1601                        ifcopy,name,id = item
1602                        if ifcopy:                               
1603                            self.PatternTree.SetItemPyData(GetPatternTreeItemId(self,id, 'Masks'),mask)
1604            finally:
1605                dlg.Destroy()
1606       
1607    if self.dataDisplay:
1608        self.dataDisplay.Destroy()
1609    self.dataFrame.SetMenuBar(self.dataFrame.MaskMenu)
1610    self.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=wxID_MASKCOPY)
1611    if not self.dataFrame.GetStatusBar():
1612        Status = self.dataFrame.CreateStatusBar()
1613    self.dataDisplay = wx.Panel(self.dataFrame)
1614    mainSizer = wx.BoxSizer(wx.VERTICAL)
1615    mainSizer.Add((5,10),0)
1616
1617    thresh = data['Thresholds']
1618    littleSizer = wx.FlexGridSizer(2,3,0,5)
1619    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper limits '),0,
1620        wx.ALIGN_CENTER_VERTICAL)
1621    littleSizer.Add(wx.TextCtrl(parent=self.dataDisplay,
1622        value=("%8d" % (thresh[0][0])),style=wx.TE_READONLY),0,wx.ALIGN_CENTER_VERTICAL)
1623    littleSizer.Add(wx.TextCtrl(parent=self.dataDisplay,
1624        value=("%8d" % (thresh[0][1])),style=wx.wx.TE_READONLY),0,wx.ALIGN_CENTER_VERTICAL)
1625   
1626    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper thresholds '),0,
1627        wx.ALIGN_CENTER_VERTICAL)
1628    self.lowerThreshold = wx.TextCtrl(parent=self.dataDisplay,
1629        value=("%8d" % (thresh[1][0])),style=wx.TE_PROCESS_ENTER)
1630    self.lowerThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
1631    littleSizer.Add(self.lowerThreshold,0,wx.ALIGN_CENTER_VERTICAL)
1632    self.upperThreshold = wx.TextCtrl(parent=self.dataDisplay,
1633        value=("%8d" % (thresh[1][1])),style=wx.TE_PROCESS_ENTER)
1634    self.upperThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
1635    littleSizer.Add(self.upperThreshold,0,wx.ALIGN_CENTER_VERTICAL)
1636    mainSizer.Add(littleSizer,0,)
1637       
1638
1639
1640    mainSizer.Layout()   
1641    self.dataDisplay.SetSizer(mainSizer)
1642    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
1643    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))   
1644   
1645def UpdatePhaseData(self,item,data,oldPage):
1646    import GSASIIElem as G2el
1647    Atoms = []
1648    self.SelectedRow = 0
1649   
1650    def BookResize(event):
1651        w,h = self.GetSize()
1652        self.dataDisplay.SetSize(wx.Size(w,h))
1653       
1654    def FillGeneralGrid():
1655        def SetLatticeParametersStyle(SGData,table):
1656            if SGData['SGLaue'] in ['m3','m3m']:
1657                table[4][2] = table[4][3] = table[4][1]
1658                General.SetCellStyle(4,2,"light grey",True)
1659                General.SetCellStyle(4,3,"light grey",True)
1660                table[4][4] = table[4][5] = table[4][6] = 90.
1661                General.SetCellStyle(4,4,"light grey",True)
1662                General.SetCellStyle(4,5,"light grey",True)
1663                General.SetCellStyle(4,6,"light grey",True)
1664            elif SGData['SGLaue'] in ['3R','3mR']:
1665                table[4][2] = table[4][3] = table[4][1]
1666                General.SetCellStyle(4,2,"light grey",True)
1667                General.SetCellStyle(4,3,"light grey",True)
1668                table[4][5] = table[4][6] = table[4][4]
1669                General.SetCellStyle(4,5,"light grey",True)
1670                General.SetCellStyle(4,6,"light grey",True)
1671            elif SGData['SGLaue'] in ['3','3m1','31m','6/m','6/mmm']:
1672                table[4][2] = table[4][1]
1673                General.SetCellStyle(4,2,"light grey",True)
1674                table[4][4] = table[4][5] = 90.
1675                table[4][6] = 120.
1676                General.SetCellStyle(4,4,"light grey",True)
1677                General.SetCellStyle(4,5,"light grey",True)
1678                General.SetCellStyle(4,6,"light grey",True)
1679            elif SGData['SGLaue'] in ['4/m','4/mmm']:
1680                table[4][2] = table[4][1]
1681                General.SetCellStyle(4,2,"light grey",True)
1682                table[4][4] = table[4][5] = table[4][6] = 90.
1683                General.SetCellStyle(4,4,"light grey",True)
1684                General.SetCellStyle(4,5,"light grey",True)
1685                General.SetCellStyle(4,6,"light grey",True)
1686            elif SGData['SGLaue'] in ['mmm']:
1687                table[4][4] = table[4][5] = table[4][6] = 90.
1688                General.SetCellStyle(4,4,"light grey",True)
1689                General.SetCellStyle(4,5,"light grey",True)
1690                General.SetCellStyle(4,6,"light grey",True)
1691            elif SGData['SGLaue'] in ['2/m']:
1692                if SGData['SGUniq'] == 'a':
1693                    table[4][5]= table[4][6] = 90.
1694                    General.SetCellStyle(4,5,"light grey",True)
1695                    General.SetCellStyle(4,6,"light grey",True)
1696                if SGData['SGUniq'] == 'b':
1697                    table[4][4]= table[4][6] = 90.
1698                    General.SetCellStyle(4,4,"light grey",True)
1699                    General.SetCellStyle(4,6,"light grey",True)
1700                if SGData['SGUniq'] == 'c':
1701                    table[4][4]= table[4][5] = 90.
1702                    General.SetCellStyle(4,4,"light grey",True)
1703                    General.SetCellStyle(4,5,"light grey",True)
1704           
1705        def RefreshGeneralGrid(event):
1706               
1707            r,c =  event.GetRow(),event.GetCol()
1708            generalData[0] = table[0][0]
1709            self.PatternTree.SetItemText(item,generalData[0])
1710            generalData[1] = table[1][0]
1711            SpcGp = table[2][0]
1712            SGErr,SGData = G2spc.SpcGroup(SpcGp)
1713            if r == 2 and c == 0:
1714                if SGErr:
1715                    text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous']
1716                    table[2][0] = generalData[2]['SpGrp']
1717                    msg = 'Space Group Error'
1718                    Style = wx.ICON_EXCLAMATION
1719                else:
1720                    text = G2spc.SGPrint(SGData)
1721                    generalData[2] = SGData
1722                    msg = 'Space Group Information'
1723                    Style = wx.ICON_INFORMATION
1724                Text = ''
1725                for line in text:
1726                    Text += line+'\n'
1727                wx.MessageBox(Text,caption=msg,style=Style)
1728            General.SetCellValue(4,0,str(generalData[3][0]))
1729            for c in range(1,7):
1730                General.SetCellStyle(4,c,"white",False)
1731                generalData[3][c] = float(General.GetCellValue(4,c))
1732            generalData[3][7] = G2cmp.calc_V(G2cmp.cell2A(generalData[3][1:7]))
1733            SetLatticeParametersStyle(SGData,table)
1734            generalData[4][1] = float(General.GetCellValue(5,1))
1735            General.ForceRefresh()
1736                       
1737        rowLabels = ['Phase name','Phase type','Space group',
1738            'Lattice ',' parameters','Scale factor','Elements','No. per cell','Atom weight','','Bond radii','Angle radii']
1739        generalData = data['General']
1740        atomData = data['Atoms']
1741        AtomTypes = []
1742        NoAtoms = {}
1743        BondRadii = []
1744        AngleRadii = []
1745        AtomMass = []
1746        colType = 1
1747        colSS = 7
1748        self.dataFrame.setSizePosLeft([600,350])
1749        if generalData[1] =='macromolecular':
1750            colType = 4
1751            colSS = 10
1752        for atom in atomData:
1753            if AtomTypes.count(atom[colType]):
1754                NoAtoms[atom[colType]] += atom[colSS-1]*atom[colSS+1]
1755            else:
1756                Info = G2el.GetAtomInfo(atom[colType])
1757                AtomTypes.append(Info['Symbol'])
1758                BondRadii.append(Info['Drad'])
1759                AngleRadii.append(Info['Arad'])
1760                AtomMass.append(Info['Mass'])
1761                NoAtoms[atom[colType]] = atom[colSS-1]*atom[colSS+1]
1762        generalData[5:9] = [AtomTypes,NoAtoms,AtomMass,BondRadii,AngleRadii]
1763        colLabels = []
1764        colLabels += ['' for i in range(max(8,len(generalData[5])))]
1765        table = []
1766        table.append([generalData[0],'','','','','','','',''])      #phase name
1767        table.append([generalData[1],'','','','','','','',''])      #phase type
1768        E,SGData = G2spc.SpcGroup(generalData[2]['SpGrp'])
1769        table.append([SGData['SpGrp'],'','','','','','','',''])     #space group symbol
1770        table.append(['refine','a    ','b    ','c    ','alpha ','beta ','gamma','volume  '])
1771        table.append(generalData[3])                      #lattice parameters
1772        table.append([generalData[4][0],generalData[4][1],'','','','','',''])   #scale factor
1773        table.append(generalData[5]+['' for i in range(max(8,len(generalData[5])))]) #element list
1774        line = []
1775        mass = 0.
1776        for i,elem in enumerate(generalData[5]):
1777            mass += generalData[6][elem]*generalData[7][i]
1778            line.append(generalData[6][elem])
1779        Volume = generalData[3][7]
1780        table.append(line+['' for i in range(max(8,len(generalData[5])))]) #No. per cell
1781        table.append(generalData[7]+['' for i in range(max(8,len(generalData[5])))])  #At. wt.
1782        if generalData[1] == 'macromolecular' and mass > 0.0:
1783            table.append(['density',mass/(0.6022137*Volume),'Matthews coeff.',Volume/mass,'','','','',''])           
1784        else:
1785            table.append(['density',mass/(0.6022137*Volume),'','','','','','',''])
1786        table.append(generalData[8]+['' for i in range(max(8,len(generalData[5])))])
1787        table.append(generalData[9]+['' for i in range(max(8,len(generalData[5])))])
1788        Types = [wg.GRID_VALUE_STRING for i in range(max(8,len(generalData[5])))]
1789        generalTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1790        General.SetTable(generalTable, True)
1791        General.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshGeneralGrid)
1792        General.SetMargins(0,0)
1793        General.SetColSize(0,100)
1794        General.SetColLabelSize(0)
1795        for c in range(max(8,len(generalData[5]))):
1796            if c > 0:
1797                General.SetReadOnly(0,c,isReadOnly=True)
1798                General.SetReadOnly(1,c,isReadOnly=True)
1799                General.SetReadOnly(2,c,isReadOnly=True)
1800            General.SetReadOnly(3,c,isReadOnly=True)                         #unit cell labels
1801            General.SetCellAlignment(3,c,wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
1802            if c < 4:
1803                General.SetCellRenderer(4,c,wg.GridCellFloatRenderer(10,5))
1804                General.SetCellEditor(4,c,wg.GridCellFloatEditor(10,5))
1805                General.SetReadOnly(9,c,isReadOnly=True)
1806            else:
1807                General.SetCellRenderer(4,c,wg.GridCellFloatRenderer(10,3))
1808                General.SetCellEditor(4,c,wg.GridCellFloatEditor(10,3))
1809            for r in range(6,12):
1810                General.SetReadOnly(r,c,isReadOnly=True)
1811        General.SetReadOnly(4,7,isReadOnly=True)                            #cell volume - no edit
1812        General.SetCellEditor(1,0,wg.GridCellChoiceEditor(['nuclear','modulated',   #phase type
1813            'magnetic','macromolecular','Pawley'],False))                           #- change only if no atoms
1814        if line:                                                    #no.of atoms not zero!
1815            General.SetReadOnly(1,0,isReadOnly=True)                #can't change phase type
1816        General.SetCellRenderer(4,0,wg.GridCellBoolRenderer())              #lattice parameters           
1817        General.SetCellEditor(4,0,wg.GridCellBoolEditor())
1818        SetLatticeParametersStyle(SGData,table)
1819        General.SetCellRenderer(5,1,wg.GridCellFloatRenderer(10,4))         #scale factor
1820        General.SetCellEditor(5,1,wg.GridCellFloatEditor(10,4))
1821        General.SetCellRenderer(5,0,wg.GridCellBoolRenderer())           
1822        General.SetCellEditor(5,0,wg.GridCellBoolEditor())
1823        General.SetCellRenderer(9,1,wg.GridCellFloatRenderer(8,3))
1824        General.SetCellRenderer(9,3,wg.GridCellFloatRenderer(8,3))
1825   
1826    def FillAtomsGrid():
1827       
1828        def RefreshAtomGrid(event):
1829            r,c =  event.GetRow(),event.GetCol()
1830            if r < 0:                          #on col label!
1831                sel = -1
1832                if Atoms.GetColLabelValue(c) == 'refine':
1833                    choice = ['F - site fraction','X - coordinates','U - thermal parameters']
1834                    dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice)
1835                    if dlg.ShowModal() == wx.ID_OK:
1836                        sel = dlg.GetSelections()
1837                        parms = ''
1838                        for x in sel:
1839                            parms += choice[x][0]                           
1840                elif Atoms.GetColLabelValue(c) == 'I/A':
1841                    choice = ['Isotropic','Anisotropic']
1842                    dlg = wx.SingleChoiceDialog(self,'Select','Thermal Motion',choice)
1843                    if dlg.ShowModal() == wx.ID_OK:
1844                        sel = dlg.GetSelection()
1845                        parms = choice[sel][0]
1846                if sel >= 0:
1847                    for r in range(Atoms.GetNumberRows()):
1848                        Atoms.SetCellValue(r,c,parms)
1849            elif c < 0:                    #picked atom row
1850                self.SelectedRow = r
1851            elif Atoms.GetColLabelValue(c) in ['x','y','z']:
1852                colLabel = Atoms.GetColLabelValue(c)
1853                if colLabel == 'x':
1854                    XYZ = [atomData[r][c],atomData[r][c+1],atomData[r][c+2]]
1855                elif colLabel == 'y':
1856                    XYZ = [atomData[r][c-1],atomData[r][c],atomData[r][c+1]]
1857                elif colLabel == 'z':
1858                    XYZ = [atomData[r][c-2],atomData[r][c-1],atomData[r][c]]
1859                if None in XYZ:
1860                    XYZ = [0,0,0]
1861                SScol = colLabels.index('site sym')
1862                Mulcol = colLabels.index('mult')
1863                E,SGData = G2spc.SpcGroup(generalData[2]['SpGrp'])
1864                Sytsym,Mult = G2spc.SytSym(XYZ,SGData)
1865                atomData[r][SScol] = Sytsym
1866                atomData[r][Mulcol] = Mult
1867                Atoms.ForceRefresh()
1868                   
1869        def AtomTypeSelect(event):
1870            r,c =  event.GetRow(),event.GetCol()
1871            if Atoms.GetColLabelValue(c) == 'Type':
1872                PE = G2elem.PickElement(self)
1873                if PE.ShowModal() == wx.ID_OK:
1874                    atomData[r][c] = PE.Elem.strip()
1875                PE.Destroy()
1876                Atoms.ForceRefresh()
1877            else:
1878                event.Skip()
1879       
1880        generalData = data['General']
1881        atomData = data['Atoms']
1882        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",
1883            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',
1884            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_STRING,wg.GRID_VALUE_NUMBER,wg.GRID_VALUE_CHOICE+":I,A",
1885            wg.GRID_VALUE_FLOAT+':10,4',
1886            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',
1887            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4']
1888        colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23']
1889        if generalData[1] == 'magnetic':
1890            colLabels += ['Mx','My','Mz']
1891            Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU,"
1892            Types += [
1893                wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4']
1894        elif generalData[1] == 'macromolecular':
1895            colLabels = ['res no','residue','chain'] + colLabels
1896            Types = [wg.GRID_VALUE_NUMBER,
1897                wg.GRID_VALUE_CHOICE+": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK",
1898                wg.GRID_VALUE_STRING] + Types       
1899        table = []
1900        rowLabels = []
1901        for i,atom in enumerate(atomData):
1902            table.append(atom)
1903            rowLabels.append(str(i+1))
1904        atomTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1905        Atoms.SetTable(atomTable, True)
1906        Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
1907        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1908        Atoms.Bind(wg.EVT_GRID_SELECT_CELL, AtomTypeSelect)
1909        Atoms.SetMargins(0,0)
1910        Atoms.AutoSizeColumns(True)
1911        colType = colLabels.index('Type')
1912        colSS = colLabels.index('site sym')
1913        colIA = colLabels.index('I/A')
1914        for row in range(Atoms.GetNumberRows()):
1915            Atoms.SetReadOnly(row,colSS,True)                         #site sym
1916            Atoms.SetReadOnly(row,colSS+1,True)                       #Mult
1917            if Atoms.GetCellValue(row,colIA) == 'I':
1918                for i in range(2,8):
1919                    Atoms.SetCellRenderer(row,colIA+i,wg.GridCellStringRenderer())
1920                    Atoms.SetReadOnly(row,colIA+i,isReadOnly=True)
1921                    Atoms.SetCellValue(row,colIA+i,'')
1922            elif Atoms.GetCellValue(row,colIA) == 'A':
1923                Atoms.SetCellRenderer(row,colIA+1,wg.GridCellStringRenderer())
1924                Atoms.SetReadOnly(row,colIA+1,isReadOnly=True)
1925                Atoms.SetCellValue(row,colIA+1,'')
1926       
1927    def AtomAdd(event):
1928        atomData = data['Atoms']
1929        generalData = data['General']
1930        Ncol = Atoms.GetNumberCols()
1931        if generalData[1] == 'macromolecular':
1932            atomData.append([0,'UNK','','UNK','UNK','',0,0,0,0,'',0,'I',0.10,0,0,0,0,0,0])
1933        elif generalData[1] == 'nuclear':
1934            atomData.append(['UNK','UNK','',0,0,0,0,'',0,'I',0.01,0,0,0,0,0,0])
1935        event.StopPropagation()
1936        FillAtomsGrid()
1937           
1938    def AtomInsert(event):
1939        atomData = data['Atoms']
1940        generalData = data['General']
1941        Ncol = Atoms.GetNumberCols()
1942        if generalData[1][0] == 'macromolecular':
1943            atomData.append([0,'UNK','','UNK','UNK','',0,0,0,0,'',0,'I',0.10,0,0,0,0,0,0])
1944        elif generalData[1][0] == 'nuclear':
1945            atomData.append(['UNK','UNK','',0,0,0,0,'',0,'I',0.01,0,0,0,0,0,0])
1946        event.StopPropagation()
1947        FillAtomsGrid()
1948       
1949    def UpdateDrawing():
1950        print 'Drawing'
1951       
1952    def FillPawleyReflectionsGrid():
1953       
1954        print 'Pawley reflections'
1955       
1956    def OnPageChanged(event):
1957        page = event.GetSelection()
1958        text = self.dataDisplay.GetPageText(page)
1959        if text == 'Atoms':
1960            self.dataFrame.SetMenuBar(self.dataFrame.AtomsMenu)
1961            self.dataFrame.Bind(wx.EVT_MENU, AtomAdd, id=wxID_ATOMSEDITADD)
1962            self.dataFrame.Bind(wx.EVT_MENU, AtomInsert, id=wxID_ATOMSEDITINSERT)
1963            FillAtomsGrid()           
1964        else:
1965            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1966        event.Skip()
1967       
1968    if self.dataDisplay:
1969        self.dataDisplay.Destroy()                   
1970    PhaseName = self.PatternTree.GetItemText(item)
1971    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1972    self.dataFrame.SetLabel('Phase Data for '+PhaseName)
1973    self.dataDisplay = GSNoteBook(parent=self.dataFrame,size=self.dataFrame.GetClientSize())
1974   
1975    General = GSGrid(parent=self.dataDisplay)
1976    FillGeneralGrid()
1977    self.dataDisplay.AddPage(General,'General')
1978     
1979    GeneralData = data['General']
1980    if GeneralData[3] == 'Pawley':
1981        PawleyRefl = GSGrid(parent=self.dataDisplay)
1982        self.dataDisplay.AddPage(PawleyRefl,'Pawley reflections')
1983        FillPawleyReflectionsGrid()
1984    else:
1985        Atoms = GSGrid(parent=self.dataDisplay)
1986        FillAtomsGrid()
1987        self.dataDisplay.AddPage(Atoms,'Atoms')
1988
1989    Drawing = wx.Window(parent=self.dataDisplay)
1990    self.dataDisplay.AddPage(Drawing,'Drawing')
1991   
1992    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
1993    self.dataDisplay.SetSelection(oldPage)
1994   
1995                         
1996def GetPatternTreeItemId(self, parentId, itemText):
1997    item, cookie = self.PatternTree.GetFirstChild(parentId)
1998    while item:
1999        if self.PatternTree.GetItemText(item) == itemText:
2000            return item
2001        item, cookie = self.PatternTree.GetNextChild(parentId, cookie)
2002    return 0               
2003
2004def MovePatternTreeToGrid(self,item):
2005   
2006    oldPage = 0
2007    if self.dataFrame:
2008        self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2009        if self.dataFrame.GetLabel() == 'Comments':
2010            data = [self.dataDisplay.GetValue()]
2011            self.dataDisplay.Clear() 
2012            Id = GetPatternTreeItemId(self,self.root, 'Comments')
2013            if Id: self.PatternTree.SetItemPyData(Id,data)
2014        if self.dataFrame.GetLabel() == 'Notebook':
2015            data = [self.dataDisplay.GetValue()]
2016            self.dataDisplay.Clear() 
2017            Id = GetPatternTreeItemId(self,self.root, 'Notebook')
2018            if Id: self.PatternTree.SetItemPyData(Id,data)
2019        if 'Phase Data for' in self.dataFrame.GetLabel():
2020            if self.dataDisplay: 
2021                oldPage = self.dataDisplay.GetSelection()
2022        self.dataFrame.Clear()
2023        self.dataFrame.SetLabel('')
2024    else:
2025       self.dataFrame = DataFrame(parent=self.mainPanel)
2026
2027    self.dataFrame.Raise()           
2028    self.PickId = 0
2029    parentID = self.root
2030    self.ExportPattern.Enable(False)
2031    if item != self.root:
2032        parentID = self.PatternTree.GetItemParent(item)
2033    if self.PatternTree.GetItemParent(item) == self.root:
2034        self.PatternId = item
2035        self.PickId = item
2036        if self.PatternTree.GetItemText(item) == 'Notebook':
2037            self.PatternId = 0
2038            self.ExportPattern.Enable(False)
2039            data = self.PatternTree.GetItemPyData(item)
2040            UpdateNotebook(self,data)
2041        elif self.PatternTree.GetItemText(item) == 'Controls':
2042            self.PatternId = 0
2043            self.ExportPattern.Enable(False)
2044            data = self.PatternTree.GetItemPyData(item)
2045            UpdateControls(self,data)
2046        elif 'IMG' in self.PatternTree.GetItemText(item):
2047            self.Image = item
2048            G2plt.PlotImage(self,newPlot=True)
2049        elif 'PKS' in self.PatternTree.GetItemText(item):
2050            G2plt.PlotPowderLines(self)
2051        elif 'PWDR' in self.PatternTree.GetItemText(item):           
2052            self.ExportPattern.Enable(True)
2053            G2plt.PlotPatterns(self,newPlot=True)
2054        elif 'SXTL' in self.PatternTree.GetItemText(item):
2055            self.Sngl = item
2056            G2plt.PlotSngl(self,newPlot=True)
2057           
2058    elif self.PatternTree.GetItemText(parentID) == 'Phases':
2059        self.PickId = item
2060        data = self.PatternTree.GetItemPyData(item)
2061        UpdatePhaseData(self,item,data,oldPage)
2062    elif self.PatternTree.GetItemText(item) == 'Comments':
2063        self.PatternId = self.PatternTree.GetItemParent(item)
2064        self.PickId = item
2065        data = self.PatternTree.GetItemPyData(item)
2066        UpdateComments(self,data)
2067    elif self.PatternTree.GetItemText(item) == 'Image Controls':
2068        self.dataFrame.SetTitle('Image Controls')
2069        self.PickId = item
2070        self.Image = self.PatternTree.GetItemParent(item)
2071        data = self.PatternTree.GetItemPyData(item)
2072        UpdateImageControls(self,data)
2073        G2plt.PlotImage(self)
2074    elif self.PatternTree.GetItemText(item) == 'Masks':
2075        self.dataFrame.SetTitle('Masks')
2076        self.PickId = item
2077        self.Image = self.PatternTree.GetItemParent(item)
2078        data = self.PatternTree.GetItemPyData(item)
2079        UpdateMasks(self,data)
2080        G2plt.PlotImage(self)
2081    elif self.PatternTree.GetItemText(item) == 'HKL Plot Controls':
2082        self.PickId = item
2083        self.Sngl = self.PatternTree.GetItemParent(item)
2084        data = self.PatternTree.GetItemPyData(item)
2085        UpdateHKLControls(self,data)
2086        G2plt.PlotSngl(self)               
2087    elif self.PatternTree.GetItemText(item) == 'Peak List':
2088        self.PatternId = self.PatternTree.GetItemParent(item)
2089        self.ExportPeakList.Enable(True)
2090        self.PickId = item
2091        data = self.PatternTree.GetItemPyData(item)
2092        UpdatePeakGrid(self,data)
2093        G2plt.PlotPatterns(self)
2094    elif self.PatternTree.GetItemText(item) == 'Background':
2095        self.PatternId = self.PatternTree.GetItemParent(item)
2096        self.PickId = item
2097        data = self.PatternTree.GetItemPyData(item)
2098        UpdateBackgroundGrid(self,data)
2099        G2plt.PlotPatterns(self)
2100    elif self.PatternTree.GetItemText(item) == 'Limits':
2101        self.PatternId = self.PatternTree.GetItemParent(item)
2102        self.PickId = item
2103        data = self.PatternTree.GetItemPyData(item)
2104        UpdateLimitsGrid(self,data)
2105        G2plt.PlotPatterns(self)
2106    elif self.PatternTree.GetItemText(item) == 'Instrument Parameters':
2107        self.PatternId = self.PatternTree.GetItemParent(item)
2108        self.PickId = item
2109        data = self.PatternTree.GetItemPyData(item)
2110        UpdateInstrumentGrid(self,data)
2111        G2plt.PlotPeakWidths(self)
2112    elif self.PatternTree.GetItemText(item) == 'Index Peak List':
2113        self.PatternId = self.PatternTree.GetItemParent(item)
2114        self.ExportPeakList.Enable(True)
2115        self.PickId = item
2116        data = self.PatternTree.GetItemPyData(item)
2117        UpdateIndexPeaksGrid(self,data)
2118        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
2119            G2plt.PlotPowderLines(self)
2120        else:
2121            G2plt.PlotPatterns(self)
2122    elif self.PatternTree.GetItemText(item) == 'Unit Cells List':
2123        self.PatternId = self.PatternTree.GetItemParent(item)
2124        self.PickId = item
2125        data = self.PatternTree.GetItemPyData(item)
2126        if not data:
2127            data.append([0,0.1,4,25.0,0,'P1',1,1,1,90,90,90]) #zero error flag, max zero error, max Nc/No, start volume
2128            data.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0])      #Bravais lattice flags
2129            data.append([])                                 #empty cell list
2130            data.append([])                                 #empty dmin
2131            self.PatternTree.SetItemPyData(item,data)                             
2132        UpdateUnitCellsGrid(self,data)
2133        self.dataFrame.RefineCell.Enable(True)
2134        self.dataFrame.IndexPeaks.Enable(True)
2135        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
2136            G2plt.PlotPowderLines(self)
2137        else:
2138            G2plt.PlotPatterns(self)
Note: See TracBrowser for help on using the repository browser.