source: trunk/GSASIIphsGUI.py @ 483

Last change on this file since 483 was 483, checked in by vondreele, 10 years ago

changes to eliminate wx objects (Colour & Point) from being saved in the gpx file
finish saving of selected sequential refinement results

  • Property svn:keywords set to Date Author Revision URL Id
File size: 152.8 KB
Line 
1#GSASII - phase data display routines
2########### SVN repository information ###################
3# $Date: 2012-02-14 19:59:51 +0000 (Tue, 14 Feb 2012) $
4# $Author: vondreele $
5# $Revision: 483 $
6# $URL: trunk/GSASIIphsGUI.py $
7# $Id: GSASIIphsGUI.py 483 2012-02-14 19:59:51Z vondreele $
8########### SVN repository information ###################
9import wx
10import wx.grid as wg
11import matplotlib as mpl
12import math
13import copy
14import time
15import sys
16import random as ran
17import cPickle
18import GSASIIpath
19import GSASIIlattice as G2lat
20import GSASIIspc as G2spc
21import GSASIIElem as G2elem
22import GSASIIplot as G2plt
23import GSASIIgrid as G2gd
24import GSASIIIO as G2IO
25import GSASIIstruct as G2str
26import numpy as np
27import numpy.linalg as nl
28
29VERY_LIGHT_GREY = wx.Colour(235,235,235)
30WHITE = wx.Colour(255,255,255)
31BLACK = wx.Colour(0,0,0)
32
33# trig functions in degrees
34sind = lambda x: math.sin(x*math.pi/180.)
35tand = lambda x: math.tan(x*math.pi/180.)
36cosd = lambda x: math.cos(x*math.pi/180.)
37asind = lambda x: 180.*math.asin(x)/math.pi
38
39class SymOpDialog(wx.Dialog):
40    def __init__(self,parent,SGData,New=True):
41        wx.Dialog.__init__(self,parent,-1,'Select symmetry operator',
42            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
43        panel = wx.Panel(self)
44        self.SGData = SGData
45        self.New = New
46        self.OpSelected = [0,0,0,[0,0,0],False]
47        mainSizer = wx.BoxSizer(wx.VERTICAL)
48        mainSizer.Add((5,5),0)
49        if SGData['SGInv']:
50            choice = ['No','Yes']
51            self.inv = wx.RadioBox(panel,-1,'Choose inversion?',choices=choice)
52            self.inv.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
53            mainSizer.Add(self.inv,0,wx.ALIGN_CENTER_VERTICAL)
54        mainSizer.Add((5,5),0)
55        if SGData['SGLatt'] != 'P':
56            LattOp = G2spc.Latt2text(SGData['SGLatt']).split(';')
57            self.latt = wx.RadioBox(panel,-1,'Choose cell centering?',choices=LattOp)
58            self.latt.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
59            mainSizer.Add(self.latt,0,wx.ALIGN_CENTER_VERTICAL)
60        mainSizer.Add((5,5),0)
61        if SGData['SGLaue'] in ['-1','2/m','mmm','4/m','4/mmm']:
62            Ncol = 2
63        else:
64            Ncol = 3
65        OpList = []
66        for M,T in SGData['SGOps']:
67            OpList.append(G2spc.MT2text(M,T))
68        self.oprs = wx.RadioBox(panel,-1,'Choose space group operator?',choices=OpList,
69            majorDimension=Ncol)
70        self.oprs.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
71        mainSizer.Add(self.oprs,0,wx.ALIGN_CENTER_VERTICAL)
72        mainSizer.Add((5,5),0)
73        mainSizer.Add(wx.StaticText(panel,-1,"   Choose unit cell?"),0,wx.ALIGN_CENTER_VERTICAL)
74        mainSizer.Add((5,5),0)
75        cellSizer = wx.BoxSizer(wx.HORIZONTAL)
76        cellSizer.Add((5,0),0)
77        cellName = ['X','Y','Z']
78        self.cell = []
79        for i in range(3):
80            self.cell.append(wx.SpinCtrl(panel,-1,cellName[i],size=wx.Size(50,20)))
81            self.cell[-1].SetRange(-3,3)
82            self.cell[-1].SetValue(0)
83            self.cell[-1].Bind(wx.EVT_SPINCTRL, self.OnOpSelect)
84            cellSizer.Add(self.cell[-1],0,wx.ALIGN_CENTER_VERTICAL)
85        mainSizer.Add(cellSizer,0,)
86        if self.New:
87            choice = ['No','Yes']
88            self.new = wx.RadioBox(panel,-1,'Generate new positions?',choices=choice)
89            self.new.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
90            mainSizer.Add(self.new,0,wx.ALIGN_CENTER_VERTICAL)
91        mainSizer.Add((5,5),0)
92
93        OkBtn = wx.Button(panel,-1,"Ok")
94        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
95        cancelBtn = wx.Button(panel,-1,"Cancel")
96        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
97        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
98        btnSizer.Add((20,20),1)
99        btnSizer.Add(OkBtn)
100        btnSizer.Add((20,20),1)
101        btnSizer.Add(cancelBtn)
102        btnSizer.Add((20,20),1)
103
104        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
105        panel.SetSizer(mainSizer)
106        panel.Fit()
107        self.Fit()
108
109    def OnOpSelect(self,event):
110        if self.SGData['SGInv']:
111            self.OpSelected[0] = self.inv.GetSelection()
112        if self.SGData['SGLatt'] != 'P':
113            self.OpSelected[1] = self.latt.GetSelection()
114        self.OpSelected[2] = self.oprs.GetSelection()
115        for i in range(3):
116            self.OpSelected[3][i] = float(self.cell[i].GetValue())
117        if self.New:
118            self.OpSelected[4] = self.new.GetSelection()
119
120    def GetSelection(self):
121        return self.OpSelected
122
123    def OnOk(self,event):
124        parent = self.GetParent()
125        parent.Raise()
126        self.EndModal(wx.ID_OK)
127        self.Destroy()
128
129    def OnCancel(self,event):
130        parent = self.GetParent()
131        parent.Raise()
132        self.EndModal(wx.ID_CANCEL)
133        self.Destroy()
134
135class DisAglDialog(wx.Dialog):
136   
137    def __default__(self,data,default):
138        if data:
139            self.data = data
140        else:
141            self.data = {}
142            self.data['Name'] = default['Name']
143            self.data['Factors'] = [0.85,0.85]
144            self.data['AtomTypes'] = default['AtomTypes']
145            self.data['BondRadii'] = default['BondRadii']
146            self.data['AngleRadii'] = default['AngleRadii']
147       
148    def __init__(self,parent,data,default):
149        wx.Dialog.__init__(self,parent,-1,'Distance Angle Controls', 
150            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
151        self.default = default
152        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
153        self.__default__(data,self.default)
154        self.Draw(self.data)
155               
156    def Draw(self,data):
157        self.panel.Destroy()
158        self.panel = wx.Panel(self)
159        mainSizer = wx.BoxSizer(wx.VERTICAL)
160        mainSizer.Add(wx.StaticText(self.panel,-1,'Controls for phase '+data['Name']),
161            0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
162        mainSizer.Add((10,10),1)
163       
164        radiiSizer = wx.FlexGridSizer(2,3,5,5)
165        radiiSizer.Add(wx.StaticText(self.panel,-1,' Type'),0,wx.ALIGN_CENTER_VERTICAL)
166        radiiSizer.Add(wx.StaticText(self.panel,-1,'Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
167        radiiSizer.Add(wx.StaticText(self.panel,-1,'Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
168        self.objList = {}
169        for id,item in enumerate(self.data['AtomTypes']):
170            radiiSizer.Add(wx.StaticText(self.panel,-1,' '+item),0,wx.ALIGN_CENTER_VERTICAL)
171            bRadii = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['BondRadii'][id]),style=wx.TE_PROCESS_ENTER)
172            self.objList[bRadii.GetId()] = ['BondRadii',id]
173            bRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
174            bRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
175            radiiSizer.Add(bRadii,0,wx.ALIGN_CENTER_VERTICAL)
176            aRadii = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['AngleRadii'][id]),style=wx.TE_PROCESS_ENTER)
177            self.objList[aRadii.GetId()] = ['AngleRadii',id]
178            aRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
179            aRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
180            radiiSizer.Add(aRadii,0,wx.ALIGN_CENTER_VERTICAL)
181        mainSizer.Add(radiiSizer,0,wx.EXPAND)
182        factorSizer = wx.FlexGridSizer(2,2,5,5)
183        Names = ['Bond','Angle']
184        for i,name in enumerate(Names):
185            factorSizer.Add(wx.StaticText(self.panel,-1,name+' search factor'),0,wx.ALIGN_CENTER_VERTICAL)
186            bondFact = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['Factors'][i]),style=wx.TE_PROCESS_ENTER)
187            self.objList[bondFact.GetId()] = ['Factors',i]
188            bondFact.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
189            bondFact.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
190            factorSizer.Add(bondFact)
191        mainSizer.Add(factorSizer,0,wx.EXPAND)
192       
193        OkBtn = wx.Button(self.panel,-1,"Ok")
194        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
195        ResetBtn = wx.Button(self.panel,-1,'Reset')
196        ResetBtn.Bind(wx.EVT_BUTTON, self.OnReset)
197        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
198        btnSizer.Add((20,20),1)
199        btnSizer.Add(OkBtn)
200        btnSizer.Add(ResetBtn)
201        btnSizer.Add((20,20),1)
202        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
203        self.panel.SetSizer(mainSizer)
204        self.panel.Fit()
205        self.Fit()
206   
207    def OnRadiiVal(self,event):
208        Obj = event.GetEventObject()
209        item = self.objList[Obj.GetId()]
210        try:
211            self.data[item[0]][item[1]] = float(Obj.GetValue())
212        except ValueError:
213            pass
214        Obj.SetValue("%.3f"%(self.data[item[0]][item[1]]))          #reset in case of error
215       
216    def GetData(self):
217        return self.data
218       
219    def OnOk(self,event):
220        parent = self.GetParent()
221        parent.Raise()
222        self.EndModal(wx.ID_OK)             
223        self.Destroy()
224       
225    def OnReset(self,event):
226        data = {}
227        self.__default__(data,self.default)
228        self.Draw(self.data)
229       
230def UpdatePhaseData(G2frame,Item,data,oldPage):
231
232    Atoms = []
233    if G2frame.dataDisplay:
234        G2frame.dataDisplay.Destroy()
235    PhaseName = G2frame.PatternTree.GetItemText(Item)
236    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
237    G2frame.dataFrame.SetLabel('Phase Data for '+PhaseName)
238    G2frame.dataFrame.CreateStatusBar()
239    G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
240
241    def SetupGeneral():
242        generalData = data['General']
243        atomData = data['Atoms']
244        generalData['AtomTypes'] = []
245        generalData['Isotopes'] = {}
246        if 'Isotope' not in generalData:
247            generalData['Isotope'] = {}
248        if 'Data plot type' not in generalData:
249            generalData['Data plot type'] = 'Mustrain'
250        if 'POhkl' not in generalData:
251            generalData['POhkl'] = [0,0,1]
252        generalData['NoAtoms'] = {}
253        generalData['BondRadii'] = []
254        generalData['AngleRadii'] = []
255        generalData['vdWRadii'] = []
256        generalData['AtomMass'] = []
257        generalData['Color'] = []
258        generalData['Mydir'] = G2frame.dirname
259        cx,ct,cs,cia = [3,1,7,9]
260        generalData['AtomPtrs'] = [cx,ct,cs,cia]
261        if generalData['Type'] =='macromolecular':
262            cx,ct,cs,cia = [6,4,10,12]
263            generalData['AtomPtrs'] = [cx,ct,cs,cia]
264        for atom in atomData:
265            atom[ct] = atom[ct].lower().capitalize()              #force to standard form
266            if generalData['AtomTypes'].count(atom[ct]):
267                generalData['NoAtoms'][atom[ct]] += atom[cs-1]*float(atom[cs+1])
268            elif atom[ct] != 'UNK':
269                Info = G2elem.GetAtomInfo(atom[ct])
270                generalData['AtomTypes'].append(atom[ct])
271                generalData['Isotopes'][atom[ct]] = Info['Isotopes']
272                generalData['BondRadii'].append(Info['Drad'])
273                generalData['AngleRadii'].append(Info['Arad'])
274                generalData['vdWRadii'].append(Info['Vdrad'])
275                if atom[ct] in generalData['Isotope']:
276                    generalData['AtomMass'].append(Info['Isotopes'][generalData['Isotope'][atom[ct]]][0])
277                else:
278                    generalData['AtomMass'].append(Info['Mass'])
279                generalData['NoAtoms'][atom[ct]] = atom[cs-1]*float(atom[cs+1])
280                generalData['Color'].append(Info['Color'])
281
282    def UpdateGeneral():
283       
284        ''' default dictionary structure for phase data: (taken from GSASII.py)
285        'General':{
286            'Name':PhaseName
287            'Type':'nuclear'
288            'SGData':SGData
289            'Cell':[False,10.,10.,10.,90.,90.,90,1000.]
290            'AtomPtrs':[]
291            'Histogram list':['',]
292            'Pawley dmin':1.0}
293        'Atoms':[]
294        'Drawing':{}
295        '''
296        G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataGeneral) # do this here, since this is called from all over
297       
298        phaseTypes = ['nuclear','modulated','magnetic','macromolecular','Pawley']
299        SetupGeneral()
300        generalData = data['General']
301       
302        def OnPhaseName(event):
303            oldName = generalData['Name']
304            generalData['Name'] = NameTxt.GetValue()
305            G2frame.G2plotNB.Rename(oldName,generalData['Name'])
306            G2frame.dataFrame.SetLabel('Phase Data for '+generalData['Name'])
307            G2frame.PatternTree.SetItemText(Item,generalData['Name'])
308            #Hmm, need to change phase name key in Reflection Lists for each histogram
309                       
310        def OnPhaseType(event):
311            if not generalData['AtomTypes']:             #can change only if no atoms!
312                generalData['Type'] = TypeTxt.GetValue()
313                dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
314                UpdateGeneral()         #must use this way!
315                if generalData['Type'] == 'Pawley':
316                    if G2frame.dataDisplay.FindPage('Atoms'):
317                        G2frame.dataDisplay.DeletePage(G2frame.dataDisplay.FindPage('Atoms'))
318                        G2frame.dataDisplay.DeletePage(G2frame.dataDisplay.FindPage('Draw Options'))
319                        G2frame.dataDisplay.DeletePage(G2frame.dataDisplay.FindPage('Draw Atoms'))
320                    if not G2frame.dataDisplay.FindPage('Pawley reflections'):
321                        G2frame.PawleyRefl = G2gd.GSGrid(G2frame.dataDisplay)     
322                        G2frame.dataDisplay.AddPage(G2frame.PawleyRefl,'Pawley reflections')
323            else:
324                TypeTxt.SetValue(generalData['Type'])               
325               
326        def OnSpaceGroup(event):
327            SpcGp = SGTxt.GetValue()
328            SGErr,SGData = G2spc.SpcGroup(SpcGp)
329            if SGErr:
330                text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous']
331                SGTxt.SetValue(generalData['SGData']['SpGrp'])
332                msg = 'Space Group Error'
333                Style = wx.ICON_EXCLAMATION
334            else:
335                text = G2spc.SGPrint(SGData)
336                generalData['SGData'] = SGData
337                msg = 'Space Group Information'
338                Style = wx.ICON_INFORMATION
339            Text = ''
340            for line in text:
341                Text += line+'\n'
342            wx.MessageBox(Text,caption=msg,style=Style)
343            dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
344            UpdateGeneral()
345           
346        def OnCellRef(event):
347            generalData['Cell'][0] = cellRef.GetValue()
348           
349        def OnCellChange(event):
350            SGData = generalData['SGData']
351            laue = SGData['SGLaue']
352            if laue == '2/m':
353                laue += SGData['SGUniq']
354            cell = generalData['Cell']
355            Obj = event.GetEventObject()
356            ObjId = cellList.index(Obj.GetId())
357            try:
358                value = max(1.0,float(Obj.GetValue()))
359            except ValueError:
360                if ObjId < 3:               #bad cell edge - reset
361                    value = controls[6+ObjId]
362                else:                       #bad angle
363                    value = 90.
364            if laue in ['m3','m3m']:
365                cell[1] = cell[2] = cell[3] = value
366                cell[4] = cell[5] = cell[6] = 90.0
367                Obj.SetValue("%.5f"%(cell[1]))
368            elif laue in ['3R','3mR']:
369                if ObjId == 0:
370                    cell[1] = cell[2] = cell[3] = value
371                    Obj.SetValue("%.5f"%(cell[1]))
372                else:
373                    cell[4] = cell[5] = cell[6] = value
374                    Obj.SetValue("%.5f"%(cell[4]))
375            elif laue in ['3','3m1','31m','6/m','6/mmm','4/m','4/mmm']:                   
376                cell[4] = cell[5] = 90.
377                cell[6] = 120.
378                if laue in ['4/m','4/mmm']:
379                    cell[6] = 90.
380                if ObjId == 0:
381                    cell[1] = cell[2] = value
382                    Obj.SetValue("%.5f"%(cell[1]))
383                else:
384                    cell[3] = value
385                    Obj.SetValue("%.5f"%(cell[3]))
386            elif laue in ['mmm']:
387                cell[ObjId+1] = value
388                cell[4] = cell[5] = cell[6] = 90.
389                Obj.SetValue("%.5f"%(cell[ObjId+1]))
390            elif laue in ['2/m'+'a']:
391                cell[5] = cell[6] = 90.
392                if ObjId != 3:
393                    cell[ObjId+1] = value
394                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
395                else:
396                    cell[4] = value
397                    Obj.SetValue("%.3f"%(cell[4]))
398            elif laue in ['2/m'+'b']:
399                cell[4] = cell[6] = 90.
400                if ObjId != 3:
401                    cell[ObjId+1] = value
402                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
403                else:
404                    cell[5] = value
405                    Obj.SetValue("%.3f"%(cell[5]))
406            elif laue in ['2/m'+'c']:
407                cell[5] = cell[6] = 90.
408                if ObjId != 3:
409                    cell[ObjId+1] = value
410                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
411                else:
412                    cell[6] = value
413                    Obj.SetValue("%.3f"%(cell[6]))
414            else:
415                cell[ObjId+1] = value
416                if ObjId < 3:
417                    Obj.SetValue("%.5f"%(cell[1+ObjId]))
418                else:
419                    Obj.SetValue("%.3f"%(cell[1+ObjId]))
420            cell[7] = G2lat.calc_V(G2lat.cell2A(cell[1:7]))
421            volVal.SetValue("%.3f"%(cell[7]))
422            generalData['Cell'] = cell
423            dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
424            UpdateGeneral()
425                       
426        def OnPawleyVal(event):
427            try:
428                dmin = float(pawlVal.GetValue())
429                if 0.25 <= dmin <= 20.:
430                    generalData['Pawley dmin'] = dmin
431            except ValueError:
432                pass
433            pawlVal.SetValue("%.3f"%(generalData['Pawley dmin']))          #reset in case of error       
434           
435        def OnIsotope(event):
436            Obj = event.GetEventObject()
437            item = Indx[Obj.GetId()]
438            isotope = Obj.GetValue()
439            generalData['Isotope'][item] = isotope
440            indx = generalData['AtomTypes'].index(item)
441            data['General']['AtomMass'][indx] = generalData['Isotopes'][item][isotope][0]
442            dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
443            UpdateGeneral()
444                                               
445        cellGUIlist = [[['m3','m3m'],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
446        [['3R','3mR'],6,zip([" a = "," alpha = "," Vol = "],["%.5f","%.3f","%.3f"],[True,True,False],[0,2,0])],
447        [['3','3m1','31m','6/m','6/mmm','4/m','4/mmm'],6,zip([" a = "," c = "," Vol = "],["%.5f","%.5f","%.3f"],[True,True,False],[0,2,0])],
448        [['mmm'],8,zip([" a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
449            [True,True,True,False],[0,1,2,0])],
450        [['2/m'+'a'],10,zip([" a = "," b = "," c = "," alpha = "," Vol = "],
451            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
452        [['2/m'+'b'],10,zip([" a = "," b = "," c = "," beta = "," Vol = "],
453            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
454        [['2/m'+'c'],10,zip([" a = "," b = "," c = "," gamma = "," Vol = "],
455            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
456        [['-1'],8,zip([" a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
457            ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
458            [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
459       
460        General.DestroyChildren()
461        dataDisplay = wx.Panel(General)
462        mainSizer = wx.BoxSizer(wx.VERTICAL)
463        mainSizer.Add((5,5),0)
464        mainSizer.Add(wx.StaticText(dataDisplay,-1,'General phase data:'),0,wx.ALIGN_CENTER_VERTICAL)
465        mainSizer.Add((5,5),0)
466        nameSizer = wx.BoxSizer(wx.HORIZONTAL)
467        nameSizer.Add(wx.StaticText(dataDisplay,-1,' Phase name: '),0,wx.ALIGN_CENTER_VERTICAL)
468        NameTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['Name'],style=wx.TE_PROCESS_ENTER)
469        NameTxt.Bind(wx.EVT_TEXT_ENTER,OnPhaseName)
470        NameTxt.Bind(wx.EVT_KILL_FOCUS,OnPhaseName)
471        nameSizer.Add(NameTxt,0,wx.ALIGN_CENTER_VERTICAL)
472        nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Phase type: '),0,wx.ALIGN_CENTER_VERTICAL)
473        if len(data['Atoms']):
474            choices = phaseTypes[:-1]
475        else:
476            choices = phaseTypes           
477        TypeTxt = wx.ComboBox(dataDisplay,-1,value=generalData['Type'],choices=choices,
478            style=wx.CB_READONLY|wx.CB_DROPDOWN)
479        TypeTxt.Bind(wx.EVT_COMBOBOX, OnPhaseType)
480        nameSizer.Add(TypeTxt,0,wx.ALIGN_CENTER_VERTICAL)
481        nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Space group: '),0,wx.ALIGN_CENTER_VERTICAL)
482        SGTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['SGData']['SpGrp'],style=wx.TE_PROCESS_ENTER)
483        SGTxt.Bind(wx.EVT_TEXT_ENTER,OnSpaceGroup)
484        nameSizer.Add(SGTxt,0,wx.ALIGN_CENTER_VERTICAL)
485        mainSizer.Add(nameSizer,0)
486        mainSizer.Add((5,5),0)
487        cell = generalData['Cell']
488        laue = generalData['SGData']['SGLaue']
489        if laue == '2/m':
490            laue += generalData['SGData']['SGUniq']
491        for cellGUI in cellGUIlist:
492            if laue in cellGUI[0]:
493                useGUI = cellGUI
494        cellList = []
495        cellSizer = wx.FlexGridSizer(2,useGUI[1]+1,5,5)
496        cellRef = wx.CheckBox(dataDisplay,-1,label='Refine unit cell:')
497        cellSizer.Add(cellRef,0,wx.ALIGN_CENTER_VERTICAL)
498        cellRef.Bind(wx.EVT_CHECKBOX, OnCellRef)
499        cellRef.SetValue(cell[0])
500        for txt,fmt,ifEdit,Id in useGUI[2]:
501            cellSizer.Add(wx.StaticText(dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL)
502            if ifEdit:          #a,b,c,etc.
503                cellVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[Id+1])),
504                    style=wx.TE_PROCESS_ENTER)
505                cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
506                cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
507                cellSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL)
508                cellList.append(cellVal.GetId())
509            else:               #volume
510                volVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[7])),style=wx.TE_READONLY)
511                volVal.SetBackgroundColour(VERY_LIGHT_GREY)
512                cellSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL)
513        mainSizer.Add(cellSizer,0)
514        mainSizer.Add((5,5),0)
515       
516        Indx = {}
517        if len(generalData['AtomTypes']):
518            mass = 0.
519            for i,elem in enumerate(generalData['AtomTypes']):
520                mass += generalData['NoAtoms'][elem]*generalData['AtomMass'][i]
521            denSizer = wx.BoxSizer(wx.HORIZONTAL)
522            denSizer.Add(wx.StaticText(dataDisplay,-1,' Density: '),0,wx.ALIGN_CENTER_VERTICAL)
523            Volume = generalData['Cell'][7]
524            density = mass/(0.6022137*Volume)
525            denTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(density),style=wx.TE_READONLY)
526            denTxt.SetBackgroundColour(VERY_LIGHT_GREY)
527            denSizer.Add(denTxt,0,wx.ALIGN_CENTER_VERTICAL)       
528            if generalData['Type'] == 'macromolecular' and mass > 0.0:
529                denSizer.Add(wx.StaticText(dataDisplay,-1,' Matthews coeff.: '),
530                    0,wx.ALIGN_CENTER_VERTICAL)
531                mattTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(Volume/mass),style=wx.TE_READONLY)
532                mattTxt.SetBackgroundColour(VERY_LIGHT_GREY)
533                denSizer.Add(mattTxt,0,wx.ALIGN_CENTER_VERTICAL)
534            mainSizer.Add(denSizer)
535            mainSizer.Add((5,5),0)
536           
537            elemSizer = wx.FlexGridSizer(8,len(generalData['AtomTypes'])+1,1,1)
538            elemSizer.Add(wx.StaticText(dataDisplay,label='Elements'),0,wx.ALIGN_CENTER_VERTICAL)
539            for elem in generalData['AtomTypes']:
540                typTxt = wx.TextCtrl(dataDisplay,value=elem,style=wx.TE_READONLY)
541                typTxt.SetBackgroundColour(VERY_LIGHT_GREY)
542                elemSizer.Add(typTxt,0,wx.ALIGN_CENTER_VERTICAL)
543            elemSizer.Add(wx.StaticText(dataDisplay,label='Isotope'),0,wx.ALIGN_CENTER_VERTICAL)
544            for elem in generalData['AtomTypes']:
545                choices = generalData['Isotopes'][elem].keys()
546                if elem not in generalData['Isotope']:
547                    generalData['Isotope'][elem] = 'Nat. Abund.'
548                isoSel = wx.ComboBox(dataDisplay,-1,value=generalData['Isotope'][elem],choices=choices,
549                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
550                isoSel.Bind(wx.EVT_COMBOBOX,OnIsotope)
551                Indx[isoSel.GetId()] = elem
552                elemSizer.Add(isoSel,1,wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
553            elemSizer.Add(wx.StaticText(dataDisplay,label='No. per cell'),0,wx.ALIGN_CENTER_VERTICAL)
554            for elem in generalData['AtomTypes']:
555                numbTxt = wx.TextCtrl(dataDisplay,value='%.1f'%(generalData['NoAtoms'][elem]),
556                    style=wx.TE_READONLY)
557                numbTxt.SetBackgroundColour(VERY_LIGHT_GREY)
558                elemSizer.Add(numbTxt,0,wx.ALIGN_CENTER_VERTICAL)
559            elemSizer.Add(wx.StaticText(dataDisplay,label='Atom weight'),0,wx.ALIGN_CENTER_VERTICAL)
560            for wt in generalData['AtomMass']:
561                wtTxt = wx.TextCtrl(dataDisplay,value='%.3f'%(wt),style=wx.TE_READONLY)
562                wtTxt.SetBackgroundColour(VERY_LIGHT_GREY)
563                elemSizer.Add(wtTxt,0,wx.ALIGN_CENTER_VERTICAL)
564            elemSizer.Add(wx.StaticText(dataDisplay,label='Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
565            for rad in generalData['BondRadii']:
566                bondRadii = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
567                bondRadii.SetBackgroundColour(VERY_LIGHT_GREY)
568                elemSizer.Add(bondRadii,0,wx.ALIGN_CENTER_VERTICAL)
569            elemSizer.Add(wx.StaticText(dataDisplay,label='Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
570            for rad in generalData['AngleRadii']:
571                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
572                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
573                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
574            elemSizer.Add(wx.StaticText(dataDisplay,label='van der Waals radii'),0,wx.ALIGN_CENTER_VERTICAL)
575            for rad in generalData['vdWRadii']:
576                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
577                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
578                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
579            elemSizer.Add(wx.StaticText(dataDisplay,label='Default color'),0,wx.ALIGN_CENTER_VERTICAL)
580            for R,G,B in generalData['Color']:
581                colorTxt = wx.TextCtrl(dataDisplay,value='',style=wx.TE_READONLY)
582                colorTxt.SetBackgroundColour(wx.Colour(R,G,B))
583                elemSizer.Add(colorTxt,0,wx.ALIGN_CENTER_VERTICAL)
584            mainSizer.Add(elemSizer)
585           
586        elif generalData['Type'] == 'Pawley':
587            pawlSizer = wx.BoxSizer(wx.HORIZONTAL)
588            pawlSizer.Add(wx.StaticText(dataDisplay,label=' Pawley dmin: '),0,wx.ALIGN_CENTER_VERTICAL)
589            pawlVal = wx.TextCtrl(dataDisplay,value='%.3f'%(generalData['Pawley dmin']),style=wx.TE_PROCESS_ENTER)
590            pawlVal.Bind(wx.EVT_TEXT_ENTER,OnPawleyVal)       
591            pawlVal.Bind(wx.EVT_KILL_FOCUS,OnPawleyVal)
592            pawlSizer.Add(pawlVal,0,wx.ALIGN_CENTER_VERTICAL)
593            mainSizer.Add(pawlSizer)
594
595        dataDisplay.SetSizer(mainSizer)
596        Size = mainSizer.Fit(G2frame.dataFrame)
597        Size[1] += 26                           #compensate for status bar
598        dataDisplay.SetSize(Size)
599        G2frame.dataFrame.setSizePosLeft(Size)
600
601    def FillAtomsGrid():
602
603        G2frame.dataFrame.setSizePosLeft([700,300])
604        generalData = data['General']
605        atomData = data['Atoms']
606        Items = [G2gd.wxID_ATOMSEDITINSERT, G2gd.wxID_ATOMSEDITDELETE, G2gd.wxID_ATOMSREFINE, 
607            G2gd.wxID_ATOMSMODIFY, G2gd.wxID_ATOMSTRANSFORM, G2gd.wxID_ATONTESTINSERT]
608        if atomData:
609            for item in Items:   
610                G2frame.dataFrame.AtomsMenu.Enable(item,True)
611        else:
612            for item in Items:
613                G2frame.dataFrame.AtomsMenu.Enable(item,False)           
614           
615        AAchoice = ": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK"
616        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",]+ \
617            3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_FLOAT+':10,4', #x,y,z,frac
618            wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+":I,A",]
619        Types += 7*[wg.GRID_VALUE_FLOAT+':10,5',]
620        colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23']
621        if generalData['Type'] == 'magnetic':
622            colLabels += ['Mx','My','Mz']
623            Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU,"
624            Types += 3*[wg.GRID_VALUE_FLOAT+':10,4',]
625        elif generalData['Type'] == 'macromolecular':
626            colLabels = ['res no','residue','chain'] + colLabels
627            Types = [wg.GRID_VALUE_STRING,
628                wg.GRID_VALUE_CHOICE+AAchoice,
629                wg.GRID_VALUE_STRING] + Types
630        elif generalData['Type'] == 'modulated':
631            Types += []
632            colLabels += []
633
634        def RefreshAtomGrid(event):
635
636            r,c =  event.GetRow(),event.GetCol()
637            if r < 0 and c < 0:
638                for row in range(Atoms.GetNumberRows()):
639                    Atoms.SelectRow(row,True)                   
640            if r < 0:                          #double click on col label! Change all atoms!
641                sel = -1
642                noSkip = True
643                if Atoms.GetColLabelValue(c) == 'refine':
644                    Type = generalData['Type']
645                    if Type in ['nuclear','macromolecular']:
646                        choice = ['F - site fraction','X - coordinates','U - thermal parameters']
647                    elif Type in ['magnetic',]:
648                        choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
649                    dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice)
650                    if dlg.ShowModal() == wx.ID_OK:
651                        sel = dlg.GetSelections()
652                        parms = ''
653                        for x in sel:
654                            parms += choice[x][0]
655                    dlg.Destroy()
656                elif Atoms.GetColLabelValue(c) == 'I/A':
657                    choice = ['Isotropic','Anisotropic']
658                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal Motion',choice)
659                    if dlg.ShowModal() == wx.ID_OK:
660                        sel = dlg.GetSelection()
661                        parms = choice[sel][0]
662                    dlg.Destroy()
663                elif Atoms.GetColLabelValue(c) == 'Type':
664                    choice = generalData['AtomTypes']
665                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom types',choice)
666                    if dlg.ShowModal() == wx.ID_OK:
667                        sel = dlg.GetSelection()
668                        parms = choice[sel]
669                        noSkip = False
670                        Atoms.ClearSelection()
671                        for row in range(Atoms.GetNumberRows()):
672                            if parms == atomData[row][c]:
673                                Atoms.SelectRow(row,True)
674                elif Atoms.GetColLabelValue(c) == 'residue':
675                    choice = []
676                    for r in range(Atoms.GetNumberRows()):
677                        if str(atomData[r][c]) not in choice:
678                            choice.append(str(atomData[r][c]))
679                    choice.sort()
680                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue',choice)
681                    if dlg.ShowModal() == wx.ID_OK:
682                        sel = dlg.GetSelection()
683                        parms = choice[sel]
684                        noSkip = False
685                        Atoms.ClearSelection()
686                        for row in range(Atoms.GetNumberRows()):
687                            if parms == atomData[row][c]:
688                                Atoms.SelectRow(row,True)
689                elif Atoms.GetColLabelValue(c) == 'res no':
690                    choice = []
691                    for r in range(Atoms.GetNumberRows()):
692                        if str(atomData[r][c]) not in choice:
693                            choice.append(str(atomData[r][c]))
694                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue no.',choice)
695                    if dlg.ShowModal() == wx.ID_OK:
696                        sel = dlg.GetSelection()
697                        parms = choice[sel]
698                        noSkip = False
699                        Atoms.ClearSelection()
700                        for row in range(Atoms.GetNumberRows()):
701                            if int(parms) == atomData[row][c]:
702                                Atoms.SelectRow(row,True)
703                elif Atoms.GetColLabelValue(c) == 'chain':
704                    choice = []
705                    for r in range(Atoms.GetNumberRows()):
706                        if atomData[r][c] not in choice:
707                            choice.append(atomData[r][c])
708                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Chain',choice)
709                    if dlg.ShowModal() == wx.ID_OK:
710                        sel = dlg.GetSelection()
711                        parms = choice[sel]
712                        noSkip = False
713                        Atoms.ClearSelection()
714                        for row in range(Atoms.GetNumberRows()):
715                            if parms == atomData[row][c]:
716                                Atoms.SelectRow(row,True)
717                    dlg.Destroy()
718                elif Atoms.GetColLabelValue(c) == 'Uiso':       #this needs to ask for value
719                    pass                                        #& then change all 'I' atoms
720                if sel >= 0 and noSkip:
721                    ui = colLabels.index('U11')
722                    us = colLabels.index('Uiso')
723                    ss = colLabels.index('site sym')
724                    for r in range(Atoms.GetNumberRows()):
725                        ID = atomData[r][-1]
726                        if parms != atomData[r][c] and Atoms.GetColLabelValue(c) == 'I/A':
727                            if parms == 'A':                #'I' --> 'A'
728                                Uiso = float(Atoms.GetCellValue(r,us))
729                                sytsym = atomData[r][ss]
730                                CSI = G2spc.GetCSuinel(sytsym)
731                                atomData[r][ui:ui+6] = Uiso*np.array(CSI[3])
732                                atomData[r][us] = 0.0
733                                Atoms.SetCellStyle(r,us,VERY_LIGHT_GREY,True)
734                                for i in range(6):
735                                    ci = ui+i
736                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
737                                    if CSI[2][i]:
738                                        Atoms.SetCellStyle(r,ci,WHITE,False)
739                            else:                           #'A' --> 'I'
740                                Uij = atomData[r][ui:ui+6]
741                                Uiso = (Uij[0]+Uij[1]+Uij[2])/3.0
742                                atomData[r][us] = Uiso
743                                Atoms.SetCellStyle(r,us,WHITE,False)
744                                for i in range(6):
745                                    ci = ui+i
746                                    atomData[r][ci] = 0.0
747                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
748                        atomData[r][c] = parms
749                        if 'Atoms' in data['Drawing']:
750                            DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
751                    FillAtomsGrid()
752                   
753        def ChangeAtomCell(event):
754           
755            def chkUij(Uij,CSI): #needs to do something!!!
756                return Uij
757
758            r,c =  event.GetRow(),event.GetCol()
759            if r >= 0 and c >= 0:
760                ID = atomData[r][-1]
761                if Atoms.GetColLabelValue(c) in ['x','y','z']:
762                    ci = colLabels.index('x')
763                    XYZ = atomData[r][ci:ci+3]
764                    if None in XYZ:
765                        XYZ = [0,0,0]
766                    SScol = colLabels.index('site sym')
767                    Mulcol = colLabels.index('mult')
768                    E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
769                    Sytsym,Mult = G2spc.SytSym(XYZ,SGData)
770                    atomData[r][SScol] = Sytsym
771                    atomData[r][Mulcol] = Mult
772                    if atomData[r][colLabels.index('I/A')] == 'A':
773                        ui = colLabels.index('U11')
774                        CSI = G2spc.GetCSuinel(Sytsym)
775                        atomData[r][ui:ui+6] = chkUij(atomData[r][ui:ui+6],Sytsym)
776                        for i in range(6):
777                            ci = i+ui
778                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
779                            if CSI[2][i]:
780                                Atoms.SetCellStyle(r,ci,WHITE,False)
781                    SetupGeneral()
782                elif Atoms.GetColLabelValue(c) == 'I/A':            #note use of text color to make it vanish!
783                    if atomData[r][c] == 'I':
784                        Uij = atomData[r][c+2:c+8]
785                        atomData[r][c+1] = (Uij[0]+Uij[1]+Uij[2])/3.0
786                        Atoms.SetCellStyle(r,c+1,WHITE,False)
787                        Atoms.SetCellTextColour(r,c+1,BLACK)
788                        for i in range(6):
789                            ci = i+colLabels.index('U11')
790                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
791                            Atoms.SetCellTextColour(r,ci,VERY_LIGHT_GREY)
792                            atomData[r][ci] = 0.0
793                    else:
794                        value = atomData[r][c+1]
795                        CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
796                        atomData[r][c+1] =  0.0
797                        Atoms.SetCellStyle(r,c+1,VERY_LIGHT_GREY,True)
798                        Atoms.SetCellTextColour(r,c+1,VERY_LIGHT_GREY)
799                        for i in range(6):
800                            ci = i+colLabels.index('U11')
801                            atomData[r][ci] = value*CSI[3][i]
802                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
803                            Atoms.SetCellTextColour(r,ci,BLACK)
804                            if CSI[2][i]:
805                                Atoms.SetCellStyle(r,ci,WHITE,False)
806                elif Atoms.GetColLabelValue(c) in ['U11','U22','U33','U12','U13','U23']:
807                    value = atomData[r][c]
808                    CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
809                    iUij = CSI[0][c-colLabels.index('U11')]
810                    for i in range(6):
811                        if iUij == CSI[0][i]:
812                            atomData[r][i+colLabels.index('U11')] = value*CSI[1][i]
813                if 'Atoms' in data['Drawing']:
814                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
815                    FindBondsDraw()
816                   
817        def AtomTypeSelect(event):
818            r,c =  event.GetRow(),event.GetCol()
819            if Atoms.GetColLabelValue(c) == 'Type':
820                PE = G2elem.PickElement(G2frame)
821                if PE.ShowModal() == wx.ID_OK:
822                    atomData[r][c] = PE.Elem.strip()
823                    name = atomData[r][c]
824                    if len(name) in [2,4]:
825                        atomData[r][c-1] = name[:2]+'(%d)'%(r+1)
826                    else:
827                        atomData[r][c-1] = name[:1]+'(%d)'%(r+1)
828                PE.Destroy()
829                SetupGeneral()
830                FillAtomsGrid()
831                value = Atoms.GetCellValue(r,c)
832                atomData[r][c] = value
833                ID = atomData[r][-1]
834                if 'Atoms' in data['Drawing']:
835                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
836            else:
837                event.Skip()
838
839        def RowSelect(event):
840            r,c =  event.GetRow(),event.GetCol()
841            if r < 0 and c < 0:
842                if Atoms.IsSelection():
843                    Atoms.ClearSelection()
844            elif c < 0:                   #only row clicks
845                if event.ControlDown():                   
846                    if r in Atoms.GetSelectedRows():
847                        Atoms.DeselectRow(r)
848                    else:
849                        Atoms.SelectRow(r,True)
850                elif event.ShiftDown():
851                    for row in range(r+1):
852                        Atoms.SelectRow(row,True)
853                else:
854                    Atoms.ClearSelection()
855                    Atoms.SelectRow(r,True)               
856               
857        def ChangeSelection(event):
858            r,c =  event.GetRow(),event.GetCol()
859            if r < 0 and c < 0:
860                Atoms.ClearSelection()
861            if c < 0:
862                if r in Atoms.GetSelectedRows():
863                    Atoms.DeselectRow(r)
864                else:
865                    Atoms.SelectRow(r,True)
866            if r < 0:
867                if c in Atoms.GetSelectedCols():
868                    Atoms.DeselectCol(c)
869                else:
870                    Atoms.SelectCol(c,True)
871       
872        SGData = data['General']['SGData']
873        if SGData['SGPolax']:
874            G2frame.dataFrame.SetStatusText('Warning: The location of the origin is arbitrary in '+SGData['SGPolax'])
875        table = []
876        rowLabels = []
877        for i,atom in enumerate(atomData):
878            table.append(atom)
879            rowLabels.append(str(i))
880        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
881        Atoms.SetTable(atomTable, True)
882        Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeAtomCell)
883        Atoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, AtomTypeSelect)
884        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
885        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
886        Atoms.Bind(wg.EVT_GRID_LABEL_RIGHT_CLICK, ChangeSelection)
887        Atoms.SetMargins(0,0)
888        Atoms.AutoSizeColumns(False)
889        colType = colLabels.index('Type')
890        colSS = colLabels.index('site sym')
891        colIA = colLabels.index('I/A')
892        colU11 = colLabels.index('U11')
893        colUiso = colLabels.index('Uiso')
894        for i in range(colU11-1,colU11+6):
895            Atoms.SetColSize(i,50)           
896        for row in range(Atoms.GetNumberRows()):
897            Atoms.SetReadOnly(row,colType,True)
898            Atoms.SetReadOnly(row,colSS,True)                         #site sym
899            Atoms.SetReadOnly(row,colSS+1,True)                       #Mult
900            if Atoms.GetCellValue(row,colIA) == 'A':
901                CSI = G2spc.GetCSuinel(atomData[row][colLabels.index('site sym')])
902                Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True)
903                Atoms.SetCellTextColour(row,colUiso,VERY_LIGHT_GREY)
904                for i in range(6):
905                    ci = colU11+i
906                    Atoms.SetCellTextColour(row,ci,BLACK)
907                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
908                    if CSI[2][i]:
909                        Atoms.SetCellStyle(row,ci,WHITE,False)
910            else:
911                Atoms.SetCellStyle(row,colUiso,WHITE,False)
912                Atoms.SetCellTextColour(row,colUiso,BLACK)
913                for i in range(6):
914                    ci = colU11+i
915                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
916                    Atoms.SetCellTextColour(row,ci,VERY_LIGHT_GREY)
917
918    def OnAtomAdd(event):
919        AtomAdd(0,0,0)
920        FillAtomsGrid()
921        event.StopPropagation()
922       
923    def OnAtomTestAdd(event):
924        try:
925            drawData = data['Drawing']
926            x,y,z = drawData['testPos'][0]
927            AtomAdd(x,y,z)
928        except:
929            AtomAdd(0,0,0)
930        FillAtomsGrid()
931        event.StopPropagation()
932               
933    def AtomAdd(x,y,z):
934        atomData = data['Atoms']
935        generalData = data['General']
936        Ncol = Atoms.GetNumberCols()
937        atId = ran.randint(0,sys.maxint)
938        E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
939        Sytsym,Mult = G2spc.SytSym([x,y,z],SGData)
940        if generalData['Type'] == 'macromolecular':
941            atomData.append([0,'UNK','','UNK','H','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
942        elif generalData['Type'] == 'nuclear':
943            atomData.append(['UNK','H','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
944        elif generalData['Type'] == 'magnetic':
945            atomData.append(['UNK','H','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId])
946        SetupGeneral()
947        if 'Atoms' in data['Drawing']:           
948            DrawAtomAdd(data['Drawing'],atomData[-1])
949            G2plt.PlotStructure(G2frame,data)
950
951    def OnAtomInsert(event):
952        AtomInsert(0,0,0)
953        FillAtomsGrid()
954        event.StopPropagation()
955       
956    def OnAtomTestInsert(event):
957        if 'Drawing' in data:
958            drawData = data['Drawing']
959            x,y,z = drawData['testPos'][0]
960            AtomAdd(x,y,z)
961            FillAtomsGrid()
962        event.StopPropagation()
963           
964    def AtomInsert(x,y,z):
965        indx = Atoms.GetSelectedRows()
966        if indx:
967            indx = indx[0]
968            atomData = data['Atoms']
969            generalData = data['General']
970            Ncol = Atoms.GetNumberCols()
971            E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
972            Sytsym,Mult = G2spc.SytSym([0,0,0],SGData)
973            atId = ran.randint(0,sys.maxint)
974            if generalData['Type'] == 'macromolecular':
975                atomData.insert(indx,[0,'UNK','','UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
976            elif generalData['Type'] == 'nuclear':
977                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
978            elif generalData['Type'] == 'magnetic':
979                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId])
980            SetupGeneral()
981
982    def AtomDelete(event):
983        indx = Atoms.GetSelectedRows()
984        IDs = []
985        if indx:
986            atomData = data['Atoms']
987            indx.reverse()
988            for ind in indx:
989                atom = atomData[ind]
990                IDs.append(atom[-1])
991                del atomData[ind]
992            if 'Atoms' in data['Drawing']:
993                DrawAtomsDeleteByIDs(IDs)
994                FillAtomsGrid()
995                G2plt.PlotStructure(G2frame,data)
996        event.StopPropagation()
997
998    def AtomRefine(event):
999        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1000        c = colLabels.index('refine')
1001        indx = Atoms.GetSelectedRows()
1002        if indx:
1003            atomData = data['Atoms']
1004            generalData = data['General']
1005            Type = generalData['Type']
1006            if Type in ['nuclear','macromolecular']:
1007                choice = ['F - site fraction','X - coordinates','U - thermal parameters']
1008            elif Type == 'magnetic':
1009                choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
1010            dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice)
1011            if dlg.ShowModal() == wx.ID_OK:
1012                sel = dlg.GetSelections()
1013                parms = ''
1014                for x in sel:
1015                    parms += choice[x][0]
1016                for r in indx:
1017                    atomData[r][c] = parms
1018                Atoms.ForceRefresh()
1019            dlg.Destroy()
1020
1021    def AtomModify(event):                  #intent to implement global modifications (+,-,*,/, etc.)?
1022        indx = Atoms.GetSelectedRows()
1023        if indx:
1024            atomData = data['Atoms']
1025            generalData = data['General']
1026
1027    def AtomTransform(event):
1028        indx = Atoms.GetSelectedRows()
1029        if indx:
1030            generalData = data['General']
1031            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1032            cx = colLabels.index('x')
1033            cuia = colLabels.index('I/A')
1034            cuij = colLabels.index('U11')
1035            css = colLabels.index('site sym')
1036            atomData = data['Atoms']
1037            generalData = data['General']
1038            SGData = generalData['SGData']
1039            dlg = SymOpDialog(G2frame,SGData,True)
1040            try:
1041                if dlg.ShowModal() == wx.ID_OK:
1042                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1043                    Cell = np.array(Cell)
1044                    cent = SGData['SGCen'][Cent]
1045                    M,T = SGData['SGOps'][Opr]
1046                    for ind in indx:
1047                        XYZ = np.array(atomData[ind][cx:cx+3])
1048                        XYZ = np.inner(M,XYZ)+T
1049                        if Inv:
1050                            XYZ = -XYZ
1051                        XYZ = XYZ+cent+Cell
1052                        if New:
1053                            atom = copy.copy(atomData[ind])
1054                        else:
1055                            atom = atomData[ind]
1056                        atom[cx:cx+3] = XYZ
1057                        atom[css:css+2] = G2spc.SytSym(XYZ,SGData)
1058                        if atom[cuia] == 'A':
1059                            Uij = atom[cuij:cuij+6]
1060                            U = G2spc.Uij2U(Uij)
1061                            U = np.inner(np.inner(M,U),M)
1062                            Uij = G2spc.U2Uij(U)
1063                            atom[cuij:cuij+6] = Uij
1064                        if New:
1065                            atomData.append(atom)
1066            finally:
1067                dlg.Destroy()
1068            Atoms.ClearSelection()
1069            if New:
1070                FillAtomsGrid()
1071            else:
1072                Atoms.ForceRefresh()
1073
1074    def OnDistAngle(event):
1075        indx = Atoms.GetSelectedRows()
1076        Oxyz = []
1077        xyz = []
1078        DisAglData = {}
1079        DisAglCtls = {}
1080        if indx:
1081            generalData = data['General']
1082            DisAglData['OrigIndx'] = indx
1083            if 'DisAglCtls' in generalData:
1084                DisAglCtls = generalData['DisAglCtls']
1085            dlg = DisAglDialog(G2frame,DisAglCtls,generalData)
1086            if dlg.ShowModal() == wx.ID_OK:
1087                DisAglCtls = dlg.GetData()
1088            dlg.Destroy()
1089            generalData['DisAglCtls'] = DisAglCtls
1090            atomData = data['Atoms']
1091            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1092            cx = colLabels.index('x')
1093            cn = colLabels.index('Name')
1094            for i,atom in enumerate(atomData):
1095                xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1096                if i in indx:
1097                    Oxyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1098            DisAglData['OrigAtoms'] = Oxyz
1099            DisAglData['TargAtoms'] = xyz
1100            generalData = data['General']
1101            DisAglData['SGData'] = generalData['SGData']
1102            DisAglData['Cell'] = generalData['Cell'][1:] #+ volume
1103            if 'pId' in data:
1104                DisAglData['pId'] = data['pId']
1105                DisAglData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance'))
1106            G2str.DistAngle(DisAglCtls,DisAglData)
1107           
1108#Structure drawing GUI stuff               
1109
1110    def SetupDrawingData():
1111        generalData = data['General']
1112        atomData = data['Atoms']
1113        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
1114            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
1115        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
1116            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
1117        defaultDrawing = {'viewPoint':[[0.5,0.5,0.5],[]],'showHydrogen':True,'backColor':[0,0,0],'depthFog':False,
1118            'Zclip':50.0,'cameraPos':50.,'radiusFactor':0.85,
1119            'bondRadius':0.1,'ballScale':0.33,'vdwScale':0.67,'ellipseProb':50,'sizeH':0.50,
1120            'unitCellBox':False,'showABC':True,'selectedAtoms':[],
1121            'Rotation':[0.0,0.0,0.0,[]],'bondList':{},'testPos':[[-.1,-.1,-.1],[0.0,0.0,0.0],[0,0]]}
1122        try:
1123            drawingData = data['Drawing']
1124        except KeyError:
1125            data['Drawing'] = {}
1126            drawingData = data['Drawing']
1127        if not drawingData:                 #fill with defaults if empty
1128            drawingData = copy.copy(defaultDrawing)
1129            drawingData['Atoms'] = []
1130        cx,ct,cs = [0,0,0]
1131        if generalData['Type'] == 'nuclear':
1132            cx,ct,cs = [2,1,6]         #x, type & style
1133        elif generalData['Type'] == 'macromolecular':
1134            cx,ct,cs = [5,4,9]         #x, type & style
1135        elif generalData['Type'] == 'magnetic':
1136            cx,ct,cs = [2,1,6]         #x, type & style
1137#        elif generalData['Type'] == 'modulated':
1138#           ?????   for future
1139        if not drawingData['Atoms']:
1140            for atom in atomData:
1141                DrawAtomAdd(drawingData,atom)
1142            drawingData['atomPtrs'] = [cx,ct,cs]
1143            data['Drawing'] = drawingData
1144           
1145    def MakeDrawAtom(atom,oldatom=None):
1146        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
1147            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
1148        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
1149            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
1150        generalData = data['General']
1151        SGData = generalData['SGData']
1152        if generalData['Type'] == 'nuclear':
1153            if oldatom:
1154                opr = oldatom[5]
1155                if atom[9] == 'A':                   
1156                    X,U = G2spc.ApplyStringOps(opr,SGData,atom[3:6],atom[11:17])
1157                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:11]+list(U)+oldatom[17:]][0]
1158                else:
1159                    X = G2spc.ApplyStringOps(opr,SGData,atom[3:6])
1160                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:]+[oldatom[-1]]][0]
1161            else:
1162                atomInfo = [atom[:2]+atom[3:6]+['1',]+['vdW balls',]+
1163                    ['',]+[[255,255,255],]+atom[9:]+[[],[]]][0]
1164            ct,cs = [1,8]         #type & color
1165        elif generalData['Type'] == 'macromolecular':
1166            try:
1167                oneLetter = AA3letter.index(atom[1])
1168            except ValueError:
1169                oneLetter = -1
1170            atomInfo = [[atom[1].strip()+atom[0],]+
1171                [AA1letter[oneLetter]+atom[0],]+atom[2:5]+
1172                atom[6:9]+['1',]+['sticks',]+['',]+[[255,255,255],]+atom[12:]+[[],[]]][0]
1173            ct,cs = [4,11]         #type & color
1174        elif generalData['Type'] == 'magnetic':
1175            if oldatom:
1176                atomInfo = [atom[:2]+oldatom[3:]][0]
1177            else:
1178                atomInfo = [atom[:2]+atom[3:6]+['vdW balls',]+['',]+atom[9:]+[[],[]]][0]
1179            ct,cs = [1,8]         #type & color
1180#        elif generalData['Type'] == 'modulated':
1181#           ?????   for future
1182        atNum = generalData['AtomTypes'].index(atom[ct])
1183        atomInfo[cs] = list(generalData['Color'][atNum])
1184        return atomInfo
1185           
1186    def DrawAtomAdd(drawingData,atom):
1187        drawingData['Atoms'].append(MakeDrawAtom(atom))
1188       
1189    def DrawAtomsReplaceByID(drawingData,atom,ID):
1190        IDs = [ID,]
1191        atomData = drawingData['Atoms']
1192        indx = FindAtomIndexByIDs(atomData,IDs)
1193        for ind in indx:
1194            atomData[ind] = MakeDrawAtom(atom,atomData[ind])
1195           
1196    def UpdateDrawAtoms():
1197        generalData = data['General']
1198        SetupDrawingData()
1199        drawingData = data['Drawing']
1200        cx,ct,cs = drawingData['atomPtrs']
1201        atomData = drawingData['Atoms']
1202        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',]+ \
1203            [wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,polyhedra",
1204            wg.GRID_VALUE_CHOICE+": ,type,name,number",wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]
1205        styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1206        labelChoice = [' ','type','name','number']
1207        colLabels = ['Name','Type','x','y','z','Sym Op','Style','Label','Color','I/A']
1208        if generalData['Type'] == 'macromolecular':
1209            colLabels = ['Residue','1-letter','Chain'] + colLabels
1210            Types = 3*[wg.GRID_VALUE_STRING,]+Types
1211            Types[8] = wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,backbone,ribbons,schematic"
1212            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','backbone','ribbons','schematic']
1213            labelChoice = [' ','type','name','number','residue','1-letter','chain']
1214            Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1-letter,chain"
1215#        elif generalData['Type'] == 'modulated':
1216#            Types += []
1217#            colLabels += []
1218
1219        def RefreshAtomGrid(event):
1220
1221            def SetChoice(name,c,n=0):
1222                choice = []
1223                for r in range(len(atomData)):
1224                    if n:
1225                        srchStr = str(atomData[r][c][:n])
1226                    else:
1227                        srchStr = str(atomData[r][c])
1228                    if srchStr not in choice:
1229                        if n:
1230                            choice.append(str(atomData[r][c][:n]))
1231                        else:
1232                            choice.append(str(atomData[r][c]))
1233                choice.sort()
1234
1235                dlg = wx.MultiChoiceDialog(G2frame,'Select',name,choice)
1236                if dlg.ShowModal() == wx.ID_OK:
1237                    sel = dlg.GetSelections()
1238                    parms = []
1239                    for x in sel:
1240                        parms.append(choice[x])
1241                    noSkip = False
1242                    drawAtoms.ClearSelection()
1243                    drawingData['selectedAtoms'] = []
1244                    for row in range(len(atomData)):
1245                        test = atomData[row][c]
1246                        if n:
1247                            test = test[:n]
1248                        if  test in parms:
1249                            drawAtoms.SelectRow(row,True)
1250                            drawingData['selectedAtoms'].append(row)
1251                    G2plt.PlotStructure(G2frame,data)                   
1252                dlg.Destroy()
1253               
1254            r,c =  event.GetRow(),event.GetCol()
1255            if r < 0 and c < 0:
1256                for row in range(drawAtoms.GetNumberRows()):
1257                    drawingData['selectedAtoms'].append(row)
1258                    drawAtoms.SelectRow(row,True)                   
1259            elif r < 0:                          #dclick on col label
1260                sel = -1
1261                Parms = False
1262                noSkip = True
1263                if drawAtoms.GetColLabelValue(c) == 'Style':
1264                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice)
1265                    if dlg.ShowModal() == wx.ID_OK:
1266                        sel = dlg.GetSelection()
1267                        parms = styleChoice[sel]
1268                        for r in range(len(atomData)):
1269                            atomData[r][c] = parms
1270                            drawAtoms.SetCellValue(r,c,parms)
1271                        FindBondsDraw()
1272                        G2plt.PlotStructure(G2frame,data)
1273                    dlg.Destroy()
1274                elif drawAtoms.GetColLabelValue(c) == 'Label':
1275                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom labelling style',labelChoice)
1276                    if dlg.ShowModal() == wx.ID_OK:
1277                        sel = dlg.GetSelection()
1278                        parms = labelChoice[sel]
1279                        for r in range(len(atomData)):
1280                            atomData[r][c] = parms
1281                            drawAtoms.SetCellValue(r,c,parms)
1282                    dlg.Destroy()                   
1283                elif drawAtoms.GetColLabelValue(c) == 'Color':
1284                    dlg = wx.ColourDialog(G2frame)
1285                    if dlg.ShowModal() == wx.ID_OK:
1286                        color = dlg.GetColourData().GetColour()
1287                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1288                        attr.SetReadOnly(True)
1289                        attr.SetBackgroundColour(color)
1290                        for r in range(len(atomData)):
1291                            atomData[r][c] = color
1292                            drawingData['Atoms'][r][c] = color
1293                            drawAtoms.SetAttr(r,c,attr)
1294                        UpdateDrawAtoms()
1295                    dlg.Destroy()
1296                elif drawAtoms.GetColLabelValue(c) == 'Residue':
1297                    SetChoice('Residue',c,3)
1298                elif drawAtoms.GetColLabelValue(c) == '1-letter':
1299                    SetChoice('1-letter',c,1)
1300                elif drawAtoms.GetColLabelValue(c) == 'Chain':
1301                    SetChoice('Chain',c)
1302                elif drawAtoms.GetColLabelValue(c) == 'Name':
1303                    SetChoice('Name',c)
1304                elif drawAtoms.GetColLabelValue(c) == 'Sym Op':
1305                    SetChoice('Name',c)
1306                elif drawAtoms.GetColLabelValue(c) == 'Type':
1307                    SetChoice('Type',c)
1308                elif drawAtoms.GetColLabelValue(c) in ['x','y','z','I/A']:
1309                    drawAtoms.ClearSelection()
1310            else:
1311                if drawAtoms.GetColLabelValue(c) in ['Style','Label']:
1312                    atomData[r][c] = drawAtoms.GetCellValue(r,c)
1313                    FindBondsDraw()
1314                elif drawAtoms.GetColLabelValue(c) == 'Color':
1315                    color = atomData[r][c]
1316                    colors = wx.ColourData()
1317                    colors.SetChooseFull(True)
1318                    colors.SetCustomColour(0,color)
1319                    colors.SetColour(color)
1320                    dlg = wx.ColourDialog(G2frame,colors)
1321                    dlg.GetColourData().SetCustomColour(0,color)
1322                    if dlg.ShowModal() == wx.ID_OK:
1323                        color = dlg.GetColourData().GetColour()
1324                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1325                        attr.SetReadOnly(True)
1326                        attr.SetBackgroundColour(color)
1327                        atomData[r][c] = color
1328                        drawingData['Atoms'][r][c] = color
1329                        drawAtoms.SetAttr(i,cs+2,attr)
1330                    dlg.Destroy()
1331                    event.StopPropagation()
1332                    UpdateDrawAtoms()
1333            G2plt.PlotStructure(G2frame,data)
1334                   
1335        def RowSelect(event):
1336            r,c =  event.GetRow(),event.GetCol()
1337            if r < 0 and c < 0:
1338                if drawAtoms.IsSelection():
1339                    drawAtoms.ClearSelection()
1340            elif c < 0:                   #only row clicks
1341                if event.ControlDown():                   
1342                    if r in drawAtoms.GetSelectedRows():
1343                        drawAtoms.DeselectRow(r)
1344                    else:
1345                        drawAtoms.SelectRow(r,True)
1346                elif event.ShiftDown():
1347                    for row in range(r+1):
1348                        drawAtoms.SelectRow(row,True)
1349                else:
1350                    drawAtoms.ClearSelection()
1351                    drawAtoms.SelectRow(r,True)               
1352            drawingData['selectedAtoms'] = []
1353            drawingData['selectedAtoms'] = drawAtoms.GetSelectedRows()
1354            G2plt.PlotStructure(G2frame,data)                   
1355               
1356        table = []
1357        rowLabels = []
1358        for i,atom in enumerate(drawingData['Atoms']):
1359            table.append(atom[:colLabels.index('I/A')+1])
1360            rowLabels.append(str(i))
1361
1362        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1363        drawAtoms.SetTable(atomTable, True)
1364        drawAtoms.SetMargins(0,0)
1365        drawAtoms.AutoSizeColumns(True)
1366        drawAtoms.SetColSize(colLabels.index('Style'),80)
1367        drawAtoms.SetColSize(colLabels.index('Color'),50)
1368        drawAtoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
1369        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1370        drawAtoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, RefreshAtomGrid)
1371        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
1372        for i,atom in enumerate(drawingData['Atoms']):
1373            attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1374            attr.SetReadOnly(True)
1375            attr.SetBackgroundColour(atom[cs+2])
1376            drawAtoms.SetAttr(i,cs+2,attr)
1377            drawAtoms.SetCellValue(i,cs+2,'')
1378        indx = drawingData['selectedAtoms']
1379        if indx:
1380            for r in range(len(atomData)):
1381                if r in indx:
1382                    drawAtoms.SelectRow(r)
1383        for c in range(len(colLabels)):
1384           attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1385           attr.SetReadOnly(True)
1386           attr.SetBackgroundColour(VERY_LIGHT_GREY)
1387           if colLabels[c] not in ['Style','Label','Color']:
1388                drawAtoms.SetColAttr(c,attr)
1389        G2frame.dataFrame.setSizePosLeft([600,300])
1390       
1391        FindBondsDraw()
1392        drawAtoms.ClearSelection()
1393        G2plt.PlotStructure(G2frame,data)
1394
1395    def DrawAtomStyle(event):
1396        indx = drawAtoms.GetSelectedRows()
1397        if indx:
1398            generalData = data['General']
1399            atomData = data['Drawing']['Atoms']
1400            cx,ct,cs = data['Drawing']['atomPtrs']
1401            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1402            if generalData['Type'] == 'macromolecular':
1403                styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids',
1404                'backbone','ribbons','schematic']
1405            dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice)
1406            if dlg.ShowModal() == wx.ID_OK:
1407                sel = dlg.GetSelection()
1408                parms = styleChoice[sel]
1409                for r in indx:
1410                    atomData[r][cs] = parms
1411                    drawAtoms.SetCellValue(r,cs,parms)
1412            dlg.Destroy()
1413            FindBondsDraw()
1414            drawAtoms.ClearSelection()
1415            G2plt.PlotStructure(G2frame,data)
1416
1417    def DrawAtomLabel(event):
1418        indx = drawAtoms.GetSelectedRows()
1419        if indx:
1420            generalData = data['General']
1421            atomData = data['Drawing']['Atoms']
1422            cx,ct,cs = data['Drawing']['atomPtrs']
1423            styleChoice = [' ','type','name','number']
1424            if generalData['Type'] == 'macromolecular':
1425                styleChoice = [' ','type','name','number','residue','1-letter','chain']
1426            dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom label style',styleChoice)
1427            if dlg.ShowModal() == wx.ID_OK:
1428                sel = dlg.GetSelection()
1429                parms = styleChoice[sel]
1430                for r in indx:
1431                    atomData[r][cs+1] = parms
1432                    drawAtoms.SetCellValue(r,cs+1,parms)
1433            dlg.Destroy()
1434            drawAtoms.ClearSelection()
1435            G2plt.PlotStructure(G2frame,data)
1436           
1437    def DrawAtomColor(event):
1438
1439        indx = drawAtoms.GetSelectedRows()
1440        if indx:
1441            if len(indx) > 1:
1442                G2frame.dataFrame.SetStatusText('Select Custom Color, change color, Add to Custom Colors, then OK')
1443            else:
1444                G2frame.dataFrame.SetStatusText('Change color, Add to Custom Colors, then OK')
1445            generalData = data['General']
1446            atomData = data['Drawing']['Atoms']
1447            cx,ct,cs = data['Drawing']['atomPtrs']
1448            atmColors = []
1449            atmTypes = []
1450            for r in indx:
1451                if atomData[r][cs+2] not in atmColors:
1452                    atmColors.append(atomData[r][cs+2])
1453                    atmTypes.append(atomData[r][ct])
1454                    if len(atmColors) > 16:
1455                        break
1456            colors = wx.ColourData()
1457            colors.SetChooseFull(True)
1458            for i,color in enumerate(atmColors):
1459                colors.SetCustomColour(i,color)
1460            dlg = wx.ColourDialog(G2frame,colors)
1461            if dlg.ShowModal() == wx.ID_OK:
1462                for i in range(len(atmColors)):                   
1463                    atmColors[i] = dlg.GetColourData().GetCustomColour(i)
1464                colorDict = dict(zip(atmTypes,atmColors))
1465                for r in indx:
1466                    color = colorDict[atomData[r][ct]]
1467                    atomData[r][cs+2] = color
1468                    attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1469                    attr.SetBackgroundColour(color)
1470                    drawAtoms.SetAttr(r,cs+2,attr)
1471                    data['Drawing']['Atoms'][r][cs+2] = color
1472            drawAtoms.ClearSelection()
1473            dlg.Destroy()
1474            G2frame.dataFrame.SetStatusText('')
1475           
1476    def ResetAtomColors(event):
1477        generalData = data['General']
1478        atomData = data['Drawing']['Atoms']
1479        cx,ct,cs = data['Drawing']['atomPtrs']
1480        for atom in atomData:           
1481            atNum = generalData['AtomTypes'].index(atom[ct])
1482            atom[cs+2] = list(generalData['Color'][atNum])
1483        UpdateDrawAtoms()
1484        drawAtoms.ClearSelection()
1485        G2plt.PlotStructure(G2frame,data)       
1486       
1487    def SetViewPoint(event):
1488        indx = drawAtoms.GetSelectedRows()
1489        if indx:
1490            atomData = data['Drawing']['Atoms']
1491            cx = data['Drawing']['atomPtrs'][0]
1492            data['Drawing']['viewPoint'] = [atomData[indx[0]][cx:cx+3],[indx[0],0]]
1493            drawAtoms.ClearSelection()                                  #do I really want to do this?
1494            G2plt.PlotStructure(G2frame,data)
1495           
1496    def noDuplicate(xyz,atomData):                  #be careful where this is used - it's slow
1497        cx = data['Drawing']['atomPtrs'][0]
1498        if True in [np.allclose(np.array(xyz),np.array(atom[cx:cx+3]),atol=0.0002) for atom in atomData]:
1499            return False
1500        else:
1501            return True
1502               
1503    def AddSymEquiv(event):
1504        indx = drawAtoms.GetSelectedRows()
1505        indx.sort()
1506        if indx:
1507            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1508            cx = colLabels.index('x')
1509            cuia = colLabels.index('I/A')
1510            cuij = cuia+2
1511            atomData = data['Drawing']['Atoms']
1512            generalData = data['General']
1513            SGData = generalData['SGData']
1514            dlg = SymOpDialog(G2frame,SGData,False)
1515            try:
1516                if dlg.ShowModal() == wx.ID_OK:
1517                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1518                    Cell = np.array(Cell)
1519                    cent = SGData['SGCen'][Cent]
1520                    M,T = SGData['SGOps'][Opr]
1521                    for ind in indx:
1522                        XYZ = np.array(atomData[ind][cx:cx+3])
1523                        XYZ = np.inner(M,XYZ)+T
1524                        if Inv:
1525                            XYZ = -XYZ
1526                        XYZ = XYZ+cent+Cell
1527                        if noDuplicate(XYZ,atomData):
1528                            atom = copy.copy(atomData[ind])
1529                            atom[cx:cx+3] = XYZ
1530                            atomOp = atom[cx+3]
1531                            newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1532                                str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))                           
1533                            atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1534                            if atom[cuia] == 'A':
1535                                Uij = atom[cuij:cuij+6]
1536                                U = G2spc.Uij2U(Uij)
1537                                U = np.inner(np.inner(M,U),M)
1538                                Uij = G2spc.U2Uij(U)
1539                                atom[cuij:cuij+6] = Uij
1540                            atomData.append(atom)
1541            finally:
1542                dlg.Destroy()
1543            UpdateDrawAtoms()
1544            drawAtoms.ClearSelection()
1545            G2plt.PlotStructure(G2frame,data)
1546           
1547    def TransformSymEquiv(event):
1548        indx = drawAtoms.GetSelectedRows()
1549        indx.sort()
1550        if indx:
1551            atomData = data['Drawing']['Atoms']
1552            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1553            cx = colLabels.index('x')
1554            cuia = colLabels.index('I/A')
1555            cuij = cuia+2
1556            atomData = data['Drawing']['Atoms']
1557            generalData = data['General']
1558            SGData = generalData['SGData']
1559            dlg = SymOpDialog(G2frame,SGData,False)
1560            try:
1561                if dlg.ShowModal() == wx.ID_OK:
1562                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1563                    Cell = np.array(Cell)
1564                    cent = SGData['SGCen'][Cent]
1565                    M,T = SGData['SGOps'][Opr]
1566                    for ind in indx:
1567                        XYZ = np.array(atomData[ind][cx:cx+3])
1568                        XYZ = np.inner(M,XYZ)+T
1569                        if Inv:
1570                            XYZ = -XYZ
1571                        XYZ = XYZ+cent+Cell
1572                        atom = atomData[ind]
1573                        atom[cx:cx+3] = XYZ
1574                        atomOp = atom[cx+3]
1575                        newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1576                            str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))
1577                        atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1578                        if atom[cuia] == 'A':
1579                            Uij = atom[cuij:cuij+6]
1580                            U = G2spc.Uij2U(Uij)
1581                            U = np.inner(np.inner(M,U),M)
1582                            Uij = G2spc.U2Uij(U)
1583                            atom[cuij:cuij+6] = Uij
1584                    data['Drawing']['Atoms'] = atomData
1585            finally:
1586                dlg.Destroy()
1587            UpdateDrawAtoms()
1588            drawAtoms.ClearSelection()
1589            G2plt.PlotStructure(G2frame,data)
1590           
1591    def FillCoordSphere(event):
1592        generalData = data['General']
1593        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1594        radii = generalData['BondRadii']
1595        atomTypes = generalData['AtomTypes']
1596        try:
1597            indH = atomTypes.index('H')
1598            radii[indH] = 0.5
1599        except:
1600            pass           
1601        indx = drawAtoms.GetSelectedRows()
1602        if indx:
1603            indx.sort()
1604            atomData = data['Drawing']['Atoms']
1605            numAtoms = len(atomData)
1606            cx,ct,cs = data['Drawing']['atomPtrs']
1607            generalData = data['General']
1608            SGData = generalData['SGData']
1609            cellArray = G2lat.CellBlock(1)
1610            for ind in indx:
1611                atomA = atomData[ind]
1612                xyzA = np.array(atomA[cx:cx+3])
1613                indA = atomTypes.index(atomA[ct])
1614                for atomB in atomData[:numAtoms]:
1615                    indB = atomTypes.index(atomB[ct])
1616                    sumR = radii[indA]+radii[indB]
1617                    xyzB = np.array(atomB[cx:cx+3])
1618                    for xyz in cellArray+xyzB:
1619                        dist = np.sqrt(np.sum(np.inner(Amat,xyz-xyzA)**2))
1620                        if 0 < dist <= data['Drawing']['radiusFactor']*sumR:
1621                            if noDuplicate(xyz,atomData):
1622                                oprB = atomB[cx+3]
1623                                C = xyz-xyzB
1624                                newOp = '1+'+str(int(round(C[0])))+','+str(int(round(C[1])))+','+str(int(round(C[2])))
1625                                newAtom = atomB[:]
1626                                newAtom[cx:cx+3] = xyz
1627                                newAtom[cx+3] = G2spc.StringOpsProd(oprB,newOp,SGData)
1628                                atomData.append(newAtom)
1629            data['Drawing']['Atoms'] = atomData
1630            UpdateDrawAtoms()
1631            drawAtoms.ClearSelection()
1632            G2plt.PlotStructure(G2frame,data)
1633           
1634    def FillUnitCell(event):
1635        indx = drawAtoms.GetSelectedRows()
1636        indx.sort()
1637        if indx:
1638            atomData = data['Drawing']['Atoms']
1639            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1640            cx = colLabels.index('x')
1641            cuia = colLabels.index('I/A')
1642            cuij = cuia+2
1643            generalData = data['General']
1644            SGData = generalData['SGData']
1645            for ind in indx:
1646                atom = atomData[ind]
1647                XYZ = np.array(atom[cx:cx+3])
1648                if atom[cuia] == 'A':
1649                    Uij = atom[cuij:cuij+6]
1650                    result = G2spc.GenAtom(XYZ,SGData,False,Uij,False)
1651                    for item in result:
1652                        atom = copy.copy(atomData[ind])
1653                        atom[cx:cx+3] = item[0]
1654                        atom[cx+3] = str(item[2])+'+' \
1655                            +str(item[3][0])+','+str(item[3][1])+','+str(item[3][2])
1656                        atom[cuij:cuij+6] = item[1]
1657                        Opp = G2spc.Opposite(item[0])
1658                        for xyz in Opp:
1659                            if noDuplicate(xyz,atomData):
1660                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
1661                                cell = '1'+'+'+ \
1662                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
1663                                atom[cx:cx+3] = xyz
1664                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
1665                                atomData.append(atom[:])
1666                else:
1667                    result = G2spc.GenAtom(XYZ,SGData,False,Move=False)
1668                    for item in result:
1669                        atom = copy.copy(atomData[ind])
1670                        atom[cx:cx+3] = item[0]
1671                        atom[cx+3] = str(item[1])+'+' \
1672                            +str(item[2][0])+','+str(item[2][1])+','+str(item[2][2])
1673                        Opp = G2spc.Opposite(item[0])
1674                        for xyz in Opp:
1675                            if noDuplicate(xyz,atomData):
1676                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
1677                                cell = '1'+'+'+ \
1678                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
1679                                atom[cx:cx+3] = xyz
1680                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
1681                                atomData.append(atom[:])               
1682                data['Drawing']['Atoms'] = atomData
1683            UpdateDrawAtoms()
1684            drawAtoms.ClearSelection()
1685            G2plt.PlotStructure(G2frame,data)
1686           
1687    def FindBondsToo():                         #works but slow for large structures - keep as reference
1688        cx,ct,cs = data['Drawing']['atomPtrs']
1689        atomData = data['Drawing']['Atoms']
1690        generalData = data['General']
1691        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1692        radii = generalData['BondRadii']
1693        atomTypes = generalData['AtomTypes']
1694        try:
1695            indH = atomTypes.index('H')
1696            radii[indH] = 0.5
1697        except:
1698            pass           
1699        for atom in atomData:
1700            atom[-1] = []
1701        Atoms = []
1702        for i,atom in enumerate(atomData):
1703            Atoms.append([i,np.array(atom[cx:cx+3]),atom[cs],radii[atomTypes.index(atom[ct])]])
1704        for atomA in Atoms:
1705            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
1706                for atomB in Atoms:                   
1707                    Dx = atomB[1]-atomA[1]
1708                    DX = np.inner(Amat,Dx)
1709                    dist = np.sqrt(np.sum(DX**2))
1710                    sumR = atomA[3]+atomB[3]
1711                    if 0.5 < dist <= 0.85*sumR:
1712                        i = atomA[0]
1713                        if atomA[2] == 'polyhedra':
1714                            atomData[i][-1].append(DX)
1715                        elif atomB[1] != 'polyhedra':
1716                            j = atomB[0]
1717                            atomData[i][-1].append(Dx*atomA[3]/sumR)
1718                            atomData[j][-1].append(-Dx*atomB[3]/sumR)
1719                   
1720    def FindBondsDraw():                    #uses numpy & masks - very fast even for proteins!
1721        import numpy.ma as ma
1722        cx,ct,cs = data['Drawing']['atomPtrs']
1723        hydro = data['Drawing']['showHydrogen']
1724        atomData = data['Drawing']['Atoms']
1725        generalData = data['General']
1726        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1727        radii = generalData['BondRadii']
1728        atomTypes = generalData['AtomTypes']
1729        try:
1730            indH = atomTypes.index('H')
1731            radii[indH] = 0.5
1732        except:
1733            pass           
1734        for atom in atomData:
1735            atom[-2] = []               #clear out old bonds/polyhedra
1736            atom[-1] = []
1737        Indx = range(len(atomData))
1738        Atoms = []
1739        Styles = []
1740        Radii = []
1741        for atom in atomData:
1742            Atoms.append(np.array(atom[cx:cx+3]))
1743            Styles.append(atom[cs])
1744            try:
1745                if not hydro and atom[ct] == 'H':
1746                    Radii.append(0.0)
1747                else:
1748                    Radii.append(radii[atomTypes.index(atom[ct])])
1749            except ValueError:          #changed atom type!
1750                Radii.append(0.20)
1751        Atoms = np.array(Atoms)
1752        Radii = np.array(Radii)
1753        IASR = zip(Indx,Atoms,Styles,Radii)
1754        for atomA in IASR:
1755            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
1756                Dx = Atoms-atomA[1]
1757                dist = ma.masked_less(np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)),0.5) #gets rid of G2frame & disorder "bonds" < 0.5A
1758                sumR = atomA[3]+Radii
1759                IndB = ma.nonzero(ma.masked_greater(dist-data['Drawing']['radiusFactor']*sumR,0.))                 #get indices of bonded atoms
1760                i = atomA[0]
1761                for j in IndB[0]:
1762                    if Styles[i] == 'polyhedra':
1763                        atomData[i][-2].append(np.inner(Amat,Dx[j]))
1764                    elif Styles[j] != 'polyhedra' and j > i:
1765                        atomData[i][-2].append(Dx[j]*Radii[i]/sumR[j])
1766                        atomData[j][-2].append(-Dx[j]*Radii[j]/sumR[j])
1767                if Styles[i] == 'polyhedra':
1768                    Bonds = atomData[i][-2]
1769                    Faces = []
1770                    if len(Bonds) > 2:
1771                        FaceGen = G2lat.uniqueCombinations(Bonds,3)     #N.B. this is a generator
1772                        for face in FaceGen:
1773                            vol = nl.det(face)
1774                            if abs(vol) > 1. or len(Bonds) == 3:
1775                                if vol < 0.:
1776                                    face = [face[0],face[2],face[1]]
1777                                face = np.array(face)
1778                                if not np.array([np.array(nl.det(face-bond))+0.0001 < 0 for bond in Bonds]).any():
1779                                    norm = np.cross(face[1]-face[0],face[2]-face[0])
1780                                    norm /= np.sqrt(np.sum(norm**2))
1781                                    Faces.append([face,norm])
1782                        atomData[i][-1] = Faces
1783                       
1784    def DrawAtomsDelete(event):   
1785        indx = drawAtoms.GetSelectedRows()
1786        indx.sort()
1787        if indx:
1788            atomData = data['Drawing']['Atoms']
1789            indx.reverse()
1790            for ind in indx:
1791                del atomData[ind]
1792            UpdateDrawAtoms()
1793            drawAtoms.ClearSelection()
1794            G2plt.PlotStructure(G2frame,data)
1795        event.StopPropagation()
1796       
1797    def OnReloadDrawAtoms(event):
1798        data['Drawing']['Atoms'] = []
1799        UpdateDrawAtoms()
1800        drawAtoms.ClearSelection()
1801        G2plt.PlotStructure(G2frame,data)
1802        event.StopPropagation()
1803       
1804    def FindAtomIndexByIDs(atomData,IDs,Draw=True):
1805        indx = []
1806        for i,atom in enumerate(atomData):
1807            if Draw and atom[-3] in IDs:
1808                indx.append(i)
1809            elif atom[-1] in IDs:
1810                indx.append(i)
1811        return indx
1812       
1813    def DrawAtomsDeleteByIDs(IDs):
1814        atomData = data['Drawing']['Atoms']
1815        indx = FindAtomIndexByIDs(atomData,IDs)
1816        indx.reverse()
1817        for ind in indx:
1818            del atomData[ind]
1819           
1820    def ChangeDrawAtomsByIDs(colName,IDs,value):
1821        atomData = data['Drawing']['Atoms']
1822        cx,ct,cs = data['Drawing']['atomPtrs']
1823        if colName == 'Name':
1824            col = ct-1
1825        elif colName == 'Type':
1826            col = ct
1827        elif colName == 'I/A':
1828            col = cs
1829        indx = FindAtomIndexByIDs(atomData,IDs)
1830        for ind in indx:
1831            atomData[ind][col] = value
1832               
1833    def OnDrawTorsion(event):
1834        indx = drawAtoms.GetSelectedRows()
1835        if len(indx) != 4:
1836            print '**** ERROR - need 4 atoms for torsion calculation'
1837            return
1838        TorsionData = {}
1839        ocx,oct,ocs,cia = data['General']['AtomPtrs']
1840        drawingData = data['Drawing']
1841        atomData = data['Atoms']
1842#        for atom in atomData: print atom
1843        atomDData = drawingData['Atoms']
1844#        for atom in atomDData: print atom
1845        colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1846        cx = colLabels.index('x')
1847        cn = colLabels.index('Name')
1848        cid = colLabels.index('I/A')+8
1849        xyz = []
1850        Oxyz = []
1851        for i,atom in enumerate(atomDData):
1852            if i in indx:
1853                xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+4]) #also gets Sym Op
1854                id = FindAtomIndexByIDs(atomData,[atom[cid],],False)[0]
1855                Oxyz.append([id,]+atomData[id][cx+1:cx+4])
1856        TorsionData['Datoms'] = xyz
1857        TorsionData['Oatoms'] = Oxyz
1858        generalData = data['General']
1859        TorsionData['Name'] = generalData['Name']
1860        TorsionData['SGData'] = generalData['SGData']
1861        TorsionData['Cell'] = generalData['Cell'][1:] #+ volume
1862        if 'pId' in data:
1863            TorsionData['pId'] = data['pId']
1864            TorsionData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance'))
1865        G2str.Torsion(TorsionData)
1866       
1867    def OnDrawPlane(event):
1868        indx = drawAtoms.GetSelectedRows()
1869        if len(indx) < 3:
1870            print '**** ERROR - need 3+ atoms for plane calculation'
1871            return
1872        PlaneData = {}
1873        drawingData = data['Drawing']
1874        atomData = drawingData['Atoms']
1875        colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1876        cx = colLabels.index('x')
1877        cn = colLabels.index('Name')
1878        xyz = []
1879        for i,atom in enumerate(atomData):
1880            if i in indx:
1881                xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1882        generalData = data['General']
1883        PlaneData['Name'] = generalData['Name']
1884        PlaneData['Atoms'] = xyz
1885        PlaneData['Cell'] = generalData['Cell'][1:] #+ volume
1886        G2str.BestPlane(PlaneData)
1887   
1888    def OnDrawDistAngle(event):
1889        indx = drawAtoms.GetSelectedRows()
1890        print 'Future bond dist/angles for atoms',indx
1891               
1892    def UpdateDrawOptions():
1893        import copy
1894        import wx.lib.colourselect as wcs
1895        generalData = data['General']
1896        SetupDrawingData()
1897        drawingData = data['Drawing']
1898        print 'Rotation:',drawingData['Rotation']
1899        if generalData['Type'] == 'nuclear':
1900            pickChoice = ['Atoms','Bonds','Torsions','Planes']
1901        elif generalData['Type'] == 'macromolecular':
1902            pickChoice = ['Atoms','Residues','Chains','Bonds','Torsions','Planes','phi/psi']
1903
1904        def OnZclip(event):
1905            drawingData['Zclip'] = Zclip.GetValue()
1906            ZclipTxt.SetLabel('Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1907            G2plt.PlotStructure(G2frame,data)
1908           
1909        def OnCameraPos(event):
1910            drawingData['cameraPos'] = cameraPos.GetValue()
1911            cameraPosTxt.SetLabel('Camera Distance: '+'%.2f'%(drawingData['cameraPos']))
1912            ZclipTxt.SetLabel('Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1913            G2plt.PlotStructure(G2frame,data)
1914
1915        def OnBackColor(event):
1916            drawingData['backColor'] = event.GetValue()
1917            G2plt.PlotStructure(G2frame,data)
1918
1919        def OnBallScale(event):
1920            drawingData['ballScale'] = ballScale.GetValue()/100.
1921            ballScaleTxt.SetLabel('Ball scale: '+'%.2f'%(drawingData['ballScale']))
1922            G2plt.PlotStructure(G2frame,data)
1923
1924        def OnVdWScale(event):
1925            drawingData['vdwScale'] = vdwScale.GetValue()/100.
1926            vdwScaleTxt.SetLabel('van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
1927            G2plt.PlotStructure(G2frame,data)
1928
1929        def OnEllipseProb(event):
1930            drawingData['ellipseProb'] = ellipseProb.GetValue()
1931            ellipseProbTxt.SetLabel('Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
1932            G2plt.PlotStructure(G2frame,data)
1933
1934        def OnBondRadius(event):
1935            drawingData['bondRadius'] = bondRadius.GetValue()/100.
1936            bondRadiusTxt.SetLabel('Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
1937            G2plt.PlotStructure(G2frame,data)
1938
1939        def OnShowABC(event):
1940            drawingData['showABC'] = showABC.GetValue()
1941            G2plt.PlotStructure(G2frame,data)
1942
1943        def OnShowUnitCell(event):
1944            drawingData['unitCellBox'] = unitCellBox.GetValue()
1945            G2plt.PlotStructure(G2frame,data)
1946
1947        def OnShowHyd(event):
1948            drawingData['showHydrogen'] = showHydrogen.GetValue()
1949            FindBondsDraw()
1950            G2plt.PlotStructure(G2frame,data)
1951
1952        def OnSizeHatoms(event):
1953            try:
1954                value = max(0.1,min(1.2,float(sizeH.GetValue())))
1955            except ValueError:
1956                value = 0.5
1957            drawingData['sizeH'] = value
1958            sizeH.SetValue("%.2f"%(value))
1959            G2plt.PlotStructure(G2frame,data)
1960           
1961        def OnRadFactor(event):
1962            try:
1963                value = max(0.1,min(1.2,float(radFactor.GetValue())))
1964            except ValueError:
1965                value = 0.85
1966            drawingData['radiusFactor'] = value
1967            radFactor.SetValue("%.2f"%(value))
1968            FindBondsDraw()
1969            G2plt.PlotStructure(G2frame,data)
1970
1971        dataDisplay = wx.Panel(drawOptions)
1972        mainSizer = wx.BoxSizer(wx.VERTICAL)
1973        mainSizer.Add((5,5),0)
1974        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Drawing controls:'),0,wx.ALIGN_CENTER_VERTICAL)
1975        mainSizer.Add((5,5),0)
1976       
1977        slopSizer = wx.BoxSizer(wx.HORIZONTAL)
1978        slideSizer = wx.FlexGridSizer(6,2)
1979        slideSizer.AddGrowableCol(1,1)
1980
1981        cameraPosTxt = wx.StaticText(dataDisplay,-1,
1982            'Camera Distance: '+'%.2f'%(drawingData['cameraPos']),name='cameraPos')
1983        slideSizer.Add(cameraPosTxt,0,wx.ALIGN_CENTER_VERTICAL)
1984        cameraPos = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['cameraPos'],name='cameraSlider')
1985        cameraPos.SetRange(10,500)
1986        cameraPos.Bind(wx.EVT_SLIDER, OnCameraPos)
1987        slideSizer.Add(cameraPos,1,wx.EXPAND|wx.RIGHT)
1988       
1989        ZclipTxt = wx.StaticText(dataDisplay,-1,'Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1990        slideSizer.Add(ZclipTxt,0,wx.ALIGN_CENTER_VERTICAL)
1991        Zclip = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['Zclip'])
1992        Zclip.SetRange(1,99)
1993        Zclip.Bind(wx.EVT_SLIDER, OnZclip)
1994        slideSizer.Add(Zclip,1,wx.EXPAND|wx.RIGHT)
1995       
1996        vdwScaleTxt = wx.StaticText(dataDisplay,-1,'van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
1997        slideSizer.Add(vdwScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
1998        vdwScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['vdwScale']))
1999        vdwScale.Bind(wx.EVT_SLIDER, OnVdWScale)
2000        slideSizer.Add(vdwScale,1,wx.EXPAND|wx.RIGHT)
2001
2002        ellipseProbTxt = wx.StaticText(dataDisplay,-1,'Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
2003        slideSizer.Add(ellipseProbTxt,0,wx.ALIGN_CENTER_VERTICAL)
2004        ellipseProb = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['ellipseProb'])
2005        ellipseProb.SetRange(1,99)
2006        ellipseProb.Bind(wx.EVT_SLIDER, OnEllipseProb)
2007        slideSizer.Add(ellipseProb,1,wx.EXPAND|wx.RIGHT)
2008
2009        ballScaleTxt = wx.StaticText(dataDisplay,-1,'Ball scale: '+'%.2f'%(drawingData['ballScale']))
2010        slideSizer.Add(ballScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
2011        ballScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['ballScale']))
2012        ballScale.Bind(wx.EVT_SLIDER, OnBallScale)
2013        slideSizer.Add(ballScale,1,wx.EXPAND|wx.RIGHT)
2014
2015        bondRadiusTxt = wx.StaticText(dataDisplay,-1,'Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
2016        slideSizer.Add(bondRadiusTxt,0,wx.ALIGN_CENTER_VERTICAL)
2017        bondRadius = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['bondRadius']))
2018        bondRadius.SetRange(1,25)
2019        bondRadius.Bind(wx.EVT_SLIDER, OnBondRadius)
2020        slideSizer.Add(bondRadius,1,wx.EXPAND|wx.RIGHT)
2021       
2022        slopSizer.Add(slideSizer,1,wx.EXPAND|wx.RIGHT)
2023        slopSizer.Add((10,5),0)
2024        slopSizer.SetMinSize(wx.Size(300,10))
2025        mainSizer.Add(slopSizer,0)
2026        mainSizer.Add((5,5),0)
2027
2028        flexSizer = wx.FlexGridSizer(5,2,5,0)
2029        flexSizer.Add(wx.StaticText(dataDisplay,-1,'View Point:  '),0,wx.ALIGN_CENTER_VERTICAL)
2030        VP = drawingData['viewPoint'][0]
2031        viewPoint = wx.TextCtrl(dataDisplay,value='%.3f, %.3f, %.3f'%(VP[0],VP[1],VP[2]),
2032            style=wx.TE_READONLY,size=wx.Size(120,20),name='viewPoint')
2033        viewPoint.SetBackgroundColour(VERY_LIGHT_GREY)
2034        flexSizer.Add(viewPoint,0,wx.ALIGN_CENTER_VERTICAL)
2035       
2036        showABC = wx.CheckBox(dataDisplay,-1,label='Show test point?')
2037        showABC.Bind(wx.EVT_CHECKBOX, OnShowABC)
2038        showABC.SetValue(drawingData['showABC'])
2039        flexSizer.Add(showABC,0,wx.ALIGN_CENTER_VERTICAL)
2040
2041        unitCellBox = wx.CheckBox(dataDisplay,-1,label='Show unit cell?')
2042        unitCellBox.Bind(wx.EVT_CHECKBOX, OnShowUnitCell)
2043        unitCellBox.SetValue(drawingData['unitCellBox'])
2044        flexSizer.Add(unitCellBox,0,wx.ALIGN_CENTER_VERTICAL)
2045
2046        showHydrogen = wx.CheckBox(dataDisplay,-1,label='Show hydrogens?')
2047        showHydrogen.Bind(wx.EVT_CHECKBOX, OnShowHyd)
2048        showHydrogen.SetValue(drawingData['showHydrogen'])
2049        flexSizer.Add(showHydrogen,0,wx.ALIGN_CENTER_VERTICAL)
2050
2051        lineSizer = wx.BoxSizer(wx.HORIZONTAL)
2052        lineSizer.Add(wx.StaticText(dataDisplay,-1,'Background color:'),0,wx.ALIGN_CENTER_VERTICAL)
2053        backColor = wcs.ColourSelect(dataDisplay, -1,colour=drawingData['backColor'],size=wx.Size(25,25))
2054        backColor.Bind(wcs.EVT_COLOURSELECT, OnBackColor)
2055        lineSizer.Add(backColor,0,wx.ALIGN_CENTER_VERTICAL)
2056        flexSizer.Add(lineSizer,0,)
2057
2058        flexSizer.Add(wx.StaticText(dataDisplay,-1,'Hydrogen radius, A:  '),0,wx.ALIGN_CENTER_VERTICAL)
2059        sizeH = wx.TextCtrl(dataDisplay,-1,value='%.2f'%(drawingData['sizeH']),style=wx.TE_PROCESS_ENTER)
2060        sizeH.Bind(wx.EVT_TEXT_ENTER,OnSizeHatoms)
2061        sizeH.Bind(wx.EVT_KILL_FOCUS,OnSizeHatoms)
2062        flexSizer.Add(sizeH,0,wx.ALIGN_CENTER_VERTICAL)
2063
2064        flexSizer.Add(wx.StaticText(dataDisplay,-1,'Bond search factor:  '),0,wx.ALIGN_CENTER_VERTICAL)
2065        radFactor = wx.TextCtrl(dataDisplay,value='%.2f'%(drawingData['radiusFactor']),style=wx.TE_PROCESS_ENTER)
2066        radFactor.Bind(wx.EVT_TEXT_ENTER,OnRadFactor)
2067        radFactor.Bind(wx.EVT_KILL_FOCUS,OnRadFactor)
2068        flexSizer.Add(radFactor,0,wx.ALIGN_CENTER_VERTICAL)
2069        mainSizer.Add(flexSizer,0,)
2070
2071        dataDisplay.SetSizer(mainSizer)
2072        Size = mainSizer.Fit(G2frame.dataFrame)
2073        Size[1] += 26                           #compensate for status bar
2074        dataDisplay.SetSize(Size)
2075        G2frame.dataFrame.setSizePosLeft(Size)
2076       
2077    def UpdateTexture():
2078        generalData = data['General']       
2079        SGData = generalData['SGData']
2080        try:
2081            textureData = generalData['SH Texture']
2082        except KeyError:            #fix old files!
2083            textureData = generalData['SH Texture'] = {'Order':0,'Model':'cylindrical',
2084                'Sample omega':[False,0.0],'Sample chi':[False,0.0],'Sample phi':[False,0.0],
2085                'SH Coeff':[False,{}],'SHShow':False,'PFhkl':[0,0,1],
2086                'PFxyz':[0,0,1.],'PlotType':'Pole figure'}
2087        if 'SHShow' not in textureData:     #another fix
2088            textureData.update({'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
2089        try:                        #another fix!
2090            x = textureData['PlotType']
2091        except KeyError:
2092            textureData.update({'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
2093        shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
2094        SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
2095        if generalData['Type'] == 'Pawley' and G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequental results'):
2096            G2frame.dataFrame.RefineTexture.Enable(True)
2097        shAngles = ['omega','chi','phi']
2098       
2099        def SetSHCoef():
2100            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],SamSym[textureData['Model']],textureData['Order'])
2101            newSHCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
2102            SHCoeff = textureData['SH Coeff'][1]
2103            for cofName in SHCoeff:
2104                if cofName in  cofNames:
2105                    newSHCoef[cofName] = SHCoeff[cofName]
2106            return newSHCoef
2107       
2108        def OnShOrder(event):
2109            Obj = event.GetEventObject()
2110            textureData['Order'] = int(Obj.GetValue())
2111            textureData['SH Coeff'][1] = SetSHCoef()
2112            wx.CallAfter(UpdateTexture)
2113            G2plt.PlotTexture(G2frame,data,newPlot=False)
2114                       
2115        def OnShModel(event):
2116            Obj = event.GetEventObject()
2117            textureData['Model'] = Obj.GetValue()
2118            textureData['SH Coeff'][1] = SetSHCoef()
2119            wx.CallAfter(UpdateTexture)
2120            G2plt.PlotTexture(G2frame,data,newPlot=False)
2121           
2122        def OnSHRefine(event):
2123            Obj = event.GetEventObject()
2124            textureData['SH Coeff'][0] = Obj.GetValue()
2125           
2126        def OnSHShow(event):
2127            Obj = event.GetEventObject()
2128            textureData['SHShow'] = Obj.GetValue()
2129            wx.CallAfter(UpdateTexture)
2130           
2131        def OnProjSel(event):
2132            Obj = event.GetEventObject()
2133            G2frame.Projection = Obj.GetValue()
2134            G2plt.PlotTexture(G2frame,data,newPlot=False)
2135           
2136        def OnColorSel(event):
2137            Obj = event.GetEventObject()
2138            G2frame.ContourColor = Obj.GetValue()
2139            G2plt.PlotTexture(G2frame,data,newPlot=False)
2140           
2141        def OnAngRef(event):
2142            Obj = event.GetEventObject()
2143            textureData[angIndx[Obj.GetId()]][0] = Obj.GetValue()
2144           
2145        def OnAngValue(event):
2146            Obj = event.GetEventObject()
2147            try:
2148                value =  float(Obj.GetValue())
2149            except ValueError:
2150                value = textureData[valIndx[Obj.GetId()]][1]
2151            Obj.SetValue('%8.2f'%(value))
2152            textureData[valIndx[Obj.GetId()]][1] = value
2153           
2154        def OnODFValue(event): 
2155            Obj = event.GetEventObject()
2156            try:
2157                value =  float(Obj.GetValue())
2158            except ValueError:
2159                value = textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]]
2160            Obj.SetValue('%8.3f'%(value))
2161            textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] = value
2162            G2plt.PlotTexture(G2frame,data,newPlot=False)
2163           
2164        def OnPfType(event):
2165            Obj = event.GetEventObject()
2166            textureData['PlotType'] = Obj.GetValue()
2167            wx.CallAfter(UpdateTexture)
2168            G2plt.PlotTexture(G2frame,data)
2169           
2170        def OnPFValue(event):
2171            Obj = event.GetEventObject()
2172            Saxis = Obj.GetValue().split()
2173            if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:               
2174                try:
2175                    hkl = [int(Saxis[i]) for i in range(3)]
2176                except (ValueError,IndexError):
2177                    hkl = textureData['PFhkl']
2178                if not np.any(np.array(hkl)):       #can't be all zeros!
2179                    hkl = textureData['PFhkl']
2180                Obj.SetValue('%d %d %d'%(hkl[0],hkl[1],hkl[2]))
2181                textureData['PFhkl'] = hkl
2182            else:
2183                try:
2184                    xyz = [float(Saxis[i]) for i in range(3)]
2185                except (ValueError,IndexError):
2186                    xyz = textureData['PFxyz']
2187                if not np.any(np.array(xyz)):       #can't be all zeros!
2188                    xyz = textureData['PFxyz']
2189                Obj.SetValue('%3.1f %3.1f %3.1f'%(xyz[0],xyz[1],xyz[2]))
2190                textureData['PFxyz'] = xyz
2191            G2plt.PlotTexture(G2frame,data)
2192
2193        if Texture.GetSizer():
2194            Texture.GetSizer().Clear(True)
2195        mainSizer = wx.BoxSizer(wx.VERTICAL)
2196        titleSizer = wx.BoxSizer(wx.HORIZONTAL)
2197        titleSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2198        titleSizer.Add(wx.StaticText(Texture,-1,
2199            ' Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))),
2200            0,wx.ALIGN_CENTER_VERTICAL)
2201        mainSizer.Add(titleSizer,0)
2202        mainSizer.Add((0,5),0)
2203        shSizer = wx.FlexGridSizer(1,6,5,5)
2204        shSizer.Add(wx.StaticText(Texture,-1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL)
2205        shModel = wx.ComboBox(Texture,-1,value=textureData['Model'],choices=shModels,
2206            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2207        shModel.Bind(wx.EVT_COMBOBOX,OnShModel)
2208        shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL)
2209        shSizer.Add(wx.StaticText(Texture,-1,'  Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2210        shOrder = wx.ComboBox(Texture,-1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)],
2211            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2212        shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder)
2213        shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL)
2214        shRef = wx.CheckBox(Texture,-1,label=' Refine texture?')
2215        shRef.SetValue(textureData['SH Coeff'][0])
2216        shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine)
2217        shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL)
2218        shShow = wx.CheckBox(Texture,-1,label=' Show coeff.?')
2219        shShow.SetValue(textureData['SHShow'])
2220        shShow.Bind(wx.EVT_CHECKBOX, OnSHShow)
2221        shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL)
2222        mainSizer.Add(shSizer,0,0)
2223        mainSizer.Add((0,5),0)
2224        PTSizer = wx.FlexGridSizer(2,4,5,5)
2225        PTSizer.Add(wx.StaticText(Texture,-1,' Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL)
2226        choices = ['Axial pole distribution','Pole figure','Inverse pole figure']           
2227        pfType = wx.ComboBox(Texture,-1,value=str(textureData['PlotType']),choices=choices,
2228            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2229        pfType.Bind(wx.EVT_COMBOBOX,OnPfType)
2230        PTSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL)
2231        if 'Axial' not in textureData['PlotType']:
2232            PTSizer.Add(wx.StaticText(Texture,-1,' Projection type: '),0,wx.ALIGN_CENTER_VERTICAL)
2233            projSel = wx.ComboBox(Texture,-1,value=G2frame.Projection,choices=['equal area','stereographic','3D display'],
2234                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2235            projSel.Bind(wx.EVT_COMBOBOX,OnProjSel)
2236            PTSizer.Add(projSel,0,wx.ALIGN_CENTER_VERTICAL)
2237        if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
2238            PTSizer.Add(wx.StaticText(Texture,-1,' Pole figure HKL: '),0,wx.ALIGN_CENTER_VERTICAL)
2239            PH = textureData['PFhkl']
2240            pfVal = wx.TextCtrl(Texture,-1,'%d %d %d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER)
2241        else:
2242            PTSizer.Add(wx.StaticText(Texture,-1,' Inverse pole figure XYZ: '),0,wx.ALIGN_CENTER_VERTICAL)
2243            PX = textureData['PFxyz']
2244            pfVal = wx.TextCtrl(Texture,-1,'%3.1f %3.1f %3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER)
2245        pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue)
2246        pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue)
2247        PTSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL)
2248        if 'Axial' not in textureData['PlotType']:
2249            PTSizer.Add(wx.StaticText(Texture,-1,' Color scheme'),0,wx.ALIGN_CENTER_VERTICAL)
2250            choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
2251            choice.sort()
2252            colorSel = wx.ComboBox(Texture,-1,value=G2frame.ContourColor,choices=choice,
2253                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2254            colorSel.Bind(wx.EVT_COMBOBOX,OnColorSel)
2255            PTSizer.Add(colorSel,0,wx.ALIGN_CENTER_VERTICAL)       
2256        mainSizer.Add(PTSizer,0,wx.ALIGN_CENTER_VERTICAL)
2257        mainSizer.Add((0,5),0)
2258        if textureData['SHShow']:
2259            mainSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2260            mainSizer.Add((0,5),0)
2261            ODFSizer = wx.FlexGridSizer(2,8,2,2)
2262            ODFIndx = {}
2263            ODFkeys = textureData['SH Coeff'][1].keys()
2264            ODFkeys.sort()
2265            for item in ODFkeys:
2266                ODFSizer.Add(wx.StaticText(Texture,-1,item),0,wx.ALIGN_CENTER_VERTICAL)
2267                ODFval = wx.TextCtrl(Texture,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER)
2268                ODFIndx[ODFval.GetId()] = item
2269                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2270                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2271                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2272            mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2273            mainSizer.Add((0,5),0)
2274        mainSizer.Add((0,5),0)
2275        mainSizer.Add(wx.StaticText(Texture,-1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL)
2276        mainSizer.Add((0,5),0)
2277        angSizer = wx.BoxSizer(wx.HORIZONTAL)
2278        angIndx = {}
2279        valIndx = {}
2280        for item in ['Sample omega','Sample chi','Sample phi']:
2281            angRef = wx.CheckBox(Texture,-1,label=item+': ')
2282            angRef.SetValue(textureData[item][0])
2283            angIndx[angRef.GetId()] = item
2284            angRef.Bind(wx.EVT_CHECKBOX, OnAngRef)
2285            angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL)
2286            angVal = wx.TextCtrl(Texture,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER)
2287            valIndx[angVal.GetId()] = item
2288            angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue)
2289            angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue)
2290            angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL)
2291            angSizer.Add((5,0),0)
2292        mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL)
2293        Texture.SetSizer(mainSizer,True)
2294        mainSizer.Fit(G2frame.dataFrame)
2295        Size = mainSizer.GetMinSize()
2296        Size[0] += 40
2297        Size[1] = max(Size[1],250) + 20
2298        Texture.SetSize(Size)
2299        Texture.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2300        Size[1] = min(Size[1],450)
2301        G2frame.dataFrame.setSizePosLeft(Size)
2302       
2303    def UpdateDData():
2304        UseList = data['Histograms']
2305        if UseList:
2306            G2frame.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,True)
2307            G2frame.Refine.Enable(True)
2308        else:
2309            G2frame.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,False)
2310            G2frame.Refine.Enable(False)           
2311        generalData = data['General']       
2312        SGData = generalData['SGData']
2313        keyList = UseList.keys()
2314        keyList.sort()
2315        Indx = {}
2316       
2317        def OnPlotSel(event):
2318            Obj = event.GetEventObject()
2319            generalData['Data plot type'] = Obj.GetStringSelection()
2320            wx.CallAfter(UpdateDData)
2321            G2plt.PlotSizeStrainPO(G2frame,data)
2322           
2323        def OnPOhkl(event):
2324            Obj = event.GetEventObject()
2325            Saxis = Obj.GetValue().split()
2326            try:
2327                hkl = [int(Saxis[i]) for i in range(3)]
2328            except (ValueError,IndexError):
2329                hkl = generalData['POhkl']
2330            if not np.any(np.array(hkl)):
2331                hkl = generalData['POhkl']
2332            generalData['POhkl'] = hkl
2333            h,k,l = hkl
2334            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2335            G2plt.PlotSizeStrainPO(G2frame,data)
2336       
2337        def OnShowData(event):
2338            Obj = event.GetEventObject()
2339            hist = Indx[Obj.GetId()]
2340            UseList[hist]['Show'] = Obj.GetValue()
2341            wx.CallAfter(UpdateDData)
2342            G2plt.PlotSizeStrainPO(G2frame,data)
2343           
2344        def OnCopyData(event):
2345            #how about HKLF data? This is only for PWDR data
2346            Obj = event.GetEventObject()
2347            hist = Indx[Obj.GetId()]
2348            sourceDict = UseList[hist]
2349            copyNames = ['Scale','Pref.Ori.','Size','Mustrain','HStrain','Extinction']
2350            copyDict = {}
2351            for name in copyNames: 
2352                copyDict[name] = copy.deepcopy(sourceDict[name])        #force copy
2353            keyList = ['All',]+UseList.keys()
2354            if UseList:
2355                copyList = []
2356                dlg = wx.MultiChoiceDialog(G2frame, 
2357                    'Copy parameters to which histograms?', 'Copy parameters', 
2358                    keyList, wx.CHOICEDLG_STYLE)
2359                try:
2360                    if dlg.ShowModal() == wx.ID_OK:
2361                        result = dlg.GetSelections()
2362                        for i in result: 
2363                            copyList.append(keyList[i])
2364                        if 'All' in copyList: 
2365                            copyList = keyList[1:]
2366                        for item in copyList:
2367                            UseList[item].update(copy.deepcopy(copyDict))
2368                        wx.CallAfter(UpdateDData)
2369                finally:
2370                    dlg.Destroy()
2371           
2372        def OnScaleRef(event):
2373            Obj = event.GetEventObject()
2374            UseList[Indx[Obj.GetId()]]['Scale'][1] = Obj.GetValue()
2375           
2376        def OnScaleVal(event):
2377            Obj = event.GetEventObject()
2378            try:
2379                scale = float(Obj.GetValue())
2380                if scale > 0:
2381                    UseList[Indx[Obj.GetId()]]['Scale'][0] = scale
2382            except ValueError:
2383                pass
2384            Obj.SetValue("%.4f"%(UseList[Indx[Obj.GetId()]]['Scale'][0]))          #reset in case of error
2385           
2386        def OnSizeType(event):
2387            Obj = event.GetEventObject()
2388            hist = Indx[Obj.GetId()]
2389            UseList[hist]['Size'][0] = Obj.GetValue()
2390            G2plt.PlotSizeStrainPO(G2frame,data)
2391            wx.CallAfter(UpdateDData)
2392           
2393        def OnSizeRef(event):
2394            Obj = event.GetEventObject()
2395            hist,pid = Indx[Obj.GetId()]
2396            if UseList[hist]['Size'][0] == 'ellipsoidal':
2397                UseList[hist]['Size'][5][pid] = Obj.GetValue()               
2398            else:
2399                UseList[hist]['Size'][2][pid] = Obj.GetValue()
2400           
2401        def OnSizeVal(event):
2402            Obj = event.GetEventObject()
2403            hist,pid = Indx[Obj.GetId()]
2404            if UseList[hist]['Size'][0] == 'ellipsoidal':
2405                try:
2406                    size = float(Obj.GetValue())
2407                    if pid < 3 and size <= 0.001:            #10A lower limit!
2408                        raise ValueError
2409                    UseList[hist]['Size'][4][pid] = size                   
2410                except ValueError:
2411                    pass
2412                Obj.SetValue("%.3f"%(UseList[hist]['Size'][4][pid]))          #reset in case of error
2413            else:
2414                try:
2415                    size = float(Obj.GetValue())
2416                    if size <= 0.001:            #10A lower limit!
2417                        raise ValueError
2418                    UseList[hist]['Size'][1][pid] = size
2419                except ValueError:
2420                    pass
2421                Obj.SetValue("%.3f"%(UseList[hist]['Size'][1][pid]))          #reset in case of error
2422            G2plt.PlotSizeStrainPO(G2frame,data)
2423           
2424        def OnSizeAxis(event):           
2425            Obj = event.GetEventObject()
2426            hist = Indx[Obj.GetId()]
2427            Saxis = Obj.GetValue().split()
2428            try:
2429                hkl = [int(Saxis[i]) for i in range(3)]
2430            except (ValueError,IndexError):
2431                hkl = UseList[hist]['Size'][3]
2432            if not np.any(np.array(hkl)):
2433                hkl = UseList[hist]['Size'][3]
2434            UseList[hist]['Size'][3] = hkl
2435            h,k,l = hkl
2436            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2437                       
2438        def OnStrainType(event):
2439            Obj = event.GetEventObject()
2440            hist = Indx[Obj.GetId()]
2441            UseList[hist]['Mustrain'][0] = Obj.GetValue()
2442            G2plt.PlotSizeStrainPO(G2frame,data)
2443            wx.CallAfter(UpdateDData)
2444           
2445        def OnStrainRef(event):
2446            Obj = event.GetEventObject()
2447            hist,pid = Indx[Obj.GetId()]
2448            if UseList[hist]['Mustrain'][0] == 'generalized':
2449                UseList[hist]['Mustrain'][5][pid] = Obj.GetValue()
2450            else:
2451                UseList[hist]['Mustrain'][2][pid] = Obj.GetValue()
2452           
2453        def OnStrainVal(event):
2454            Snames = G2spc.MustrainNames(SGData)
2455            Obj = event.GetEventObject()
2456            hist,pid = Indx[Obj.GetId()]
2457            try:
2458                strain = float(Obj.GetValue())
2459                if UseList[hist]['Mustrain'][0] == 'generalized':
2460                    if '4' in Snames[pid] and strain < 0:
2461                        raise ValueError
2462                    UseList[hist]['Mustrain'][4][pid] = strain
2463                else:
2464                    if strain <= 0:
2465                        raise ValueError
2466                    UseList[hist]['Mustrain'][1][pid] = strain
2467            except ValueError:
2468                pass
2469            if UseList[hist]['Mustrain'][0] == 'generalized':
2470                Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][4][pid]))          #reset in case of error
2471            else:
2472                Obj.SetValue("%.1f"%(UseList[hist]['Mustrain'][1][pid]))          #reset in case of error
2473            G2plt.PlotSizeStrainPO(G2frame,data)
2474           
2475        def OnStrainAxis(event):
2476            Obj = event.GetEventObject()
2477            hist = Indx[Obj.GetId()]
2478            Saxis = Obj.GetValue().split()
2479            try:
2480                hkl = [int(Saxis[i]) for i in range(3)]
2481            except (ValueError,IndexError):
2482                hkl = UseList[hist]['Mustrain'][3]
2483            if not np.any(np.array(hkl)):
2484                hkl = UseList[hist]['Mustrain'][3]
2485            UseList[hist]['Mustrain'][3] = hkl
2486            h,k,l = hkl
2487            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2488            G2plt.PlotSizeStrainPO(G2frame,data)
2489           
2490        def OnHstrainRef(event):
2491            Obj = event.GetEventObject()
2492            hist,pid = Indx[Obj.GetId()]
2493            UseList[hist]['HStrain'][1][pid] = Obj.GetValue()
2494           
2495        def OnHstrainVal(event):
2496            Snames = G2spc.HStrainNames(SGData)
2497            Obj = event.GetEventObject()
2498            hist,pid = Indx[Obj.GetId()]
2499            try:
2500                strain = float(Obj.GetValue())
2501                UseList[hist]['HStrain'][0][pid] = strain
2502            except ValueError:
2503                pass
2504            Obj.SetValue("%.5f"%(UseList[hist]['HStrain'][0][pid]))          #reset in case of error
2505
2506        def OnPOType(event):
2507            Obj = event.GetEventObject()
2508            hist = Indx[Obj.GetId()]
2509            if 'March' in Obj.GetValue():
2510                UseList[hist]['Pref.Ori.'][0] = 'MD'
2511            else:
2512                UseList[hist]['Pref.Ori.'][0] = 'SH'
2513            wx.CallAfter(UpdateDData)           
2514
2515        def OnPORef(event):
2516            Obj = event.GetEventObject()
2517            hist = Indx[Obj.GetId()]
2518            UseList[hist]['Pref.Ori.'][2] = Obj.GetValue()
2519           
2520        def OnPOVal(event):
2521            Obj = event.GetEventObject()
2522            hist = Indx[Obj.GetId()]
2523            try:
2524                mdVal = float(Obj.GetValue())
2525                if mdVal > 0:
2526                    UseList[hist]['Pref.Ori.'][1] = mdVal
2527            except ValueError:
2528                pass
2529            Obj.SetValue("%.3f"%(UseList[hist]['Pref.Ori.'][1]))          #reset in case of error
2530           
2531        def OnPOAxis(event):
2532            Obj = event.GetEventObject()
2533            hist = Indx[Obj.GetId()]
2534            Saxis = Obj.GetValue().split()
2535            try:
2536                hkl = [int(Saxis[i]) for i in range(3)]
2537            except (ValueError,IndexError):
2538                hkl = UseList[hist]['Pref.Ori.'][3]
2539            if not np.any(np.array(hkl)):
2540                hkl = UseList[hist]['Pref.Ori.'][3]
2541            UseList[hist]['Pref.Ori.'][3] = hkl
2542            h,k,l = hkl
2543            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2544           
2545        def OnPOOrder(event):
2546            Obj = event.GetEventObject()
2547            hist = Indx[Obj.GetId()]
2548            Order = int(Obj.GetValue())
2549            UseList[hist]['Pref.Ori.'][4] = Order
2550            UseList[hist]['Pref.Ori.'][5] = SetPOCoef(Order,hist)
2551            wx.CallAfter(UpdateDData)
2552
2553        def SetPOCoef(Order,hist):
2554            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',Order,False)     #cylindrical & no M
2555            newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
2556            POCoeff = UseList[hist]['Pref.Ori.'][5]
2557            for cofName in POCoeff:
2558                if cofName in  cofNames:
2559                    newPOCoef[cofName] = POCoeff[cofName]
2560            return newPOCoef
2561       
2562        def OnExtRef(event):
2563            Obj = event.GetEventObject()
2564            UseList[Indx[Obj.GetId()]]['Extinction'][1] = Obj.GetValue()
2565           
2566        def OnExtVal(event):
2567            Obj = event.GetEventObject()
2568            try:
2569                ext = float(Obj.GetValue())
2570                if ext >= 0:
2571                    UseList[Indx[Obj.GetId()]]['Extinction'][0] = ext
2572            except ValueError:
2573                pass
2574            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][0]))          #reset in case of error
2575           
2576        def checkAxis(axis):
2577            if not np.any(np.array(axis)):
2578                return False
2579            return axis
2580           
2581        def PlotSizer():
2582            plotSizer = wx.BoxSizer(wx.VERTICAL)
2583            choice = ['Mustrain','Size','Preferred orientation']
2584            plotSel = wx.RadioBox(DData,-1,'Select plot type:',choices=choice,
2585                majorDimension=3,style=wx.RA_SPECIFY_COLS)
2586            plotSel.SetStringSelection(generalData['Data plot type'])
2587            plotSel.Bind(wx.EVT_RADIOBOX,OnPlotSel)   
2588            plotSizer.Add(plotSel)
2589            if generalData['Data plot type'] == 'Preferred orientation':
2590                POhklSizer = wx.BoxSizer(wx.HORIZONTAL)
2591                POhklSizer.Add(wx.StaticText(DData,-1,' Plot preferred orientation for H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2592                h,k,l = generalData['POhkl']
2593                poAxis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2594                poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOhkl)
2595                poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOhkl)
2596                POhklSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
2597                plotSizer.Add(POhklSizer)           
2598            return plotSizer
2599           
2600        def ScaleSizer():
2601            scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
2602            scaleRef = wx.CheckBox(DData,-1,label=' Phase fraction: ')
2603            scaleRef.SetValue(UseList[item]['Scale'][1])
2604            Indx[scaleRef.GetId()] = item
2605            scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
2606            scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
2607            scaleVal = wx.TextCtrl(DData,wx.ID_ANY,
2608                '%.4f'%(UseList[item]['Scale'][0]),style=wx.TE_PROCESS_ENTER)
2609            Indx[scaleVal.GetId()] = item
2610            scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
2611            scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
2612            scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
2613            return scaleSizer
2614           
2615        def TopSizer(name,choices,parm,OnType):
2616            topSizer = wx.BoxSizer(wx.HORIZONTAL)
2617            topSizer.Add(wx.StaticText(DData,-1,name),0,wx.ALIGN_CENTER_VERTICAL)
2618            sizeType = wx.ComboBox(DData,wx.ID_ANY,value=UseList[item][parm][0],choices=choices,
2619                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2620            sizeType.Bind(wx.EVT_COMBOBOX, OnType)
2621            Indx[sizeType.GetId()] = item
2622            topSizer.Add(sizeType)
2623            topSizer.Add((5,0),0)
2624            return topSizer
2625           
2626        def IsoSizer(name,parm,fmt,OnVal,OnRef):
2627            isoSizer = wx.BoxSizer(wx.HORIZONTAL)
2628            sizeRef = wx.CheckBox(DData,-1,label=name)
2629            sizeRef.thisown = False
2630            sizeRef.SetValue(UseList[item][parm][2][0])
2631            Indx[sizeRef.GetId()] = [item,0]
2632            sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
2633            isoSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2634            sizeVal = wx.TextCtrl(DData,wx.ID_ANY,
2635                fmt%(UseList[item][parm][1][0]),style=wx.TE_PROCESS_ENTER)
2636            Indx[sizeVal.GetId()] = [item,0]
2637            sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
2638            sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
2639            isoSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2640            return isoSizer
2641           
2642        def UniSizer(parm,OnAxis):
2643            uniSizer = wx.BoxSizer(wx.HORIZONTAL)
2644            uniSizer.Add(wx.StaticText(DData,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2645            h,k,l = UseList[item][parm][3]
2646            Axis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2647            Indx[Axis.GetId()] = item
2648            Axis.Bind(wx.EVT_TEXT_ENTER,OnAxis)
2649            Axis.Bind(wx.EVT_KILL_FOCUS,OnAxis)
2650            uniSizer.Add(Axis,0,wx.ALIGN_CENTER_VERTICAL)
2651            return uniSizer
2652           
2653        def UniDataSizer(parmName,parm,fmt,OnVal,OnRef):
2654            dataSizer = wx.BoxSizer(wx.HORIZONTAL)
2655            parms = zip([' Equatorial '+parmName,' Axial '+parmName],
2656                UseList[item][parm][1],UseList[item][parm][2],range(2))
2657            for Pa,val,ref,id in parms:
2658                sizeRef = wx.CheckBox(DData,-1,label=Pa)
2659                sizeRef.thisown = False
2660                sizeRef.SetValue(ref)
2661                Indx[sizeRef.GetId()] = [item,id]
2662                sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
2663                dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2664                sizeVal = wx.TextCtrl(DData,wx.ID_ANY,fmt%(val),style=wx.TE_PROCESS_ENTER)
2665                Indx[sizeVal.GetId()] = [item,id]
2666                sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
2667                sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
2668                dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2669                dataSizer.Add((5,0),0)
2670            return dataSizer
2671           
2672        def EllSizeDataSizer():
2673            parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[item]['Size'][4],
2674                UseList[item]['Size'][5],range(6))
2675            dataSizer = wx.FlexGridSizer(1,6,5,5)
2676            for Pa,val,ref,id in parms:
2677                sizeRef = wx.CheckBox(DData,-1,label=Pa)
2678                sizeRef.thisown = False
2679                sizeRef.SetValue(ref)
2680                Indx[sizeRef.GetId()] = [item,id]
2681                sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2682                dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2683                sizeVal = wx.TextCtrl(DData,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER)
2684                Indx[sizeVal.GetId()] = [item,id]
2685                sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2686                sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2687                dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2688            return dataSizer
2689           
2690        def GenStrainDataSizer():
2691            Snames = G2spc.MustrainNames(SGData)
2692            numb = len(Snames)
2693            if len(UseList[item]['Mustrain'][4]) < numb:
2694                UseList[item]['Mustrain'][4] = numb*[0.0,]
2695                UseList[item]['Mustrain'][5] = numb*[False,]
2696            parms = zip(Snames,UseList[item]['Mustrain'][4],UseList[item]['Mustrain'][5],range(numb))
2697            dataSizer = wx.FlexGridSizer(1,6,5,5)
2698            for Pa,val,ref,id in parms:
2699                strainRef = wx.CheckBox(DData,-1,label=Pa)
2700                strainRef.thisown = False
2701                strainRef.SetValue(ref)
2702                Indx[strainRef.GetId()] = [item,id]
2703                strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2704                dataSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2705                strainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
2706                Indx[strainVal.GetId()] = [item,id]
2707                strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2708                strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2709                dataSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2710            return dataSizer
2711           
2712        def HstrainSizer():
2713            hstrainSizer = wx.FlexGridSizer(1,6,5,5)
2714            Hsnames = G2spc.HStrainNames(SGData)
2715            parms = zip(Hsnames,UseList[item]['HStrain'][0],UseList[item]['HStrain'][1],range(len(Hsnames)))
2716            for Pa,val,ref,id in parms:
2717                hstrainRef = wx.CheckBox(DData,-1,label=Pa)
2718                hstrainRef.thisown = False
2719                hstrainRef.SetValue(ref)
2720                Indx[hstrainRef.GetId()] = [item,id]
2721                hstrainRef.Bind(wx.EVT_CHECKBOX, OnHstrainRef)
2722                hstrainSizer.Add(hstrainRef,0,wx.ALIGN_CENTER_VERTICAL)
2723                hstrainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
2724                Indx[hstrainVal.GetId()] = [item,id]
2725                hstrainVal.Bind(wx.EVT_TEXT_ENTER,OnHstrainVal)
2726                hstrainVal.Bind(wx.EVT_KILL_FOCUS,OnHstrainVal)
2727                hstrainSizer.Add(hstrainVal,0,wx.ALIGN_CENTER_VERTICAL)
2728            return hstrainSizer
2729           
2730        def PoTopSizer(POData):
2731            poSizer = wx.FlexGridSizer(1,6,5,5)
2732            choice = ['March-Dollase','Spherical harmonics']
2733            POtype = choice[['MD','SH'].index(POData[0])]
2734            poSizer.Add(wx.StaticText(DData,-1,' Preferred orientation model '),0,wx.ALIGN_CENTER_VERTICAL)
2735            POType = wx.ComboBox(DData,wx.ID_ANY,value=POtype,choices=choice,
2736                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2737            Indx[POType.GetId()] = item
2738            POType.Bind(wx.EVT_COMBOBOX, OnPOType)
2739            poSizer.Add(POType)
2740            if POData[0] == 'SH':
2741                poSizer.Add(wx.StaticText(DData,-1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2742                poOrder = wx.ComboBox(DData,wx.ID_ANY,value=str(POData[4]),choices=[str(2*i) for i in range(18)],
2743                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2744                Indx[poOrder.GetId()] = item
2745                poOrder.Bind(wx.EVT_COMBOBOX,OnPOOrder)
2746                poSizer.Add(poOrder,0,wx.ALIGN_CENTER_VERTICAL)
2747                poRef = wx.CheckBox(DData,-1,label=' Refine? ')
2748                poRef.SetValue(POData[2])
2749                Indx[poRef.GetId()] = item
2750                poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
2751                poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
2752            return poSizer
2753           
2754        def MDDataSizer(POData):
2755            poSizer = wx.BoxSizer(wx.HORIZONTAL)
2756            poRef = wx.CheckBox(DData,-1,label=' March-Dollase ratio: ')
2757            poRef.SetValue(POData[2])
2758            Indx[poRef.GetId()] = item
2759            poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
2760            poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
2761            poVal = wx.TextCtrl(DData,wx.ID_ANY,
2762                '%.3f'%(POData[1]),style=wx.TE_PROCESS_ENTER)
2763            Indx[poVal.GetId()] = item
2764            poVal.Bind(wx.EVT_TEXT_ENTER,OnPOVal)
2765            poVal.Bind(wx.EVT_KILL_FOCUS,OnPOVal)
2766            poSizer.Add(poVal,0,wx.ALIGN_CENTER_VERTICAL)
2767            poSizer.Add(wx.StaticText(DData,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2768            h,k,l =POData[3]
2769            poAxis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2770            Indx[poAxis.GetId()] = item
2771            poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOAxis)
2772            poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOAxis)
2773            poSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
2774            return poSizer
2775           
2776        def SHDataSizer(POData):
2777            textJ = G2lat.textureIndex(POData[5])
2778            mainSizer.Add(wx.StaticText(DData,-1,' Spherical harmonic coefficients: '+'Texture index: %.3f'%(textJ)),0,wx.ALIGN_CENTER_VERTICAL)
2779            mainSizer.Add((0,5),0)
2780            ODFSizer = wx.FlexGridSizer(2,8,2,2)
2781            ODFIndx = {}
2782            ODFkeys = POData[5].keys()
2783            ODFkeys.sort()
2784            for odf in ODFkeys:
2785                ODFSizer.Add(wx.StaticText(DData,-1,odf),0,wx.ALIGN_CENTER_VERTICAL)
2786                ODFval = wx.TextCtrl(DData,wx.ID_ANY,'%8.3f'%(POData[5][odf]),style=wx.TE_PROCESS_ENTER)
2787                ODFIndx[ODFval.GetId()] = odf
2788#                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2789#                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2790                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2791            return ODFSizer
2792           
2793        def ExtSizer():           
2794            extSizer = wx.BoxSizer(wx.HORIZONTAL)
2795            extRef = wx.CheckBox(DData,-1,label=' Extinction: ')
2796            extRef.SetValue(UseList[item]['Extinction'][1])
2797            Indx[extRef.GetId()] = item
2798            extRef.Bind(wx.EVT_CHECKBOX, OnExtRef)
2799            extSizer.Add(extRef,0,wx.ALIGN_CENTER_VERTICAL)
2800            extVal = wx.TextCtrl(DData,wx.ID_ANY,
2801                '%.2f'%(UseList[item]['Extinction'][0]),style=wx.TE_PROCESS_ENTER)
2802            Indx[extVal.GetId()] = item
2803            extVal.Bind(wx.EVT_TEXT_ENTER,OnExtVal)
2804            extVal.Bind(wx.EVT_KILL_FOCUS,OnExtVal)
2805            extSizer.Add(extVal,0,wx.ALIGN_CENTER_VERTICAL)
2806            return extSizer
2807           
2808        if DData.GetSizer():
2809            DData.GetSizer().Clear(True)
2810        mainSizer = wx.BoxSizer(wx.VERTICAL)
2811        mainSizer.Add(wx.StaticText(DData,-1,'Histogram data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2812        mainSizer.Add(PlotSizer())           
2813           
2814        for item in keyList:
2815            histData = UseList[item]
2816           
2817            showSizer = wx.BoxSizer(wx.HORIZONTAL)
2818            showData = wx.CheckBox(DData,-1,label=' Show '+item)
2819            showData.SetValue(UseList[item]['Show'])
2820            Indx[showData.GetId()] = item
2821            showData.Bind(wx.EVT_CHECKBOX, OnShowData)
2822            showSizer.Add(showData,0,wx.ALIGN_CENTER_VERTICAL)
2823            copyData = wx.Button(DData,-1,label=' Copy?')
2824            Indx[copyData.GetId()] = item
2825            copyData.Bind(wx.EVT_BUTTON,OnCopyData)
2826            showSizer.Add(copyData,wx.ALIGN_CENTER_VERTICAL)
2827            mainSizer.Add((5,5),0)
2828            mainSizer.Add(showSizer,0,wx.ALIGN_CENTER_VERTICAL)
2829            mainSizer.Add((0,5),0)
2830           
2831            if UseList[item]['Show']:
2832                mainSizer.Add(ScaleSizer())
2833                mainSizer.Add((0,5),0)
2834               
2835            if item[:4] == 'PWDR' and UseList[item]['Show']:
2836                if UseList[item]['Size'][0] == 'isotropic':
2837                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
2838                    isoSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
2839                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
2840                    isoSizer.Add(IsoSizer(u' Cryst. size(\xb5m): ','Size','%.3f',
2841                        OnSizeVal,OnSizeRef),0,wx.ALIGN_CENTER_VERTICAL)
2842                    mainSizer.Add(isoSizer)
2843                elif UseList[item]['Size'][0] == 'uniaxial':
2844                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
2845                    uniSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
2846                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
2847                    uniSizer.Add(UniSizer('Size',OnSizeAxis),0,wx.ALIGN_CENTER_VERTICAL)
2848                    mainSizer.Add(uniSizer)
2849                    mainSizer.Add(UniDataSizer(u'size(\xb5m): ','Size','%.3f',OnSizeVal,OnSizeRef))
2850                elif UseList[item]['Size'][0] == 'ellipsoidal':
2851                    ellSizer = wx.BoxSizer(wx.HORIZONTAL)
2852                    ellSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
2853                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
2854                    ellSizer.Add(wx.StaticText(DData,-1,u' Coefficients(\xb5m): '),0,wx.ALIGN_CENTER_VERTICAL)
2855                    mainSizer.Add(ellSizer)
2856                    mainSizer.Add(EllSizeDataSizer())
2857                mainSizer.Add((0,5),0)                   
2858               
2859                if UseList[item]['Mustrain'][0] == 'isotropic':
2860                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
2861                    isoSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
2862                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
2863                    isoSizer.Add(IsoSizer(' microstrain: ','Mustrain','%.1f',
2864                        OnStrainVal,OnStrainRef),0,wx.ALIGN_CENTER_VERTICAL)                   
2865                    mainSizer.Add(isoSizer)
2866                    mainSizer.Add((0,5),0)
2867                elif UseList[item]['Mustrain'][0] == 'uniaxial':
2868                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
2869                    uniSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
2870                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
2871                    uniSizer.Add(UniSizer('Mustrain',OnStrainAxis),0,wx.ALIGN_CENTER_VERTICAL)
2872                    mainSizer.Add(uniSizer)
2873                    mainSizer.Add(UniDataSizer('mustrain: ','Mustrain','%.1f',OnStrainVal,OnStrainRef))
2874                elif UseList[item]['Mustrain'][0] == 'generalized':
2875                    genSizer = wx.BoxSizer(wx.HORIZONTAL)
2876                    genSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
2877                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
2878                    genSizer.Add(wx.StaticText(DData,-1,' Coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2879                    mainSizer.Add(genSizer)
2880                    mainSizer.Add(GenStrainDataSizer())                       
2881                mainSizer.Add((0,5),0)
2882               
2883                mainSizer.Add(wx.StaticText(DData,-1,' Hydrostatic/elastic strain:'))
2884                mainSizer.Add(HstrainSizer())
2885                   
2886                #texture  'Pref. Ori.':['MD',1.0,False,[0,0,1],0,[]] last two for 'SH' are SHorder & coeff
2887                poSizer = wx.BoxSizer(wx.VERTICAL)
2888                POData = UseList[item]['Pref.Ori.']
2889                poSizer.Add(PoTopSizer(POData))
2890                if POData[0] == 'MD':
2891                    poSizer.Add(MDDataSizer(POData))
2892                else:           #'SH'
2893                    if POData[4]:       #SH order > 0
2894                        poSizer.Add(SHDataSizer(POData))
2895                       
2896                mainSizer.Add(poSizer)
2897                mainSizer.Add((0,5),0)               
2898                #Extinction  'Extinction':[0.0,False]
2899                mainSizer.Add(ExtSizer())
2900                mainSizer.Add((0,5),0)
2901            elif item[:4] == 'HKLF' and UseList[item]['Show']:
2902                pass
2903        mainSizer.Add((5,5),0)
2904
2905        DData.SetSizer(mainSizer,True)
2906        mainSizer.FitInside(G2frame.dataFrame)
2907        Size = mainSizer.GetMinSize()
2908        Size[0] += 40
2909        Size[1] = max(Size[1],250) + 20
2910        DData.SetSize(Size)
2911        DData.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2912        Size[1] = min(Size[1],450)
2913        G2frame.dataFrame.setSizePosLeft(Size)
2914       
2915    def OnHklfAdd(event):
2916        UseList = data['Histograms']
2917        keyList = UseList.keys()
2918        TextList = []
2919        if G2frame.PatternTree.GetCount():
2920            item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
2921            while item:
2922                name = G2frame.PatternTree.GetItemText(item)
2923                if name not in keyList and 'HKLF' in name:
2924                    TextList.append(name)
2925                item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)                       
2926            dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2927            try:
2928                if dlg.ShowModal() == wx.ID_OK:
2929                    result = dlg.GetSelections()
2930                    for i in result:
2931                        histoName = TextList[i]
2932                        UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
2933                            'Extinction':['Lorentzian','Secondary Type I',{'Eg':[0.0,False]},]}                       
2934                    data['Histograms'] = UseList
2935                    wx.CallAfter(UpdateDData)
2936            finally:
2937                dlg.Destroy()
2938       
2939    def OnPwdrAdd(event):
2940        generalData = data['General']
2941        SGData = generalData['SGData']
2942        UseList = data['Histograms']
2943        newList = []
2944        NShkl = len(G2spc.MustrainNames(SGData))
2945        NDij = len(G2spc.HStrainNames(SGData))
2946        keyList = UseList.keys()
2947        TextList = ['All PWDR']
2948        if G2frame.PatternTree.GetCount():
2949            item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
2950            while item:
2951                name = G2frame.PatternTree.GetItemText(item)
2952                if name not in keyList and 'PWDR' in name:
2953                    TextList.append(name)
2954                item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
2955            dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2956            try:
2957                if dlg.ShowModal() == wx.ID_OK:
2958                    result = dlg.GetSelections()
2959                    for i in result: newList.append(TextList[i])
2960                    if 'All PWDR' in newList:
2961                        newList = TextList[1:]
2962                    for histoName in newList:
2963                        pId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName)
2964                        UseList[histoName] = {'Histogram':histoName,'Show':False,
2965                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{}],
2966                            'Size':['isotropic',[4.,4.,],[False,False],[0,0,1],[4.,4.,4.,0.,0.,0.],6*[False,]],
2967                            'Mustrain':['isotropic',[1000.0,1000.0],[False,False],[0,0,1],
2968                                NShkl*[0.01,],NShkl*[False,]],
2969                            'HStrain':[NDij*[0.0,],NDij*[False,]],                         
2970                            'Extinction':[0.0,False]}
2971                        refList = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,pId,'Reflection Lists'))
2972                        refList[generalData['Name']] = []                       
2973                    data['Histograms'] = UseList
2974                    wx.CallAfter(UpdateDData)
2975            finally:
2976                dlg.Destroy()
2977       
2978    def OnDataDelete(event):
2979        UseList = data['Histograms']
2980        keyList = ['All',]+UseList.keys()
2981        keyList.sort()
2982        DelList = []
2983        if UseList:
2984            DelList = []
2985            dlg = wx.MultiChoiceDialog(G2frame, 
2986                'Which histogram to delete from this phase?', 'Delete histogram', 
2987                keyList, wx.CHOICEDLG_STYLE)
2988            try:
2989                if dlg.ShowModal() == wx.ID_OK:
2990                    result = dlg.GetSelections()
2991                    for i in result: 
2992                        DelList.append(keyList[i])
2993                    if 'All' in DelList:
2994                        DelList = keyList[1:]
2995                    for i in DelList:
2996                        del UseList[i]
2997                    wx.CallAfter(UpdateDData)
2998            finally:
2999                dlg.Destroy()
3000
3001    def FillPawleyReflectionsGrid():
3002                       
3003        def KeyEditPawleyGrid(event):
3004            colList = G2frame.PawleyRefl.GetSelectedCols()
3005            PawleyPeaks = data['Pawley ref']
3006            if event.GetKeyCode() == wx.WXK_RETURN:
3007                event.Skip(True)
3008            elif event.GetKeyCode() == wx.WXK_CONTROL:
3009                event.Skip(True)
3010            elif event.GetKeyCode() == wx.WXK_SHIFT:
3011                event.Skip(True)
3012            elif colList:
3013                G2frame.PawleyRefl.ClearSelection()
3014                key = event.GetKeyCode()
3015                for col in colList:
3016                    if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
3017                        if key == 89: #'Y'
3018                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True
3019                        elif key == 78:  #'N'
3020                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False
3021                        FillPawleyReflectionsGrid()
3022           
3023        if 'Pawley ref' in data:
3024            PawleyPeaks = data['Pawley ref']                       
3025            rowLabels = []
3026            for i in range(len(PawleyPeaks)): rowLabels.append(str(i))
3027            colLabels = ['h','k','l','mul','d','refine','Fsq(hkl)','sig(Fsq)']
3028            Types = 4*[wg.GRID_VALUE_LONG,]+[wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,]+ \
3029                2*[wg.GRID_VALUE_FLOAT+':10,2',]
3030            PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
3031            G2frame.PawleyRefl.SetTable(PawleyTable, True)
3032            G2frame.PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid)                 
3033            G2frame.PawleyRefl.SetMargins(0,0)
3034            G2frame.PawleyRefl.AutoSizeColumns(False)
3035            G2frame.dataFrame.setSizePosLeft([500,300])
3036                   
3037    def OnPawleyLoad(event):
3038        generalData = data['General']
3039        dmin = generalData['Pawley dmin']
3040        cell = generalData['Cell'][1:7]
3041        A = G2lat.cell2A(cell)
3042        SGData = generalData['SGData']
3043        HKLd = np.array(G2lat.GenHLaue(dmin,SGData,A))
3044        PawleyPeaks = []
3045        wx.BeginBusyCursor()
3046        try:
3047            for h,k,l,d in HKLd:
3048                ext,mul = G2spc.GenHKLf([h,k,l],SGData)[:2]
3049                if not ext:
3050                    PawleyPeaks.append([h,k,l,mul,d,False,100.0,1.0])
3051        finally:
3052            wx.EndBusyCursor()
3053        data['Pawley ref'] = PawleyPeaks
3054        FillPawleyReflectionsGrid()
3055       
3056    def OnPawleyEstimate(event):
3057        try:
3058            Refs = data['Pawley ref']
3059            Histograms = data['Histograms']
3060        except KeyError:
3061            print '**** Error - no histograms defined for this phase ****'
3062            return
3063        HistoNames = Histograms.keys()
3064        PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,HistoNames[0])
3065        xdata = G2frame.PatternTree.GetItemPyData(PatternId)[1]
3066        Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Instrument Parameters'))
3067        Inst = dict(zip(Inst[3],Inst[1]))
3068        Sample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Sample Parameters'))
3069        if 'Lam' in Inst:
3070            wave = Inst['Lam']
3071        else:
3072            wave = Inst['Lam1']
3073       
3074        posCorr = Inst['Zero']
3075        const = 9.e-2/(np.pi*Sample['Gonio. radius'])                  #shifts in microns
3076       
3077        for ref in Refs:
3078            pos = 2.0*asind(wave/(2.0*ref[4]))
3079            if 'Bragg' in Sample['Type']:
3080                pos -= const*(4.*Sample['Shift'][0]*cosd(pos/2.0)+ \
3081                    Sample['Transparency'][0]*sind(pos)*100.0)            #trans(=1/mueff) in cm
3082            else:               #Debye-Scherrer - simple but maybe not right
3083                pos -= const*(Sample['DisplaceX'][0]*cosd(pos)+Sample['DisplaceY'][0]*sind(pos))
3084            indx = np.searchsorted(xdata[0],pos)
3085            try:
3086                ref[6] = xdata[1][indx]
3087            except IndexError:
3088                pass
3089        FillPawleyReflectionsGrid()
3090                           
3091    def OnPawleyDelete(event):
3092        dlg = wx.MessageDialog(G2frame,'Do you really want to delete Pawley reflections?','Delete', 
3093            wx.YES_NO | wx.ICON_QUESTION)
3094        try:
3095            result = dlg.ShowModal()
3096        finally:
3097            dlg.Destroy()
3098        if result == wx.ID_YES: 
3099            data['Pawley ref'] = []
3100            FillPawleyReflectionsGrid()
3101   
3102    def OnTextureRefine(event):
3103        event.Skip()       
3104           
3105    def OnTextureClear(event):
3106        event.Skip()
3107
3108    def OnPageChanged(event):
3109        page = event.GetSelection()
3110        text = G2frame.dataDisplay.GetPageText(page)
3111        if text == 'Atoms':
3112            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.AtomsMenu)
3113            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
3114            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomTestAdd, id=G2gd.wxID_ATOMSTESTADD)
3115            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
3116            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomTestInsert, id=G2gd.wxID_ATONTESTINSERT)
3117            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
3118            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
3119            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
3120            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
3121            G2frame.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS)
3122            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDistAngle, id=G2gd.wxID_ATOMSDISAGL)
3123            FillAtomsGrid()
3124        elif text == 'General':
3125            UpdateGeneral()
3126        elif text == 'Data':
3127            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataMenu)
3128            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD)
3129            G2frame.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD)
3130            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE)
3131            UpdateDData()
3132            G2plt.PlotSizeStrainPO(G2frame,data,Start=True)
3133        elif text == 'Draw Options':
3134            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataDrawOptions)
3135            UpdateDrawOptions()
3136            G2plt.PlotStructure(G2frame,data)
3137        elif text == 'Draw Atoms':
3138            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DrawAtomsMenu)
3139            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE)
3140            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL)
3141            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR)
3142            G2frame.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR)
3143            G2frame.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT)
3144            G2frame.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV)
3145            G2frame.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM)
3146            G2frame.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD)           
3147            G2frame.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL)
3148            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE)
3149            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawDistAngle, id=G2gd.wxID_DRAWDISAGL)
3150            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawTorsion, id=G2gd.wxID_DRAWTORSION)
3151            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawPlane, id=G2gd.wxID_DRAWPLANE)
3152            UpdateDrawAtoms()
3153            G2plt.PlotStructure(G2frame,data)
3154        elif text == 'Pawley reflections':
3155            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.PawleyMenu)
3156            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD)
3157            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyEstimate, id=G2gd.wxID_PAWLEYESTIMATE)
3158            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyDelete, id=G2gd.wxID_PAWLEYDELETE)           
3159            FillPawleyReflectionsGrid()
3160        elif text == 'Texture':
3161            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.TextureMenu)
3162            G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureRefine, id=G2gd.wxID_REFINETEXTURE)
3163            G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureClear, id=G2gd.wxID_CLEARTEXTURE)
3164            UpdateTexture()                       
3165            G2plt.PlotTexture(G2frame,data,Start=True)
3166        else:
3167            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
3168        event.Skip()
3169       
3170    General = wx.Window(G2frame.dataDisplay)
3171    G2frame.dataDisplay.AddPage(General,'General')
3172    SetupGeneral()
3173    GeneralData = data['General']
3174    UpdateGeneral()
3175
3176    if GeneralData['Type'] == 'Pawley':
3177        DData = wx.ScrolledWindow(G2frame.dataDisplay)
3178        G2frame.dataDisplay.AddPage(DData,'Data')
3179        G2frame.PawleyRefl = G2gd.GSGrid(G2frame.dataDisplay)
3180        G2frame.dataDisplay.AddPage(G2frame.PawleyRefl,'Pawley reflections')
3181        Texture = wx.ScrolledWindow(G2frame.dataDisplay)
3182        G2frame.dataDisplay.AddPage(Texture,'Texture')
3183    else:
3184        DData = wx.ScrolledWindow(G2frame.dataDisplay)
3185        G2frame.dataDisplay.AddPage(DData,'Data')
3186        Texture = wx.ScrolledWindow(G2frame.dataDisplay)
3187        G2frame.dataDisplay.AddPage(Texture,'Texture')
3188        Atoms = G2gd.GSGrid(G2frame.dataDisplay)
3189        G2frame.dataDisplay.AddPage(Atoms,'Atoms')
3190        drawOptions = wx.Window(G2frame.dataDisplay)
3191        G2frame.dataDisplay.AddPage(drawOptions,'Draw Options')
3192        drawAtoms = G2gd.GSGrid(G2frame.dataDisplay)
3193        G2frame.dataDisplay.AddPage(drawAtoms,'Draw Atoms')
3194
3195    G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
3196    G2frame.dataDisplay.SetSelection(oldPage)
3197   
3198           
Note: See TracBrowser for help on using the repository browser.