source: trunk/GSASIIphsGUI.py @ 335

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

Add delete Pawley list; scratch "leBail" from things
mods to texture display stuff
refactor instrument parameters GUI as sizer based - no grid table
some mods to peak fit output

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