source: trunk/GSASIIphsGUI.py @ 485

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