source: trunk/GSASIIphsGUI.py @ 313

Last change on this file since 313 was 313, checked in by vondreele, 12 years ago

work on texture display & computation

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