source: trunk/GSASIIphsGUI.py @ 468

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

changed self to G2frame everywhere in all "sub" files that use it
fixed creation of 'bak' files
now force save of a new gpx file before 1st peak fit so
GSAS.save is put in a sensible directory

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