source: trunk/GSASIIphsGUI.py @ 327

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

fix to path name for atomdata.dat
fix to texture display - can't have colorbars!
put in bit to show #threads used

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