source: trunk/GSASIIphsGUI.py @ 477

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

final fixes to dist-angle-torsion calc.

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