source: trunk/GSASIIgrid.py @ 78

Last change on this file since 78 was 78, checked in by vondreel, 12 years ago

split IndexPeaks?, etc. from GSASIIcomp.py & put in new GSASIIindex.py

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