source: trunk/GSASIIgrid.py @ 82

Last change on this file since 82 was 82, checked in by vondreel, 13 years ago

split powder GUI stuff out of G2gd & put in new GSASIIpwdGUI.py - all seems to work

File size: 62.0 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 GSASIIpeak as G2pk
10import GSASIIlattice as G2lat
11import GSASIIindex as G2indx
12import GSASIIimage as G2img
13import GSASIIspc as G2spc
14import GSASIIElem as G2elem
15import GSASIIplot as G2plt
16import GSASIIIO as G2IO
17import GSASIIpwdGUI as G2pdG
18
19# trig functions in degrees
20sind = lambda x: math.sin(x*math.pi/180.)
21tand = lambda x: math.tan(x*math.pi/180.)
22cosd = lambda x: math.cos(x*math.pi/180.)
23asind = lambda x: 180.*math.asin(x)/math.pi
24       
25[ wxID_ATOMSEDITADD, wxID_ATOMSEDITINSERT, 
26] = [wx.NewId() for _init_coll_Atom_Items in range(2)]
27
28[ wxID_IMCALIBRATE, wxID_IMINTEGRATE, wxID_IMCLEARCALIB, wxID_SAVEINTG, 
29    wxID_IMCOPYCONTROLS, wxID_INTEGRATEALL,
30] = [wx.NewId() for _init_coll_IMAGE_Items in range(6)]
31
32[ wxID_MASKCOPY,
33] = [wx.NewId() for _init_coll_MASK_Items in range(1)]
34
35[ wxID_INSTPRMRESET,
36] = [wx.NewId() for _init_coll_INST_Items in range(1)]
37
38[ wxID_UNDO,wxID_PEAKFIT,wxID_AUTOPEAKFIT,
39] = [wx.NewId() for _init_coll_PEAK_Items in range(3)]
40
41[  wxID_INDEXPEAKS, wxID_REFINECELL, wxID_COPYCELL,
42] = [wx.NewId() for _init_coll_INDEX_Items in range(3)]
43
44class DataFrame(wx.Frame):
45    def _init_coll_BlankMenu(self,parent):
46        parent.Append(menu=self.Blank,title='')
47       
48    def _init_coll_AtomsMenu(self,parent):
49        parent.Append(menu=self.AtomEdit, title='Add atom')
50                   
51    def _init_coll_ImageMenu(self,parent):
52        parent.Append(menu=self.ImageEdit, title='Image Operations')
53       
54    def _init_coll_InstMenu(self,parent):
55        parent.Append(menu=self.InstEdit, title='Inst. Parm. Operations')
56       
57    def _init_coll_MaskMenu(self,parent):
58        parent.Append(menu=self.MaskEdit, title='Mask Operations')
59       
60    def _init_coll_PeakMenu(self,parent):
61        parent.Append(menu=self.PeakEdit, title='Peak Fitting')
62
63    def _init_coll_IndexMenu(self,parent):
64        parent.Append(menu=self.IndexEdit, title='Cell Index/Refine')
65       
66    def _init_coll_Atom_Items(self,parent):
67        parent.Append(help='',id=wxID_ATOMSEDITADD, kind=wx.ITEM_NORMAL,text='Append empty atom')
68        parent.Append(id=wxID_ATOMSEDITINSERT, kind=wx.ITEM_NORMAL,text='Insert empty atom',
69            help='Double left click on atom row to Insert before')
70           
71    def _init_coll_Image_Items(self,parent):
72        parent.Append(help='Calibrate detector by fitting to calibrant lines', 
73            id=wxID_IMCALIBRATE, kind=wx.ITEM_NORMAL,text='Calibrate')
74        parent.Append(help='Clear calibration data points and rings',id=wxID_IMCLEARCALIB, 
75            kind=wx.ITEM_NORMAL,text='Clear calibration')
76        parent.Append(help='Integrate selected image',id=wxID_IMINTEGRATE, 
77            kind=wx.ITEM_NORMAL,text='Integrate')
78        parent.Append(help='Integrate all images selected from list',id=wxID_INTEGRATEALL,
79            kind=wx.ITEM_NORMAL,text='Integrate all')
80        parent.Append(help='Save integration results as a series of 1-D powder patterns', 
81            id=wxID_SAVEINTG, kind=wx.ITEM_NORMAL,text='Save Integration')
82        parent.Append(help='Copy image controls to other images', 
83            id=wxID_IMCOPYCONTROLS, kind=wx.ITEM_NORMAL,text='Copy Controls')
84                   
85    def _init_coll_Mask_Items(self,parent):
86        parent.Append(help='Copy mask to other images', 
87            id=wxID_MASKCOPY, kind=wx.ITEM_NORMAL,text='Copy mask')
88
89    def _init_coll_Inst_Items(self,parent):
90        parent.Append(help='Reset instrument profile parameters to default', 
91            id=wxID_INSTPRMRESET, kind=wx.ITEM_NORMAL,text='Reset profile')
92
93    def _init_coll_Peak_Items(self,parent):
94        self.UnDo = parent.Append(help='Undo last least squares refinement', 
95            id=wxID_UNDO, kind=wx.ITEM_NORMAL,text='UnDo')
96        self.PeakFit = parent.Append(id=wxID_PEAKFIT, kind=wx.ITEM_NORMAL,text='PeakFit', 
97            help='Do single cycle of peak fitting least-squares refinement' )
98        self.AutoPeakFit = parent.Append(id=wxID_AUTOPEAKFIT, kind=wx.ITEM_NORMAL, 
99            text='AutoPeakFit',help='Do peak fitting least-squares to convergence' )
100           
101    def _init_coll_Index_Items(self,parent):
102        self.IndexPeaks = parent.Append(help='', id=wxID_INDEXPEAKS, kind=wx.ITEM_NORMAL,
103            text='Index Cell')
104        self.CopyCell = parent.Append( id=wxID_COPYCELL, kind=wx.ITEM_NORMAL,text='Copy Cell', 
105            help='Copy selected unit cell from indexing to cell refinement fields')
106        self.RefineCell = parent.Append( id=wxID_REFINECELL, kind=wx.ITEM_NORMAL, 
107            text='Refine Cell',help='Refine unit cell parameters from indexed peaks')
108
109    def _init_utils(self):
110        self.BlankMenu = wx.MenuBar()
111       
112        self.AtomsMenu = wx.MenuBar()
113        self.ImageMenu = wx.MenuBar()
114        self.MaskMenu = wx.MenuBar()
115        self.InstMenu = wx.MenuBar()
116        self.PeakMenu = wx.MenuBar()
117        self.IndexMenu = wx.MenuBar()
118        self.AtomEdit = wx.Menu(title='')
119        self.ImageEdit = wx.Menu(title='')
120        self.MaskEdit = wx.Menu(title='')
121        self.InstEdit = wx.Menu(title='')
122        self.PeakEdit = wx.Menu(title='')
123        self.IndexEdit = wx.Menu(title='')
124        self._init_coll_AtomsMenu(self.AtomsMenu)
125        self._init_coll_Atom_Items(self.AtomEdit)
126        self._init_coll_ImageMenu(self.ImageMenu)
127        self._init_coll_Image_Items(self.ImageEdit)
128        self._init_coll_MaskMenu(self.MaskMenu)
129        self._init_coll_Mask_Items(self.MaskEdit)
130        self._init_coll_InstMenu(self.InstMenu)
131        self._init_coll_Inst_Items(self.InstEdit)
132        self._init_coll_PeakMenu(self.PeakMenu)
133        self._init_coll_Peak_Items(self.PeakEdit)
134        self._init_coll_IndexMenu(self.IndexMenu)
135        self._init_coll_Index_Items(self.IndexEdit)
136        self.UnDo.Enable(False)
137        self.PeakFit.Enable(False)
138        self.AutoPeakFit.Enable(False)
139        self.IndexPeaks.Enable(False)
140        self.CopyCell.Enable(False)
141        self.RefineCell.Enable(False)
142               
143    def _init_ctrls(self, parent,name=None,size=None,pos=None):
144        wx.Frame.__init__(self,parent=parent,style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX,
145            size=size,pos=pos,title='GSAS-II data display')
146        self._init_utils()
147        if name:
148            self.SetLabel(name)
149        self.Show()
150       
151    def __init__(self,parent,data=None,name=None, size=None,pos=None):
152        self._init_ctrls(parent,name,size,pos)
153        self.data = data
154        self.screenSize = wx.DisplaySize()
155        Size = self.GetSize()
156        xPos = self.screenSize[0]-Size[0]
157        self.SetPosition(wx.Point(xPos,250))
158        self.dirname = ''
159        self.AtomGrid = []
160        self.selectedRow = 0
161       
162    def setSizePosLeft(self,Width):
163        screenSize = wx.DisplaySize()
164        self.SetSize(Width)
165        self.SetPosition(wx.Point(screenSize[0]-Width[0],250))
166       
167    def Clear(self):
168        self.ClearBackground()
169        self.DestroyChildren()
170                   
171class GSGrid(wg.Grid):
172    def __init__(self, parent, name=''):
173        wg.Grid.__init__(self,parent,-1,name=name)                   
174        self.SetSize(parent.GetClientSize())
175           
176    def Clear(self):
177        wg.Grid.ClearGrid(self)
178       
179    def SetCellStyle(self,r,c,color="white",readonly=True):
180        self.SetCellBackgroundColour(r,c,color)
181        self.SetReadOnly(r,c,isReadOnly=readonly)
182       
183class GSNoteBook(wx.Notebook):
184    def __init__(self, parent, name='',size = None):
185        wx.Notebook.__init__(self, parent, -1, name=name, style= wx.BK_TOP)
186        if size: self.SetSize(size)
187                                                     
188    def Clear(self):       
189        GSNoteBook.DeleteAllPages(self)
190       
191class Table(wg.PyGridTableBase):
192    def __init__(self, data=[], rowLabels=None, colLabels=None, types = None):
193        wg.PyGridTableBase.__init__(self)
194        self.colLabels = colLabels
195        self.rowLabels = rowLabels
196        self.dataTypes = types
197        self.data = data
198       
199    def AppendRows(self, numRows=1):
200        self.data.append([])
201        return True
202       
203    def CanGetValueAs(self, row, col, typeName):
204        if self.dataTypes:
205            colType = self.dataTypes[col].split(':')[0]
206            if typeName == colType:
207                return True
208            else:
209                return False
210        else:
211            return False
212
213    def CanSetValueAs(self, row, col, typeName):
214        return self.CanGetValueAs(row, col, typeName)
215
216    def DeleteRow(self,pos):
217        data = self.GetData()
218        self.SetData([])
219        new = []
220        for irow,row in enumerate(data):
221            if irow <> pos:
222                new.append(row)
223        self.SetData(new)
224       
225    def GetColLabelValue(self, col):
226        if self.colLabels:
227            return self.colLabels[col]
228           
229    def GetData(self):
230        data = []
231        for row in range(self.GetNumberRows()):
232            data.append(self.GetRowValues(row))
233        return data
234       
235    def GetNumberCols(self):
236        try:
237            return len(self.colLabels)
238        except TypeError:
239            return None
240       
241    def GetNumberRows(self):
242        return len(self.data)
243       
244    def GetRowLabelValue(self, row):
245        if self.rowLabels:
246            return self.rowLabels[row]
247       
248    def GetRowValues(self, row):
249        data = []
250        for col in range(self.GetNumberCols()):
251            data.append(self.GetValue(row, col))
252        return data
253       
254    def GetTypeName(self, row, col):
255        try:
256            return self.dataTypes[col]
257        except TypeError:
258            return None
259
260    def GetValue(self, row, col):
261        try:
262            return self.data[row][col]
263        except IndexError:
264            return None
265           
266    def InsertRows(self, pos, rows):
267        for row in range(rows):
268            self.data.insert(pos,[])
269            pos += 1
270       
271    def IsEmptyCell(self,row,col):
272        try:
273            return not self.data[row][col]
274        except IndexError:
275            return True
276       
277    def OnKeyPress(self, event):
278        dellist = self.GetSelectedRows()
279        if event.GetKeyCode() == wx.WXK_DELETE and dellist:
280            grid = self.GetView()
281            for i in dellist: grid.DeleteRow(i)
282               
283    def SetColLabelValue(self, col, label):
284        numcols = self.GetNumberCols()
285        if col > numcols-1:
286            self.colLabels.append(label)
287        else:
288            self.colLabels[col]=label
289       
290    def SetData(self,data):
291        for row in range(len(data)):
292            self.SetRowValues(row,data[row])
293               
294    def SetRowLabelValue(self, row, label):
295        self.rowLabels[row]=label
296           
297    def SetRowValues(self,row,data):
298        self.data[row] = data
299           
300    def SetValue(self, row, col, value):
301        def innerSetValue(row, col, value):
302            try:
303                self.data[row][col] = value
304            except TypeError:
305                return
306            except IndexError:
307                print row,col,value
308                # add a new row
309                if row > self.GetNumberRows():
310                    self.data.append([''] * self.GetNumberCols())
311                elif col > self.GetNumberCols():
312                    for row in range(self.GetNumberRows):
313                        self.data[row].append('')
314                print self.data
315                self.data[row][col] = value
316        innerSetValue(row, col, value)
317       
318def UpdateNotebook(self,data):       
319    if data:
320        self.dataFrame.SetLabel('Notebook')
321        self.dataDisplay = wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
322            style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
323        for line in data:
324            self.dataDisplay.AppendText(line+"\n")
325            self.dataDisplay.AppendText('Notebook entry @ '+time.ctime()+"\n")
326           
327def UpdateControls(self,data):
328    if data:
329        self.dataFrame.SetLabel('Controls')
330       
331     
332def UpdateComments(self,data):                   
333    if data:
334        self.dataFrame.SetLabel('Comments')
335        self.dataDisplay = wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
336            style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
337        for line in data:
338            self.dataDisplay.AppendText(line+"\n")
339             
340def UpdateHKLControls(self,data):
341   
342    def OnScaleSlider(event):
343        scale = int(scaleSel.GetValue())/1000.
344        scaleSel.SetValue(int(scale*1000.))
345        data['Scale'] = scale*10.
346        G2plt.PlotSngl(self)
347       
348    def OnLayerSlider(event):
349        layer = layerSel.GetValue()
350        data['Layer'] = layer
351        G2plt.PlotSngl(self)
352       
353    def OnSelZone(event):
354        data['Zone'] = zoneSel.GetValue()
355        G2plt.PlotSngl(self,newPlot=True)
356       
357    def OnSelType(event):
358        data['Type'] = typeSel.GetValue()
359        G2plt.PlotSngl(self)
360       
361    def SetStatusLine():
362        Status.SetStatusText("look at me!!!")
363                                     
364    if self.dataDisplay:
365        self.dataDisplay.Destroy()
366    if not self.dataFrame.GetStatusBar():
367        Status = self.dataFrame.CreateStatusBar()
368    SetStatusLine()
369    zones = ['100','010','001']
370    HKLmax = data['HKLmax']
371    HKLmin = data['HKLmin']
372    if data['ifFc']:
373        typeChoices = ['Fosq','Fo','|DFsq|/sig','|DFsq|>sig','|DFsq|>3sig']
374    else:
375        typeChoices = ['Fosq','Fo']
376    self.dataDisplay = wx.Panel(self.dataFrame)
377    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
378    mainSizer = wx.BoxSizer(wx.VERTICAL)
379    mainSizer.Add((5,10),0)
380   
381    scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
382    scaleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Scale'),0,
383        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
384    scaleSel = wx.Slider(parent=self.dataDisplay,maxValue=1000,minValue=100,
385        style=wx.SL_HORIZONTAL,value=int(data['Scale']*100))
386    scaleSizer.Add(scaleSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
387    scaleSel.SetLineSize(100)
388    scaleSel.SetPageSize(900)
389    scaleSel.Bind(wx.EVT_SLIDER, OnScaleSlider)
390    mainSizer.Add(scaleSizer,1,wx.EXPAND|wx.RIGHT)
391   
392    zoneSizer = wx.BoxSizer(wx.HORIZONTAL)
393    zoneSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Zone  '),0,
394        wx.ALIGN_CENTER_VERTICAL)
395    zoneSel = wx.ComboBox(parent=self.dataDisplay,value=data['Zone'],choices=['100','010','001'],
396        style=wx.CB_READONLY|wx.CB_DROPDOWN)
397    zoneSel.Bind(wx.EVT_COMBOBOX, OnSelZone)
398    zoneSizer.Add(zoneSel,0,wx.ALIGN_CENTER_VERTICAL)
399    zoneSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Plot type  '),0,
400        wx.ALIGN_CENTER_VERTICAL)       
401    typeSel = wx.ComboBox(parent=self.dataDisplay,value=data['Type'],choices=typeChoices,
402        style=wx.CB_READONLY|wx.CB_DROPDOWN)
403    typeSel.Bind(wx.EVT_COMBOBOX, OnSelType)
404    zoneSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
405    zoneSizer.Add((10,0),0)   
406    mainSizer.Add(zoneSizer,1,wx.EXPAND|wx.RIGHT)
407       
408    izone = zones.index(data['Zone'])
409    layerSizer = wx.BoxSizer(wx.HORIZONTAL)
410    layerSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Layer'),0,
411        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
412    layerSel = wx.Slider(parent=self.dataDisplay,maxValue=HKLmax[izone],minValue=HKLmin[izone],
413        style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS,value=0)
414    layerSel.SetLineSize(1)
415    layerSel.SetLineSize(5)
416    layerSel.Bind(wx.EVT_SLIDER, OnLayerSlider)   
417    layerSizer.Add(layerSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
418    layerSizer.Add((10,0),0)   
419    mainSizer.Add(layerSizer,1,wx.EXPAND|wx.RIGHT)
420
421       
422    mainSizer.Layout()   
423    self.dataDisplay.SetSizer(mainSizer)
424    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
425    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
426       
427def UpdateImageControls(self,data):
428    import ImageCalibrants as calFile
429   
430    def OnNewColorBar(event):
431        data['color'] = colSel.GetValue()
432        G2plt.PlotExposedImage(self)
433       
434    def OnNewCalibrant(event):
435        data['calibrant'] = calSel.GetValue()
436       
437    def OnPixLimit(event):
438        data['pixLimit'] = int(pixLimit.GetValue())
439       
440    def OnMaxSlider(event):
441        logDeltZero = math.log(data['range'][0][1]-data['range'][0][0])
442        imax = int(maxSel.GetValue())*logDeltZero/100.
443        data['range'][1][1] = math.exp(imax)+data['range'][0][0]
444        data['range'][1][0] = min(data['range'][1][1]-1,data['range'][1][0])
445        G2plt.PlotExposedImage(self)
446       
447    def OnMinSlider(event):
448        DeltOne = data['range'][1][1]-data['range'][0][0]
449        imin = int(minSel.GetValue())*DeltOne/100.
450        data['range'][1][0] = min(data['range'][1][1]-1,imin+data['range'][0][0])
451        G2plt.PlotExposedImage(self)
452       
453    def OnNumOutChans(event):
454        try:
455            numChans = int(outChan.GetValue())
456            if numChans < 1:
457                raise ValueError
458            data['outChannels'] = numChans
459        except ValueError:
460            pass
461        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
462        outChan.SetValue(str(data['outChannels']))          #reset in case of error       
463       
464    def OnNumOutAzms(event):
465        try:
466            numAzms = int(outAzim.GetValue())
467            if numAzms < 1:
468                raise ValueError
469            data['outAzimuths'] = numAzms           
470        except ValueError:
471            pass
472        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
473        outAzim.SetValue(str(data['outAzimuths']))          #reset in case of error       
474       
475    def OnWavelength(event):
476        try:
477            wave = float(waveSel.GetValue())
478            if wave < .01:
479                raise ValueError
480            data['wavelength'] = wave
481        except ValueError:
482            pass
483        waveSel.SetValue("%6.5f" % (data['wavelength']))          #reset in case of error         
484       
485    def OnCutOff(event):
486        try:
487            cutoff = float(cutOff.GetValue())
488            data['cutoff'] = cutoff
489        except ValueError:
490            pass
491        cutOff.SetValue("%.1f"%(data['cutoff']))          #reset in case of error 
492       
493    def OnShowLines(event):
494        if data['showLines']:
495            data['showLines'] = False
496        else:
497            data['showLines'] = True
498        G2plt.PlotExposedImage(self)
499       
500    def OnFullIntegrate(event):
501        if data['fullIntegrate']:
502            data['fullIntegrate'] = False
503            self.Lazim.SetEditable(True)           
504            self.Razim.SetEditable(True)           
505        else:
506            data['fullIntegrate'] = True
507            self.Lazim.SetEditable(False)           
508            self.Razim.SetEditable(False)           
509        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
510        G2plt.PlotExposedImage(self)
511       
512    def OnSetDefault(event):
513        import copy
514        if data['setDefault']:
515            self.imageDefault = {}
516            data['setDefault'] = False
517        else:
518            self.imageDefault = copy.copy(data)
519            data['setDefault'] = True
520           
521    def OnIOtth(event):
522        Ltth = float(self.InnerTth.GetValue())
523        Utth = float(self.OuterTth.GetValue())
524        if Ltth > Utth:
525            Ltth,Utth = Utth,Ltth
526        data['IOtth'] = [Ltth,Utth]
527        self.InnerTth.SetValue("%8.2f" % (Ltth))
528        self.OuterTth.SetValue("%8.2f" % (Utth))
529        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
530        G2plt.PlotExposedImage(self)
531       
532    def OnLRazim(event):
533        Lazm = int(self.Lazim.GetValue())
534        Razm = int(self.Razim.GetValue())
535        data['LRazimuth'] = [Lazm,Razm]
536        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
537        G2plt.PlotExposedImage(self)
538           
539    def OnSetRings(event):
540        if data['setRings']:
541            data['setRings'] = False
542        else:
543            data['setRings'] = True
544        setRings.SetValue(data['setRings'])
545        G2plt.PlotExposedImage(self)
546           
547    def OnClearCalib(event):
548        data['ring'] = []
549        data['rings'] = []
550        data['ellipses'] = []
551        self.dataFrame.ImageEdit.Enable(id=wxID_IMCLEARCALIB,enable=False)   
552        G2plt.PlotExposedImage(self)
553           
554    def OnCalibrate(event):       
555        data['setRings'] = False
556        setRings.SetValue(data['setRings'])
557        msg = \
558        '''Select > 4 points on inner ring of image pattern.
559        Click right mouse button to select point.
560          Use left mouse button to delete point.
561                 Press OK when done'''
562        dlg = wx.MessageDialog(self,msg,'Pick inner ring',wx.OK)
563        self.ifGetRing = True
564        dlg.ShowModal()
565        self.ifGetRing = False
566       
567        if G2img.ImageCalibrate(self,data):
568            Status.SetStatusText('Calibration successful')
569            cent = data['center']
570            centText.SetValue(("%8.3f,%8.3f" % (cent[0],cent[1])))
571            distSel.SetValue("%8.3f"%(data['distance']))
572            tiltSel.SetValue("%9.3f"%(data['tilt']))           
573            rotSel.SetValue("%9.3f"%(data['rotation']))
574            self.dataFrame.ImageEdit.Enable(id=wxID_IMCLEARCALIB,enable=True)   
575        else:
576            Status.SetStatusText('Calibration failed')
577                   
578    def OnIntegrate(event):
579        G2img.ImageIntegrate(self,data)
580        G2plt.PlotIntegration(self,newPlot=True)
581        self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=True)
582       
583    def OnIntegrateAll(event):
584        print 'integrate all'
585        TextList = []
586        Names = []
587        if self.PatternTree.GetCount():
588            id, cookie = self.PatternTree.GetFirstChild(self.root)
589            while id:
590                name = self.PatternTree.GetItemText(id)
591                Names.append(name)
592                if 'IMG' in name:
593                    TextList.append([False,name,id])
594                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
595            if not len(TextList):
596                self.ErrorDialog('Nothing to integrate','There must some "IMG" patterns')
597                return
598            dlg = self.CopyDialog(self,'Image integration controls','Select images to integrate:',TextList)
599            try:
600                if dlg.ShowModal() == wx.ID_OK:
601                    result = dlg.GetData()
602                    for item in result:
603                        ifintegrate,name,id = item
604                        if ifintegrate:
605                            id = GetPatternTreeItemId(self, self.root, name)
606                            size,imagefile = self.PatternTree.GetItemPyData(id)
607                            self.ImageZ = G2IO.GetImageData(imagefile,imageOnly=True)
608                            Id = GetPatternTreeItemId(self,id, 'Image Controls')
609                            Data = self.PatternTree.GetItemPyData(Id)
610                            G2img.ImageIntegrate(self,Data)
611                            G2plt.PlotIntegration(self,newPlot=True)
612                            self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=True)
613                            G2IO.SaveIntegration(self,Id,Data)
614            finally:
615                dlg.Destroy()
616       
617    def OnSaveIntegrate(event):
618        print 'save integration'
619        G2IO.SaveIntegration(self,self.PickId,data)
620           
621    def OnCopyControls(event):
622        TextList = []
623        Names = []
624        if self.PatternTree.GetCount():
625            id, cookie = self.PatternTree.GetFirstChild(self.root)
626            while id:
627                name = self.PatternTree.GetItemText(id)
628                Names.append(name)
629                if 'IMG' in name:
630                    if id == self.Image:
631                        Source = name
632                        Data = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,id, 'Image Controls'))
633                        Data['showLines'] = True
634                        Data['ring'] = []
635                        Data['rings'] = []
636                        Data['cutoff'] = 10
637                        Data['pixLimit'] = 20
638                        Data['ellipses'] = []
639                        Data['calibrant'] = ''
640                        Data['setDefault'] = False
641                    else:
642                        TextList.append([False,name,id])
643                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
644            if not len(TextList):
645                self.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
646                return
647            dlg = self.CopyDialog(self,'Copy image controls','Copy controls from '+Source+' to:',TextList)
648            try:
649                if dlg.ShowModal() == wx.ID_OK:
650                    result = dlg.GetData()
651                    for i,item in enumerate(result[:-1]):
652                        ifcopy,name,id = item
653                        if ifcopy:
654                            oldData = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,id, 'Image Controls'))
655                            Data['range'] = oldData['range']                               
656                            self.PatternTree.SetItemPyData(GetPatternTreeItemId(self,id, 'Image Controls'),Data)
657            finally:
658                dlg.Destroy()
659                                       
660    colorList = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
661    calList = [m for m in calFile.Calibrants.keys()]
662    if self.dataDisplay:
663        self.dataDisplay.Destroy()
664    self.dataFrame.SetMenuBar(self.dataFrame.ImageMenu)
665    if not self.dataFrame.GetStatusBar():
666        Status = self.dataFrame.CreateStatusBar()
667    self.dataFrame.Bind(wx.EVT_MENU, OnCalibrate, id=wxID_IMCALIBRATE)
668    self.dataFrame.Bind(wx.EVT_MENU, OnClearCalib, id=wxID_IMCLEARCALIB)
669    if not data['rings']:
670        self.dataFrame.ImageEdit.Enable(id=wxID_IMCLEARCALIB,enable=False)   
671    self.dataFrame.Bind(wx.EVT_MENU, OnIntegrate, id=wxID_IMINTEGRATE)
672    self.dataFrame.Bind(wx.EVT_MENU, OnIntegrateAll, id=wxID_INTEGRATEALL)
673    self.dataFrame.Bind(wx.EVT_MENU, OnSaveIntegrate, id=wxID_SAVEINTG)
674    self.dataFrame.Bind(wx.EVT_MENU, OnCopyControls, id=wxID_IMCOPYCONTROLS)
675    self.dataFrame.ImageEdit.Enable(id=wxID_SAVEINTG,enable=False)   
676    self.dataDisplay = wx.Panel(self.dataFrame)
677    mainSizer = wx.BoxSizer(wx.VERTICAL)
678    mainSizer.Add((5,10),0)
679   
680    maxSizer = wx.FlexGridSizer(2,2,0,5)
681    maxSizer.AddGrowableCol(1,1)
682    logDeltZero = math.log(data['range'][0][1]-data['range'][0][0])
683    DeltOne = data['range'][1][1]-data['range'][0][0]
684    logDeltOne = math.log(DeltOne)
685    maxSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Max intensity'),0,
686        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
687    maxSel = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
688        value=int(100*logDeltOne/logDeltZero))
689    maxSizer.Add(maxSel,1,wx.EXPAND|wx.RIGHT)
690    maxSel.Bind(wx.EVT_SLIDER, OnMaxSlider)   
691    maxSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min intensity'),0,
692        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
693    minSel = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
694        value=int(100*data['range'][1][0]/DeltOne))
695    maxSizer.Add(minSel,1,wx.EXPAND|wx.RIGHT)
696    minSel.Bind(wx.EVT_SLIDER, OnMinSlider)
697    mainSizer.Add(maxSizer,1,wx.EXPAND|wx.RIGHT)
698   
699    comboSizer = wx.BoxSizer(wx.HORIZONTAL)
700    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Color bar '),0,
701        wx.ALIGN_CENTER_VERTICAL)
702    colSel = wx.ComboBox(parent=self.dataDisplay,value=data['color'],choices=colorList,
703        style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
704    colSel.Bind(wx.EVT_COMBOBOX, OnNewColorBar)
705    comboSizer.Add(colSel,0,wx.ALIGN_CENTER_VERTICAL)
706   
707    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibrant '),0,
708        wx.ALIGN_CENTER_VERTICAL)
709    calSel = wx.ComboBox(parent=self.dataDisplay,value=data['calibrant'],choices=calList,
710        style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
711    calSel.Bind(wx.EVT_COMBOBOX, OnNewCalibrant)
712    comboSizer.Add(calSel,0,wx.ALIGN_CENTER_VERTICAL)
713    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Pixel search range '),0,
714        wx.ALIGN_CENTER_VERTICAL)
715    pixLimit = wx.ComboBox(parent=self.dataDisplay,value=str(data['pixLimit']),choices=['1','2','5','10','15','20'],
716        style=wx.CB_READONLY|wx.CB_DROPDOWN)
717    pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
718    comboSizer.Add(pixLimit,0,wx.ALIGN_CENTER_VERTICAL)
719    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min ring I/Ib '),0,
720        wx.ALIGN_CENTER_VERTICAL)
721    cutOff = wx.TextCtrl(parent=self.dataDisplay,value=("%.1f" % (data['cutoff'])),
722        style=wx.TE_PROCESS_ENTER)
723    cutOff.Bind(wx.EVT_TEXT,OnCutOff)
724    comboSizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL)
725
726    mainSizer.Add(comboSizer,0,wx.ALIGN_CENTER_HORIZONTAL)
727    mainSizer.Add((5,5),0)
728         
729    dataSizer = wx.FlexGridSizer(6,4,5,5)
730    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibration coefficients'),0,
731        wx.ALIGN_CENTER_VERTICAL)   
732    dataSizer.Add((5,0),0)
733    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Integration coefficients'),0,
734        wx.ALIGN_CENTER_VERTICAL)   
735    dataSizer.Add((5,0),0)
736   
737    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Beam center X,Y'),0,
738        wx.ALIGN_CENTER_VERTICAL)
739    cent = data['center']
740    centText = wx.TextCtrl(parent=self.dataDisplay,value=("%8.3f,%8.3f" % (cent[0],cent[1])),style=wx.TE_READONLY)
741    dataSizer.Add(centText,0,wx.ALIGN_CENTER_VERTICAL)
742   
743    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Inner/Outer 2-theta'),0,
744        wx.ALIGN_CENTER_VERTICAL)
745       
746    IOtth = data['IOtth']
747    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
748    self.InnerTth = wx.TextCtrl(parent=self.dataDisplay,
749        value=("%8.2f" % (IOtth[0])),style=wx.TE_PROCESS_ENTER)
750    self.InnerTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
751    littleSizer.Add(self.InnerTth,0,wx.ALIGN_CENTER_VERTICAL)
752    self.OuterTth = wx.TextCtrl(parent=self.dataDisplay,
753        value=("%8.2f" % (IOtth[1])),style=wx.TE_PROCESS_ENTER)
754    self.OuterTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
755    littleSizer.Add(self.OuterTth,0,wx.ALIGN_CENTER_VERTICAL)
756    dataSizer.Add(littleSizer,0,)
757       
758    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Wavelength'),0,
759        wx.ALIGN_CENTER_VERTICAL)
760    waveSel = wx.TextCtrl(parent=self.dataDisplay,value=("%6.5f" % (data['wavelength'])),
761        style=wx.TE_PROCESS_ENTER)
762    waveSel.Bind(wx.EVT_TEXT_ENTER,OnWavelength)
763    dataSizer.Add(waveSel,0,wx.ALIGN_CENTER_VERTICAL)
764         
765    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Start/End azimuth'),0,
766        wx.ALIGN_CENTER_VERTICAL)
767    LRazim = data['LRazimuth']
768    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
769    self.Lazim = wx.TextCtrl(parent=self.dataDisplay,
770        value=("%6d" % (LRazim[0])),style=wx.TE_PROCESS_ENTER)
771    self.Lazim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
772    littleSizer.Add(self.Lazim,0,wx.ALIGN_CENTER_VERTICAL)
773    self.Razim = wx.TextCtrl(parent=self.dataDisplay,
774        value=("%6d" % (LRazim[1])),style=wx.TE_PROCESS_ENTER)
775    self.Razim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
776    littleSizer.Add(self.Razim,0,wx.ALIGN_CENTER_VERTICAL)
777    dataSizer.Add(littleSizer,0,)
778       
779    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Distance'),0,
780        wx.ALIGN_CENTER_VERTICAL)
781    distSel = wx.TextCtrl(parent=self.dataDisplay,value=("%8.3f"%(data['distance'])),style=wx.TE_READONLY)
782    dataSizer.Add(distSel,0,wx.ALIGN_CENTER_VERTICAL)
783
784    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' No. 2-theta/azimuth bins'),0,
785        wx.ALIGN_CENTER_VERTICAL)
786    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
787    outChan = wx.TextCtrl(parent=self.dataDisplay,value=str(data['outChannels']),style=wx.TE_PROCESS_ENTER)
788    outChan.Bind(wx.EVT_TEXT_ENTER,OnNumOutChans)
789    littleSizer.Add(outChan,0,wx.ALIGN_CENTER_VERTICAL)
790    outAzim = wx.TextCtrl(parent=self.dataDisplay,value=str(data['outAzimuths']),style=wx.TE_PROCESS_ENTER)
791    outAzim.Bind(wx.EVT_TEXT_ENTER,OnNumOutAzms)
792    littleSizer.Add(outAzim,0,wx.ALIGN_CENTER_VERTICAL)
793    dataSizer.Add(littleSizer,0,)
794
795    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Tilt angle'),0,
796        wx.ALIGN_CENTER_VERTICAL)
797    tiltSel = wx.TextCtrl(parent=self.dataDisplay,value=("%9.3f"%(data['tilt'])),style=wx.TE_READONLY)
798    dataSizer.Add(tiltSel,0,wx.ALIGN_CENTER_VERTICAL)
799    showLines = wx.CheckBox(parent=self.dataDisplay,label='Show integration limits?')
800    dataSizer.Add(showLines,0)
801    showLines.Bind(wx.EVT_CHECKBOX, OnShowLines)
802    showLines.SetValue(data['showLines'])
803    fullIntegrate = wx.CheckBox(parent=self.dataDisplay,label='Do full integration?')
804    dataSizer.Add(fullIntegrate,0)
805    fullIntegrate.Bind(wx.EVT_CHECKBOX, OnFullIntegrate)
806    fullIntegrate.SetValue(data['fullIntegrate'])
807   
808    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Tilt rotation'),0,
809        wx.ALIGN_CENTER_VERTICAL)
810    rotSel = wx.TextCtrl(parent=self.dataDisplay,value=("%9.3f"%(data['rotation'])),style=wx.TE_READONLY)
811    dataSizer.Add(rotSel,0,wx.ALIGN_CENTER_VERTICAL)
812    setDefault = wx.CheckBox(parent=self.dataDisplay,label='Use as default for all images?')
813    dataSizer.Add(setDefault,0)
814    setDefault.Bind(wx.EVT_CHECKBOX, OnSetDefault)
815    setDefault.SetValue(data['setDefault'])
816    setRings = wx.CheckBox(parent=self.dataDisplay,label='Show ring picks?')
817    dataSizer.Add(setRings,0)
818    setRings.Bind(wx.EVT_CHECKBOX, OnSetRings)
819    setRings.SetValue(data['setRings'])
820       
821    mainSizer.Add(dataSizer,0)
822   
823    mainSizer.Layout()   
824    self.dataDisplay.SetSizer(mainSizer)
825    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
826    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
827   
828def UpdateMasks(self,data):
829   
830    def OnThreshold(event):
831        lower = max(int(self.lowerThreshold.GetValue()),thresh[0][0])
832        upper = min(int(self.upperThreshold.GetValue()),thresh[0][1])
833        data['Thresholds'][1] = [lower,upper]
834        self.lowerThreshold.SetValue("%8d" % (lower))
835        self.upperThreshold.SetValue("%8d" % (upper))
836        G2plt.PlotExposedImage(self)
837       
838    def OnCopyMask(event):
839        TextList = []
840        Names = []
841        if self.PatternTree.GetCount():
842            id, cookie = self.PatternTree.GetFirstChild(self.root)
843            while id:
844                name = self.PatternTree.GetItemText(id)
845                Names.append(name)
846                if 'IMG' in name:
847                    if id == self.Image:
848                        Source = name
849                        mask = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,id, 'Masks'))
850                    else:
851                        TextList.append([False,name,id])
852                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
853            if not len(TextList):
854                self.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
855                return
856            dlg = self.CopyDialog(self,'Copy mask information','Copy mask from '+Source+' to:',TextList)
857            try:
858                if dlg.ShowModal() == wx.ID_OK:
859                    result = dlg.GetData()
860                    for i,item in enumerate(result[:-1]):
861                        ifcopy,name,id = item
862                        if ifcopy:                               
863                            self.PatternTree.SetItemPyData(GetPatternTreeItemId(self,id, 'Masks'),mask)
864            finally:
865                dlg.Destroy()
866       
867    if self.dataDisplay:
868        self.dataDisplay.Destroy()
869    self.dataFrame.SetMenuBar(self.dataFrame.MaskMenu)
870    self.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=wxID_MASKCOPY)
871    if not self.dataFrame.GetStatusBar():
872        Status = self.dataFrame.CreateStatusBar()
873    self.dataDisplay = wx.Panel(self.dataFrame)
874    mainSizer = wx.BoxSizer(wx.VERTICAL)
875    mainSizer.Add((5,10),0)
876
877    thresh = data['Thresholds']
878    littleSizer = wx.FlexGridSizer(2,3,0,5)
879    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper limits '),0,
880        wx.ALIGN_CENTER_VERTICAL)
881    littleSizer.Add(wx.TextCtrl(parent=self.dataDisplay,
882        value=("%8d" % (thresh[0][0])),style=wx.TE_READONLY),0,wx.ALIGN_CENTER_VERTICAL)
883    littleSizer.Add(wx.TextCtrl(parent=self.dataDisplay,
884        value=("%8d" % (thresh[0][1])),style=wx.wx.TE_READONLY),0,wx.ALIGN_CENTER_VERTICAL)
885   
886    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper thresholds '),0,
887        wx.ALIGN_CENTER_VERTICAL)
888    self.lowerThreshold = wx.TextCtrl(parent=self.dataDisplay,
889        value=("%8d" % (thresh[1][0])),style=wx.TE_PROCESS_ENTER)
890    self.lowerThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
891    littleSizer.Add(self.lowerThreshold,0,wx.ALIGN_CENTER_VERTICAL)
892    self.upperThreshold = wx.TextCtrl(parent=self.dataDisplay,
893        value=("%8d" % (thresh[1][1])),style=wx.TE_PROCESS_ENTER)
894    self.upperThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
895    littleSizer.Add(self.upperThreshold,0,wx.ALIGN_CENTER_VERTICAL)
896    mainSizer.Add(littleSizer,0,)
897       
898
899
900    mainSizer.Layout()   
901    self.dataDisplay.SetSizer(mainSizer)
902    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
903    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))   
904   
905def UpdatePhaseData(self,item,data,oldPage):
906    import GSASIIElem as G2el
907    Atoms = []
908    self.SelectedRow = 0
909   
910    def BookResize(event):
911        w,h = self.GetSize()
912        self.dataDisplay.SetSize(wx.Size(w,h))
913       
914    def FillGeneralGrid():
915        def SetLatticeParametersStyle(SGData,table):
916            if SGData['SGLaue'] in ['m3','m3m']:
917                table[4][2] = table[4][3] = table[4][1]
918                General.SetCellStyle(4,2,"light grey",True)
919                General.SetCellStyle(4,3,"light grey",True)
920                table[4][4] = table[4][5] = table[4][6] = 90.
921                General.SetCellStyle(4,4,"light grey",True)
922                General.SetCellStyle(4,5,"light grey",True)
923                General.SetCellStyle(4,6,"light grey",True)
924            elif SGData['SGLaue'] in ['3R','3mR']:
925                table[4][2] = table[4][3] = table[4][1]
926                General.SetCellStyle(4,2,"light grey",True)
927                General.SetCellStyle(4,3,"light grey",True)
928                table[4][5] = table[4][6] = table[4][4]
929                General.SetCellStyle(4,5,"light grey",True)
930                General.SetCellStyle(4,6,"light grey",True)
931            elif SGData['SGLaue'] in ['3','3m1','31m','6/m','6/mmm']:
932                table[4][2] = table[4][1]
933                General.SetCellStyle(4,2,"light grey",True)
934                table[4][4] = table[4][5] = 90.
935                table[4][6] = 120.
936                General.SetCellStyle(4,4,"light grey",True)
937                General.SetCellStyle(4,5,"light grey",True)
938                General.SetCellStyle(4,6,"light grey",True)
939            elif SGData['SGLaue'] in ['4/m','4/mmm']:
940                table[4][2] = table[4][1]
941                General.SetCellStyle(4,2,"light grey",True)
942                table[4][4] = table[4][5] = table[4][6] = 90.
943                General.SetCellStyle(4,4,"light grey",True)
944                General.SetCellStyle(4,5,"light grey",True)
945                General.SetCellStyle(4,6,"light grey",True)
946            elif SGData['SGLaue'] in ['mmm']:
947                table[4][4] = table[4][5] = table[4][6] = 90.
948                General.SetCellStyle(4,4,"light grey",True)
949                General.SetCellStyle(4,5,"light grey",True)
950                General.SetCellStyle(4,6,"light grey",True)
951            elif SGData['SGLaue'] in ['2/m']:
952                if SGData['SGUniq'] == 'a':
953                    table[4][5]= table[4][6] = 90.
954                    General.SetCellStyle(4,5,"light grey",True)
955                    General.SetCellStyle(4,6,"light grey",True)
956                if SGData['SGUniq'] == 'b':
957                    table[4][4]= table[4][6] = 90.
958                    General.SetCellStyle(4,4,"light grey",True)
959                    General.SetCellStyle(4,6,"light grey",True)
960                if SGData['SGUniq'] == 'c':
961                    table[4][4]= table[4][5] = 90.
962                    General.SetCellStyle(4,4,"light grey",True)
963                    General.SetCellStyle(4,5,"light grey",True)
964           
965        def RefreshGeneralGrid(event):
966               
967            r,c =  event.GetRow(),event.GetCol()
968            generalData[0] = table[0][0]
969            self.PatternTree.SetItemText(item,generalData[0])
970            generalData[1] = table[1][0]
971            SpcGp = table[2][0]
972            SGErr,SGData = G2spc.SpcGroup(SpcGp)
973            if r == 2 and c == 0:
974                if SGErr:
975                    text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous']
976                    table[2][0] = generalData[2]['SpGrp']
977                    msg = 'Space Group Error'
978                    Style = wx.ICON_EXCLAMATION
979                else:
980                    text = G2spc.SGPrint(SGData)
981                    generalData[2] = SGData
982                    msg = 'Space Group Information'
983                    Style = wx.ICON_INFORMATION
984                Text = ''
985                for line in text:
986                    Text += line+'\n'
987                wx.MessageBox(Text,caption=msg,style=Style)
988            General.SetCellValue(4,0,str(generalData[3][0]))
989            for c in range(1,7):
990                General.SetCellStyle(4,c,"white",False)
991                generalData[3][c] = float(General.GetCellValue(4,c))
992            generalData[3][7] = G2lat.calc_V(G2lat.cell2A(generalData[3][1:7]))
993            SetLatticeParametersStyle(SGData,table)
994            generalData[4][1] = float(General.GetCellValue(5,1))
995            General.ForceRefresh()
996                       
997        rowLabels = ['Phase name','Phase type','Space group',
998            'Lattice ',' parameters','Scale factor','Elements','No. per cell','Atom weight','','Bond radii','Angle radii']
999        generalData = data['General']
1000        atomData = data['Atoms']
1001        AtomTypes = []
1002        NoAtoms = {}
1003        BondRadii = []
1004        AngleRadii = []
1005        AtomMass = []
1006        colType = 1
1007        colSS = 7
1008        self.dataFrame.setSizePosLeft([600,350])
1009        if generalData[1] =='macromolecular':
1010            colType = 4
1011            colSS = 10
1012        for atom in atomData:
1013            if AtomTypes.count(atom[colType]):
1014                NoAtoms[atom[colType]] += atom[colSS-1]*atom[colSS+1]
1015            else:
1016                Info = G2el.GetAtomInfo(atom[colType])
1017                AtomTypes.append(Info['Symbol'])
1018                BondRadii.append(Info['Drad'])
1019                AngleRadii.append(Info['Arad'])
1020                AtomMass.append(Info['Mass'])
1021                NoAtoms[atom[colType]] = atom[colSS-1]*atom[colSS+1]
1022        generalData[5:9] = [AtomTypes,NoAtoms,AtomMass,BondRadii,AngleRadii]
1023        colLabels = []
1024        colLabels += ['' for i in range(max(8,len(generalData[5])))]
1025        table = []
1026        table.append([generalData[0],'','','','','','','',''])      #phase name
1027        table.append([generalData[1],'','','','','','','',''])      #phase type
1028        E,SGData = G2spc.SpcGroup(generalData[2]['SpGrp'])
1029        table.append([SGData['SpGrp'],'','','','','','','',''])     #space group symbol
1030        table.append(['refine','a    ','b    ','c    ','alpha ','beta ','gamma','volume  '])
1031        table.append(generalData[3])                      #lattice parameters
1032        table.append([generalData[4][0],generalData[4][1],'','','','','',''])   #scale factor
1033        table.append(generalData[5]+['' for i in range(max(8,len(generalData[5])))]) #element list
1034        line = []
1035        mass = 0.
1036        for i,elem in enumerate(generalData[5]):
1037            mass += generalData[6][elem]*generalData[7][i]
1038            line.append(generalData[6][elem])
1039        Volume = generalData[3][7]
1040        table.append(line+['' for i in range(max(8,len(generalData[5])))]) #No. per cell
1041        table.append(generalData[7]+['' for i in range(max(8,len(generalData[5])))])  #At. wt.
1042        if generalData[1] == 'macromolecular' and mass > 0.0:
1043            table.append(['density',mass/(0.6022137*Volume),'Matthews coeff.',Volume/mass,'','','','',''])           
1044        else:
1045            table.append(['density',mass/(0.6022137*Volume),'','','','','','',''])
1046        table.append(generalData[8]+['' for i in range(max(8,len(generalData[5])))])
1047        table.append(generalData[9]+['' for i in range(max(8,len(generalData[5])))])
1048        Types = [wg.GRID_VALUE_STRING for i in range(max(8,len(generalData[5])))]
1049        generalTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1050        General.SetTable(generalTable, True)
1051        General.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshGeneralGrid)
1052        General.SetMargins(0,0)
1053        General.SetColSize(0,100)
1054        General.SetColLabelSize(0)
1055        for c in range(max(8,len(generalData[5]))):
1056            if c > 0:
1057                General.SetReadOnly(0,c,isReadOnly=True)
1058                General.SetReadOnly(1,c,isReadOnly=True)
1059                General.SetReadOnly(2,c,isReadOnly=True)
1060            General.SetReadOnly(3,c,isReadOnly=True)                         #unit cell labels
1061            General.SetCellAlignment(3,c,wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
1062            if c < 4:
1063                General.SetCellRenderer(4,c,wg.GridCellFloatRenderer(10,5))
1064                General.SetCellEditor(4,c,wg.GridCellFloatEditor(10,5))
1065                General.SetReadOnly(9,c,isReadOnly=True)
1066            else:
1067                General.SetCellRenderer(4,c,wg.GridCellFloatRenderer(10,3))
1068                General.SetCellEditor(4,c,wg.GridCellFloatEditor(10,3))
1069            for r in range(6,12):
1070                General.SetReadOnly(r,c,isReadOnly=True)
1071        General.SetReadOnly(4,7,isReadOnly=True)                            #cell volume - no edit
1072        General.SetCellEditor(1,0,wg.GridCellChoiceEditor(['nuclear','modulated',   #phase type
1073            'magnetic','macromolecular','Pawley'],False))                           #- change only if no atoms
1074        if line:                                                    #no.of atoms not zero!
1075            General.SetReadOnly(1,0,isReadOnly=True)                #can't change phase type
1076        General.SetCellRenderer(4,0,wg.GridCellBoolRenderer())              #lattice parameters           
1077        General.SetCellEditor(4,0,wg.GridCellBoolEditor())
1078        SetLatticeParametersStyle(SGData,table)
1079        General.SetCellRenderer(5,1,wg.GridCellFloatRenderer(10,4))         #scale factor
1080        General.SetCellEditor(5,1,wg.GridCellFloatEditor(10,4))
1081        General.SetCellRenderer(5,0,wg.GridCellBoolRenderer())           
1082        General.SetCellEditor(5,0,wg.GridCellBoolEditor())
1083        General.SetCellRenderer(9,1,wg.GridCellFloatRenderer(8,3))
1084        General.SetCellRenderer(9,3,wg.GridCellFloatRenderer(8,3))
1085   
1086    def FillAtomsGrid():
1087       
1088        def RefreshAtomGrid(event):
1089            r,c =  event.GetRow(),event.GetCol()
1090            if r < 0:                          #on col label!
1091                sel = -1
1092                if Atoms.GetColLabelValue(c) == 'refine':
1093                    choice = ['F - site fraction','X - coordinates','U - thermal parameters']
1094                    dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice)
1095                    if dlg.ShowModal() == wx.ID_OK:
1096                        sel = dlg.GetSelections()
1097                        parms = ''
1098                        for x in sel:
1099                            parms += choice[x][0]                           
1100                elif Atoms.GetColLabelValue(c) == 'I/A':
1101                    choice = ['Isotropic','Anisotropic']
1102                    dlg = wx.SingleChoiceDialog(self,'Select','Thermal Motion',choice)
1103                    if dlg.ShowModal() == wx.ID_OK:
1104                        sel = dlg.GetSelection()
1105                        parms = choice[sel][0]
1106                if sel >= 0:
1107                    for r in range(Atoms.GetNumberRows()):
1108                        Atoms.SetCellValue(r,c,parms)
1109            elif c < 0:                    #picked atom row
1110                self.SelectedRow = r
1111            elif Atoms.GetColLabelValue(c) in ['x','y','z']:
1112                colLabel = Atoms.GetColLabelValue(c)
1113                if colLabel == 'x':
1114                    XYZ = [atomData[r][c],atomData[r][c+1],atomData[r][c+2]]
1115                elif colLabel == 'y':
1116                    XYZ = [atomData[r][c-1],atomData[r][c],atomData[r][c+1]]
1117                elif colLabel == 'z':
1118                    XYZ = [atomData[r][c-2],atomData[r][c-1],atomData[r][c]]
1119                if None in XYZ:
1120                    XYZ = [0,0,0]
1121                SScol = colLabels.index('site sym')
1122                Mulcol = colLabels.index('mult')
1123                E,SGData = G2spc.SpcGroup(generalData[2]['SpGrp'])
1124                Sytsym,Mult = G2spc.SytSym(XYZ,SGData)
1125                atomData[r][SScol] = Sytsym
1126                atomData[r][Mulcol] = Mult
1127                Atoms.ForceRefresh()
1128                   
1129        def AtomTypeSelect(event):
1130            r,c =  event.GetRow(),event.GetCol()
1131            if Atoms.GetColLabelValue(c) == 'Type':
1132                PE = G2elem.PickElement(self)
1133                if PE.ShowModal() == wx.ID_OK:
1134                    atomData[r][c] = PE.Elem.strip()
1135                PE.Destroy()
1136                Atoms.ForceRefresh()
1137            else:
1138                event.Skip()
1139       
1140        generalData = data['General']
1141        atomData = data['Atoms']
1142        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",
1143            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',
1144            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_STRING,wg.GRID_VALUE_NUMBER,wg.GRID_VALUE_CHOICE+":I,A",
1145            wg.GRID_VALUE_FLOAT+':10,4',
1146            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',
1147            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4']
1148        colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23']
1149        if generalData[1] == 'magnetic':
1150            colLabels += ['Mx','My','Mz']
1151            Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU,"
1152            Types += [
1153                wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4']
1154        elif generalData[1] == 'macromolecular':
1155            colLabels = ['res no','residue','chain'] + colLabels
1156            Types = [wg.GRID_VALUE_NUMBER,
1157                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",
1158                wg.GRID_VALUE_STRING] + Types       
1159        table = []
1160        rowLabels = []
1161        for i,atom in enumerate(atomData):
1162            table.append(atom)
1163            rowLabels.append(str(i+1))
1164        atomTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1165        Atoms.SetTable(atomTable, True)
1166        Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
1167        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1168        Atoms.Bind(wg.EVT_GRID_SELECT_CELL, AtomTypeSelect)
1169        Atoms.SetMargins(0,0)
1170        Atoms.AutoSizeColumns(True)
1171        colType = colLabels.index('Type')
1172        colSS = colLabels.index('site sym')
1173        colIA = colLabels.index('I/A')
1174        for row in range(Atoms.GetNumberRows()):
1175            Atoms.SetReadOnly(row,colSS,True)                         #site sym
1176            Atoms.SetReadOnly(row,colSS+1,True)                       #Mult
1177            if Atoms.GetCellValue(row,colIA) == 'I':
1178                for i in range(2,8):
1179                    Atoms.SetCellRenderer(row,colIA+i,wg.GridCellStringRenderer())
1180                    Atoms.SetReadOnly(row,colIA+i,isReadOnly=True)
1181                    Atoms.SetCellValue(row,colIA+i,'')
1182            elif Atoms.GetCellValue(row,colIA) == 'A':
1183                Atoms.SetCellRenderer(row,colIA+1,wg.GridCellStringRenderer())
1184                Atoms.SetReadOnly(row,colIA+1,isReadOnly=True)
1185                Atoms.SetCellValue(row,colIA+1,'')
1186       
1187    def AtomAdd(event):
1188        atomData = data['Atoms']
1189        generalData = data['General']
1190        Ncol = Atoms.GetNumberCols()
1191        if generalData[1] == 'macromolecular':
1192            atomData.append([0,'UNK','','UNK','UNK','',0,0,0,0,'',0,'I',0.10,0,0,0,0,0,0])
1193        elif generalData[1] == 'nuclear':
1194            atomData.append(['UNK','UNK','',0,0,0,0,'',0,'I',0.01,0,0,0,0,0,0])
1195        event.StopPropagation()
1196        FillAtomsGrid()
1197           
1198    def AtomInsert(event):
1199        atomData = data['Atoms']
1200        generalData = data['General']
1201        Ncol = Atoms.GetNumberCols()
1202        if generalData[1][0] == 'macromolecular':
1203            atomData.append([0,'UNK','','UNK','UNK','',0,0,0,0,'',0,'I',0.10,0,0,0,0,0,0])
1204        elif generalData[1][0] == 'nuclear':
1205            atomData.append(['UNK','UNK','',0,0,0,0,'',0,'I',0.01,0,0,0,0,0,0])
1206        event.StopPropagation()
1207        FillAtomsGrid()
1208       
1209    def UpdateDrawing():
1210        print 'Drawing'
1211       
1212    def FillPawleyReflectionsGrid():
1213       
1214        print 'Pawley reflections'
1215       
1216    def OnPageChanged(event):
1217        page = event.GetSelection()
1218        text = self.dataDisplay.GetPageText(page)
1219        if text == 'Atoms':
1220            self.dataFrame.SetMenuBar(self.dataFrame.AtomsMenu)
1221            self.dataFrame.Bind(wx.EVT_MENU, AtomAdd, id=wxID_ATOMSEDITADD)
1222            self.dataFrame.Bind(wx.EVT_MENU, AtomInsert, id=wxID_ATOMSEDITINSERT)
1223            FillAtomsGrid()           
1224        else:
1225            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1226        event.Skip()
1227       
1228    if self.dataDisplay:
1229        self.dataDisplay.Destroy()                   
1230    PhaseName = self.PatternTree.GetItemText(item)
1231    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1232    self.dataFrame.SetLabel('Phase Data for '+PhaseName)
1233    self.dataDisplay = GSNoteBook(parent=self.dataFrame,size=self.dataFrame.GetClientSize())
1234   
1235    General = GSGrid(parent=self.dataDisplay)
1236    FillGeneralGrid()
1237    self.dataDisplay.AddPage(General,'General')
1238     
1239    GeneralData = data['General']
1240    if GeneralData[3] == 'Pawley':
1241        PawleyRefl = GSGrid(parent=self.dataDisplay)
1242        self.dataDisplay.AddPage(PawleyRefl,'Pawley reflections')
1243        FillPawleyReflectionsGrid()
1244    else:
1245        Atoms = GSGrid(parent=self.dataDisplay)
1246        FillAtomsGrid()
1247        self.dataDisplay.AddPage(Atoms,'Atoms')
1248
1249    Drawing = wx.Window(parent=self.dataDisplay)
1250    self.dataDisplay.AddPage(Drawing,'Drawing')
1251   
1252    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
1253    self.dataDisplay.SetSelection(oldPage)
1254   
1255                         
1256def GetPatternTreeItemId(self, parentId, itemText):
1257    item, cookie = self.PatternTree.GetFirstChild(parentId)
1258    while item:
1259        if self.PatternTree.GetItemText(item) == itemText:
1260            return item
1261        item, cookie = self.PatternTree.GetNextChild(parentId, cookie)
1262    return 0               
1263
1264def MovePatternTreeToGrid(self,item):
1265   
1266    oldPage = 0
1267    if self.dataFrame:
1268        self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1269        if self.dataFrame.GetLabel() == 'Comments':
1270            data = [self.dataDisplay.GetValue()]
1271            self.dataDisplay.Clear() 
1272            Id = GetPatternTreeItemId(self,self.root, 'Comments')
1273            if Id: self.PatternTree.SetItemPyData(Id,data)
1274        if self.dataFrame.GetLabel() == 'Notebook':
1275            data = [self.dataDisplay.GetValue()]
1276            self.dataDisplay.Clear() 
1277            Id = GetPatternTreeItemId(self,self.root, 'Notebook')
1278            if Id: self.PatternTree.SetItemPyData(Id,data)
1279        if 'Phase Data for' in self.dataFrame.GetLabel():
1280            if self.dataDisplay: 
1281                oldPage = self.dataDisplay.GetSelection()
1282        self.dataFrame.Clear()
1283        self.dataFrame.SetLabel('')
1284    else:
1285       self.dataFrame = DataFrame(parent=self.mainPanel)
1286
1287    self.dataFrame.Raise()           
1288    self.PickId = 0
1289    parentID = self.root
1290    self.ExportPattern.Enable(False)
1291    if item != self.root:
1292        parentID = self.PatternTree.GetItemParent(item)
1293    if self.PatternTree.GetItemParent(item) == self.root:
1294        self.PatternId = item
1295        self.PickId = item
1296        if self.PatternTree.GetItemText(item) == 'Notebook':
1297            self.PatternId = 0
1298            self.ExportPattern.Enable(False)
1299            data = self.PatternTree.GetItemPyData(item)
1300            UpdateNotebook(self,data)
1301        elif self.PatternTree.GetItemText(item) == 'Controls':
1302            self.PatternId = 0
1303            self.ExportPattern.Enable(False)
1304            data = self.PatternTree.GetItemPyData(item)
1305            UpdateControls(self,data)
1306        elif 'IMG' in self.PatternTree.GetItemText(item):
1307            self.Image = item
1308            G2plt.PlotImage(self,newPlot=True)
1309        elif 'PKS' in self.PatternTree.GetItemText(item):
1310            G2plt.PlotPowderLines(self)
1311        elif 'PWDR' in self.PatternTree.GetItemText(item):           
1312            self.ExportPattern.Enable(True)
1313            G2plt.PlotPatterns(self,newPlot=True)
1314        elif 'SXTL' in self.PatternTree.GetItemText(item):
1315            self.Sngl = item
1316            G2plt.PlotSngl(self,newPlot=True)
1317           
1318    elif self.PatternTree.GetItemText(parentID) == 'Phases':
1319        self.PickId = item
1320        data = self.PatternTree.GetItemPyData(item)
1321        UpdatePhaseData(self,item,data,oldPage)
1322    elif self.PatternTree.GetItemText(item) == 'Comments':
1323        self.PatternId = self.PatternTree.GetItemParent(item)
1324        self.PickId = item
1325        data = self.PatternTree.GetItemPyData(item)
1326        UpdateComments(self,data)
1327    elif self.PatternTree.GetItemText(item) == 'Image Controls':
1328        self.dataFrame.SetTitle('Image Controls')
1329        self.PickId = item
1330        self.Image = self.PatternTree.GetItemParent(item)
1331        data = self.PatternTree.GetItemPyData(item)
1332        UpdateImageControls(self,data)
1333        G2plt.PlotImage(self)
1334    elif self.PatternTree.GetItemText(item) == 'Masks':
1335        self.dataFrame.SetTitle('Masks')
1336        self.PickId = item
1337        self.Image = self.PatternTree.GetItemParent(item)
1338        data = self.PatternTree.GetItemPyData(item)
1339        UpdateMasks(self,data)
1340        G2plt.PlotImage(self)
1341    elif self.PatternTree.GetItemText(item) == 'HKL Plot Controls':
1342        self.PickId = item
1343        self.Sngl = self.PatternTree.GetItemParent(item)
1344        data = self.PatternTree.GetItemPyData(item)
1345        UpdateHKLControls(self,data)
1346        G2plt.PlotSngl(self)               
1347    elif self.PatternTree.GetItemText(item) == 'Peak List':
1348        self.PatternId = self.PatternTree.GetItemParent(item)
1349        self.ExportPeakList.Enable(True)
1350        self.PickId = item
1351        data = self.PatternTree.GetItemPyData(item)
1352        G2pdG.UpdatePeakGrid(self,data)
1353        G2plt.PlotPatterns(self)
1354    elif self.PatternTree.GetItemText(item) == 'Background':
1355        self.PatternId = self.PatternTree.GetItemParent(item)
1356        self.PickId = item
1357        data = self.PatternTree.GetItemPyData(item)
1358        G2pdG.UpdateBackgroundGrid(self,data)
1359        G2plt.PlotPatterns(self)
1360    elif self.PatternTree.GetItemText(item) == 'Limits':
1361        self.PatternId = self.PatternTree.GetItemParent(item)
1362        self.PickId = item
1363        data = self.PatternTree.GetItemPyData(item)
1364        G2pdG.UpdateLimitsGrid(self,data)
1365        G2plt.PlotPatterns(self)
1366    elif self.PatternTree.GetItemText(item) == 'Instrument Parameters':
1367        self.PatternId = self.PatternTree.GetItemParent(item)
1368        self.PickId = item
1369        data = self.PatternTree.GetItemPyData(item)
1370        G2pdG.UpdateInstrumentGrid(self,data)
1371        G2plt.PlotPeakWidths(self)
1372    elif self.PatternTree.GetItemText(item) == 'Index Peak List':
1373        self.PatternId = self.PatternTree.GetItemParent(item)
1374        self.ExportPeakList.Enable(True)
1375        self.PickId = item
1376        data = self.PatternTree.GetItemPyData(item)
1377        G2pdG.UpdateIndexPeaksGrid(self,data)
1378        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
1379            G2plt.PlotPowderLines(self)
1380        else:
1381            G2plt.PlotPatterns(self)
1382    elif self.PatternTree.GetItemText(item) == 'Unit Cells List':
1383        self.PatternId = self.PatternTree.GetItemParent(item)
1384        self.PickId = item
1385        data = self.PatternTree.GetItemPyData(item)
1386        if not data:
1387            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
1388            data.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0])      #Bravais lattice flags
1389            data.append([])                                 #empty cell list
1390            data.append([])                                 #empty dmin
1391            self.PatternTree.SetItemPyData(item,data)                             
1392        G2pdG.UpdateUnitCellsGrid(self,data)
1393        self.dataFrame.RefineCell.Enable(True)
1394        self.dataFrame.IndexPeaks.Enable(True)
1395        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
1396            G2plt.PlotPowderLines(self)
1397        else:
1398            G2plt.PlotPatterns(self)
Note: See TracBrowser for help on using the repository browser.