source: trunk/GSASIIphsGUI.py @ 326

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

remove cf2py
add inverse polefigure

  • 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-06-30 16:38:20 +0000 (Thu, 30 Jun 2011) $
4# $Author: vondreele $
5# $Revision: 326 $
6# $URL: trunk/GSASIIphsGUI.py $
7# $Id: GSASIIphsGUI.py 326 2011-06-30 16:38:20Z 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            print 'before'
1924            UpdateDData()
1925            print 'after'
1926            G2plt.PlotTexture(self,data,newPlot=True)
1927           
1928        def OnPFValue(event):
1929            Obj = event.GetEventObject()
1930            if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
1931                try:
1932                    value = '['+Obj.GetValue()+']'
1933                    hkl = eval(value)
1934                except:
1935                    value = str(textureData['PFhkl'])
1936                    hkl = eval(value)
1937                Obj.SetValue('%d,%d,%d'%(hkl[0],hkl[1],hkl[2]))
1938                textureData['PFhkl'] = hkl
1939            else:
1940                try:
1941                    value =  '['+Obj.GetValue()+']'
1942                    xyz = eval(value)
1943                except:
1944                    value = str(textureData['PFhkl'])
1945                    xyz = eval(value)
1946                Obj.SetValue('%3.1f,%3.1f,%3.1f'%(xyz[0],xyz[1],xyz[2]))
1947                textureData['PFxyz'] = xyz
1948            G2plt.PlotTexture(self,data,newPlot=True)
1949       
1950        def OnShowData(event):
1951            Obj = event.GetEventObject()
1952            hist = Indx[Obj.GetId()]
1953            UseList[hist]['Show'] = Obj.GetValue()
1954            UpdateDData()
1955            G2plt.PlotStrain(self,data)
1956           
1957        def OnScaleRef(event):
1958            Obj = event.GetEventObject()
1959            UseList[Indx[Obj.GetId()]]['Scale'][1] = Obj.GetValue()
1960           
1961        def OnScaleVal(event):
1962            Obj = event.GetEventObject()
1963            try:
1964                scale = float(Obj.GetValue())
1965                if scale > 0:
1966                    UseList[Indx[Obj.GetId()]]['Scale'][0] = scale
1967            except ValueError:
1968                pass
1969            Obj.SetValue("%.4f"%(UseList[Indx[Obj.GetId()]]['Scale'][0]))          #reset in case of error
1970           
1971        def OnSizeType(event):
1972            Obj = event.GetEventObject()
1973            hist = Indx[Obj.GetId()]
1974            UseList[hist]['Size'][0] = Obj.GetValue()
1975            UpdateDData()
1976           
1977        def OnSizeRef(event):
1978            Obj = event.GetEventObject()
1979            hist,pid = Indx[Obj.GetId()]
1980            UseList[hist]['Size'][2][pid] = Obj.GetValue()
1981           
1982        def OnSizeVal(event):
1983            Obj = event.GetEventObject()
1984            hist,pid = Indx[Obj.GetId()]
1985            try:
1986                size = float(Obj.GetValue())
1987                if pid == 0 and size <= 0:
1988                    raise ValueError
1989                elif pid == 1 and size <= -UseList[hist]['Size'][1][0]:
1990                    raise ValueError
1991                UseList[hist]['Size'][1][pid] = size
1992            except ValueError:
1993                pass
1994            Obj.SetValue("%.1f"%(UseList[hist]['Size'][1][pid]))          #reset in case of error
1995           
1996        def OnSizeAxis(event):           
1997            Obj = event.GetEventObject()
1998            hist = Indx[Obj.GetId()]
1999            Saxis = Obj.GetValue().split()
2000            try:
2001                hkl = [int(Saxis[i]) for i in range(3)]
2002            except (ValueError,IndexError):
2003                hkl = UseList[hist]['Size'][3]
2004            if not np.any(np.array(hkl)):
2005                hkl = UseList[hist]['Size'][3]
2006            UseList[hist]['Size'][3] = hkl
2007            h,k,l = hkl
2008            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2009                       
2010        def OnStrainType(event):
2011            Obj = event.GetEventObject()
2012            hist = Indx[Obj.GetId()]
2013            UseList[hist]['Mustrain'][0] = Obj.GetValue()
2014            UpdateDData()
2015            G2plt.PlotStrain(self,data)
2016           
2017        def OnStrainRef(event):
2018            Obj = event.GetEventObject()
2019            hist,pid = Indx[Obj.GetId()]
2020            if UseList[hist]['Mustrain'][0] == 'generalized':
2021                UseList[hist]['Mustrain'][5][pid] = Obj.GetValue()
2022            else:
2023                UseList[hist]['Mustrain'][2][pid] = Obj.GetValue()
2024           
2025        def OnStrainVal(event):
2026            Snames = G2spc.MustrainNames(SGData)
2027            Obj = event.GetEventObject()
2028            hist,pid = Indx[Obj.GetId()]
2029            try:
2030                strain = float(Obj.GetValue())
2031                if UseList[hist]['Mustrain'][0] == 'generalized':
2032                    if '4' in Snames[pid] and strain < 0:
2033                        raise ValueError
2034                    UseList[hist]['Mustrain'][4][pid] = strain
2035                else:
2036                    if pid == 0 and strain < 0:
2037                        raise ValueError
2038                    elif pid == 1 and strain < -UseList[hist]['Mustrain'][1][0]:
2039                        raise ValueError
2040                    UseList[hist]['Mustrain'][1][pid] = strain
2041            except ValueError:
2042                pass
2043            if UseList[hist]['Mustrain'][0] == 'generalized':
2044                Obj.SetValue("%.5f"%(UseList[hist]['Mustrain'][4][pid]))          #reset in case of error
2045            else:
2046                Obj.SetValue("%.5f"%(UseList[hist]['Mustrain'][1][pid]))          #reset in case of error
2047            G2plt.PlotStrain(self,data)
2048           
2049        def OnStrainAxis(event):
2050            Obj = event.GetEventObject()
2051            hist = Indx[Obj.GetId()]
2052            Saxis = Obj.GetValue().split()
2053            try:
2054                hkl = [int(Saxis[i]) for i in range(3)]
2055            except (ValueError,IndexError):
2056                hkl = UseList[hist]['Mustrain'][3]
2057            if not np.any(np.array(hkl)):
2058                hkl = UseList[hist]['Mustrain'][3]
2059            UseList[hist]['Mustrain'][3] = hkl
2060            h,k,l = hkl
2061            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2062            G2plt.PlotStrain(self,data)
2063
2064        def OnMDRef(event):
2065            Obj = event.GetEventObject()
2066            hist = Indx[Obj.GetId()]
2067            UseList[hist]['MDtexture'][1] = Obj.GetValue()
2068           
2069        def OnMDVal(event):
2070            Obj = event.GetEventObject()
2071            hist = Indx[Obj.GetId()]
2072            try:
2073                mdVal = float(Obj.GetValue())
2074                if mdVal > 0:
2075                    UseList[hist]['MDtexture'][0] = mdVal
2076            except ValueError:
2077                pass
2078            Obj.SetValue("%.3f"%(UseList[hist]['MDtexture'][0]))          #reset in case of error
2079           
2080        def OnMDAxis(event):
2081            Obj = event.GetEventObject()
2082            hist = Indx[Obj.GetId()]
2083            Saxis = Obj.GetValue().split()
2084            try:
2085                hkl = [int(Saxis[i]) for i in range(3)]
2086            except (ValueError,IndexError):
2087                hkl = UseList[hist]['MDtexture'][2]
2088            if not np.any(np.array(hkl)):
2089                hkl = UseList[hist]['MDtexture'][2]
2090            UseList[hist]['MDtexture'][2] = hkl
2091            h,k,l = hkl
2092            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2093           
2094        def OnExtRef(event):
2095            Obj = event.GetEventObject()
2096            UseList[Indx[Obj.GetId()]]['Extinction'][1] = Obj.GetValue()
2097           
2098        def OnExtVal(event):
2099            Obj = event.GetEventObject()
2100            try:
2101                ext = float(Obj.GetValue())
2102                if ext >= 0:
2103                    UseList[Indx[Obj.GetId()]]['Extinction'][0] = ext
2104            except ValueError:
2105                pass
2106            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][0]))          #reset in case of error
2107           
2108        def checkAxis(axis):
2109            if not np.any(np.array(axis)):
2110                return False
2111            return axis
2112           
2113        DData.DestroyChildren()
2114        dataDisplay = wx.Panel(DData)
2115        mainSizer = wx.BoxSizer(wx.VERTICAL)
2116        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2117        mainSizer.Add((0,5),0)
2118        shSizer = wx.BoxSizer(wx.HORIZONTAL)
2119        shSizer.Add(wx.StaticText(dataDisplay,-1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL)
2120        shModel = wx.ComboBox(dataDisplay,-1,value=textureData['Model'],choices=shModels,
2121            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2122        shModel.Bind(wx.EVT_COMBOBOX,OnShModel)
2123        shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL)
2124        shSizer.Add(wx.StaticText(dataDisplay,-1,'  Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2125        shOrder = wx.ComboBox(dataDisplay,-1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)],
2126            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2127        shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder)
2128        shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL)
2129        shSizer.Add((5,0),0)
2130        shRef = wx.CheckBox(dataDisplay,label=' Refine texture?')
2131        shRef.SetValue(textureData['SH Coeff'][0])
2132        shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine)
2133        shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL)
2134        shShow = wx.CheckBox(dataDisplay,label=' Show coeff.?')
2135        shShow.SetValue(textureData['SHShow'])
2136        shShow.Bind(wx.EVT_CHECKBOX, OnSHShow)
2137        shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL)
2138        mainSizer.Add(shSizer,0,0)
2139        mainSizer.Add((0,5),0)
2140        mainSizer.Add(wx.StaticText(dataDisplay,-1,
2141            'Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))),
2142            0,wx.ALIGN_CENTER_VERTICAL)
2143        mainSizer.Add((0,5),0)
2144        if textureData['SHShow']:
2145            mainSizer.Add(wx.StaticText(dataDisplay,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2146            mainSizer.Add((0,5),0)
2147            ODFSizer = wx.FlexGridSizer(2,8,2,2)
2148            ODFIndx = {}
2149            ODFkeys = textureData['SH Coeff'][1].keys()
2150            ODFkeys.sort()
2151            for item in ODFkeys:
2152                ODFSizer.Add(wx.StaticText(dataDisplay,-1,item),0,wx.ALIGN_CENTER_VERTICAL)
2153                ODFval = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER)
2154                ODFIndx[ODFval.GetId()] = item
2155                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2156                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2157                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2158            mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2159            mainSizer.Add((0,5),0)
2160        PFSizer = wx.BoxSizer(wx.HORIZONTAL)
2161        PFSizer.Add(wx.StaticText(dataDisplay,-1,'Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL)
2162        choices = ['Axial pole distribution','Pole figure','Inverse pole figure']           
2163        pfType = wx.ComboBox(dataDisplay,-1,value=str(textureData['PlotType']),choices=choices,
2164            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2165        pfType.Bind(wx.EVT_COMBOBOX,OnPfType)
2166        PFSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL)
2167        mainSizer.Add(PFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2168        if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
2169            PFSizer.Add(wx.StaticText(dataDisplay,-1,'  Display pole figure for HKL: '),0,wx.ALIGN_CENTER_VERTICAL)
2170            PH = textureData['PFhkl']
2171            pfVal = wx.TextCtrl(dataDisplay,-1,'%d,%d,%d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER)
2172            pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue)
2173            pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue)
2174            PFSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL)
2175        else:
2176            PFSizer.Add(wx.StaticText(dataDisplay,-1,'  Display inverse pole figure for XYZ: '),0,wx.ALIGN_CENTER_VERTICAL)
2177            PX = textureData['PFxyz']
2178            pfVal = wx.TextCtrl(dataDisplay,-1,'%3.1f,%3.1f,%3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER)
2179            pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue)
2180            pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue)
2181            PFSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL)
2182        mainSizer.Add((0,5),0)
2183        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL)
2184        mainSizer.Add((0,5),0)
2185        angSizer = wx.BoxSizer(wx.HORIZONTAL)
2186        angIndx = {}
2187        valIndx = {}
2188        for item in ['Sample omega','Sample chi','Sample phi']:
2189            angRef = wx.CheckBox(dataDisplay,label=item+': ')
2190            angRef.SetValue(textureData[item][0])
2191            angIndx[angRef.GetId()] = item
2192            angRef.Bind(wx.EVT_CHECKBOX, OnAngRef)
2193            angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL)
2194            angVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER)
2195            valIndx[angVal.GetId()] = item
2196            angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue)
2197            angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue)
2198            angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL)
2199            angSizer.Add((5,0),0)
2200        mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL)
2201        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Histogram data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2202        for item in keyList:
2203            histData = UseList[item]
2204            mainSizer.Add((5,5),0)
2205            showData = wx.CheckBox(dataDisplay,label=' Show '+item)
2206            showData.SetValue(UseList[item]['Show'])
2207            Indx[showData.GetId()] = item
2208            showData.Bind(wx.EVT_CHECKBOX, OnShowData)
2209            mainSizer.Add(showData,0,wx.ALIGN_CENTER_VERTICAL)
2210            mainSizer.Add((0,5),0)
2211            if UseList[item]['Show']:
2212                scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
2213                scaleRef = wx.CheckBox(dataDisplay,label=' Scale factor: ')
2214                scaleRef.SetValue(UseList[item]['Scale'][1])
2215                Indx[scaleRef.GetId()] = item
2216                scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
2217                scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
2218                scaleVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2219                    '%.4f'%(UseList[item]['Scale'][0]),style=wx.TE_PROCESS_ENTER)
2220                Indx[scaleVal.GetId()] = item
2221                scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
2222                scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
2223                scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
2224                mainSizer.Add(scaleSizer)
2225                mainSizer.Add((0,5),0)
2226               
2227            if item[:4] == 'PWDR' and UseList[item]['Show']:
2228                mainSizer.Add((0,5),0)
2229                sizeSizer = wx.BoxSizer(wx.HORIZONTAL)
2230                choices = ['isotropic','uniaxial',]
2231                sizeType = wx.ComboBox(dataDisplay,wx.ID_ANY,value=UseList[item]['Size'][0],choices=choices,
2232                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2233                sizeType.Bind(wx.EVT_COMBOBOX, OnSizeType)
2234                Indx[sizeType.GetId()] = item
2235                sizeSizer.Add(sizeType)
2236                sizeSizer.Add((5,0),0)
2237                if UseList[item]['Size'][0] == 'isotropic':
2238                    sizeRef = wx.CheckBox(dataDisplay,label=' Cryst. size: ')
2239                    sizeRef.SetValue(UseList[item]['Size'][2][0])
2240                    Indx[sizeRef.GetId()] = [item,0]
2241                    sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2242                    sizeSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2243                    sizeVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2244                        '%.1f'%(UseList[item]['Size'][1][0]),style=wx.TE_PROCESS_ENTER)
2245                    Indx[sizeVal.GetId()] = [item,0]
2246                    sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2247                    sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2248                    sizeSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2249                    mainSizer.Add(sizeSizer)
2250                    mainSizer.Add((0,5),0)
2251                elif UseList[item]['Size'][0] == 'uniaxial':
2252                    sizeSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2253                    h,k,l = UseList[item]['Size'][3]
2254                    sizeAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2255                    Indx[sizeAxis.GetId()] = item
2256                    sizeAxis.Bind(wx.EVT_TEXT_ENTER,OnSizeAxis)
2257                    sizeAxis.Bind(wx.EVT_KILL_FOCUS,OnSizeAxis)
2258                    sizeSizer.Add(sizeAxis,0,wx.ALIGN_CENTER_VERTICAL)
2259                    mainSizer.Add(sizeSizer)
2260                    mainSizer.Add((0,5),0)
2261                    sizeSizer = wx.BoxSizer(wx.HORIZONTAL)
2262                    parms = zip([' Equatorial size: ',' Axial size: '],UseList[item]['Size'][1],
2263                        UseList[item]['Size'][2],range(2))
2264                    for Pa,val,ref,id in parms:
2265                        sizeRef = wx.CheckBox(dataDisplay,label=Pa)
2266                        sizeRef.SetValue(ref)
2267                        Indx[sizeRef.GetId()] = [item,id]
2268                        sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2269                        sizeSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2270                        sizeVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.1f'%(val),style=wx.TE_PROCESS_ENTER)
2271                        Indx[sizeVal.GetId()] = [item,id]
2272                        sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2273                        sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2274                        sizeSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2275                        sizeSizer.Add((5,0),0)
2276                    sizeSizer.Add((5,0),0)                   
2277                    mainSizer.Add(sizeSizer)
2278               
2279                strainSizer = wx.BoxSizer(wx.HORIZONTAL)
2280                choices = ['isotropic','uniaxial','generalized',]
2281                strainType = wx.ComboBox(dataDisplay,wx.ID_ANY,value=UseList[item]['Mustrain'][0],choices=choices,
2282                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2283                strainType.Bind(wx.EVT_COMBOBOX, OnStrainType)
2284                Indx[strainType.GetId()] = item
2285                strainSizer.Add(strainType)
2286                strainSizer.Add((5,0),0)
2287                if UseList[item]['Mustrain'][0] == 'isotropic':
2288                    strainRef = wx.CheckBox(dataDisplay,label=' microstrain: ')
2289                    strainRef.SetValue(UseList[item]['Mustrain'][2][0])
2290                    Indx[strainRef.GetId()] = [item,0]
2291                    strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2292                    strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2293                    strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2294                        '%.3f'%(UseList[item]['Mustrain'][1][0]),style=wx.TE_PROCESS_ENTER)
2295                    Indx[strainVal.GetId()] = [item,0]
2296                    strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2297                    strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2298                    strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2299                    mainSizer.Add(strainSizer)
2300                    mainSizer.Add((0,5),0)
2301                elif UseList[item]['Mustrain'][0] == 'uniaxial':
2302                    strainSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2303                    h,k,l = UseList[item]['Mustrain'][3]
2304                    strAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2305                    Indx[strAxis.GetId()] = item
2306                    strAxis.Bind(wx.EVT_TEXT_ENTER,OnStrainAxis)
2307                    strAxis.Bind(wx.EVT_KILL_FOCUS,OnStrainAxis)
2308                    strainSizer.Add(strAxis,0,wx.ALIGN_CENTER_VERTICAL)
2309                    mainSizer.Add(strainSizer)
2310                    mainSizer.Add((0,5),0)
2311                    strainSizer = wx.BoxSizer(wx.HORIZONTAL)
2312                    parms = zip([' Equatorial mustrain: ',' Axial mustrain: '],
2313                        UseList[item]['Mustrain'][1],UseList[item]['Mustrain'][2],range(2))
2314                    for Pa,val,ref,id in parms:
2315                        strainRef = wx.CheckBox(dataDisplay,label=Pa)
2316                        strainRef.SetValue(ref)
2317                        Indx[strainRef.GetId()] = [item,id]
2318                        strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2319                        strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2320                        strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER)
2321                        Indx[strainVal.GetId()] = [item,id]
2322                        strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2323                        strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2324                        strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2325                        strainSizer.Add((5,0),0)
2326                    strainSizer.Add((5,0),0)                   
2327                    mainSizer.Add(strainSizer)
2328                elif UseList[item]['Mustrain'][0] == 'generalized':
2329                    strainSizer.Add(wx.StaticText(dataDisplay,-1,' Coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2330                    mainSizer.Add(strainSizer)
2331                    mainSizer.Add((0,5),0)
2332                    Snames = G2spc.MustrainNames(SGData)
2333                    numb = len(Snames)
2334                    if len(UseList[item]['Mustrain'][4]) < numb:
2335                        UseList[item]['Mustrain'][4] = numb*[0.0,]
2336                        UseList[item]['Mustrain'][5] = numb*[False,]
2337                    parms = zip(Snames,UseList[item]['Mustrain'][4],UseList[item]['Mustrain'][5],range(numb))
2338                    strainSizer = wx.FlexGridSizer(numb%3+1,6,5,5)
2339                    for Pa,val,ref,id in parms:
2340                        strainRef = wx.CheckBox(dataDisplay,label=Pa)
2341                        strainRef.SetValue(ref)
2342                        Indx[strainRef.GetId()] = [item,id]
2343                        strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2344                        strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2345                        strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
2346                        Indx[strainVal.GetId()] = [item,id]
2347                        strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2348                        strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2349                        strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2350                    mainSizer.Add(strainSizer)
2351                #MD texture  'MDtexture':[1.0,False,[0,0,1]]
2352                mdSizer = wx.BoxSizer(wx.HORIZONTAL)
2353                mdRef = wx.CheckBox(dataDisplay,label=' March-Dollase texture ratio: ')
2354                mdRef.SetValue(UseList[item]['MDtexture'][1])
2355                Indx[mdRef.GetId()] = item
2356                mdRef.Bind(wx.EVT_CHECKBOX, OnMDRef)
2357                mdSizer.Add(mdRef,0,wx.ALIGN_CENTER_VERTICAL)
2358                mdVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2359                    '%.3f'%(UseList[item]['MDtexture'][0]),style=wx.TE_PROCESS_ENTER)
2360                Indx[mdVal.GetId()] = item
2361                mdVal.Bind(wx.EVT_TEXT_ENTER,OnMDVal)
2362                mdVal.Bind(wx.EVT_KILL_FOCUS,OnMDVal)
2363                mdSizer.Add(mdVal,0,wx.ALIGN_CENTER_VERTICAL)
2364                mdSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2365                h,k,l = UseList[item]['MDtexture'][2]
2366                mdAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2367                Indx[mdAxis.GetId()] = item
2368                mdAxis.Bind(wx.EVT_TEXT_ENTER,OnMDAxis)
2369                mdAxis.Bind(wx.EVT_KILL_FOCUS,OnMDAxis)
2370                mdSizer.Add(mdAxis,0,wx.ALIGN_CENTER_VERTICAL)
2371                mainSizer.Add(mdSizer)
2372                mainSizer.Add((0,5),0)
2373               
2374                #Extinction  'Extinction':[0.0,False]
2375                extSizer = wx.BoxSizer(wx.HORIZONTAL)
2376                extRef = wx.CheckBox(dataDisplay,label=' Extinction: ')
2377                extRef.SetValue(UseList[item]['Extinction'][1])
2378                Indx[extRef.GetId()] = item
2379                extRef.Bind(wx.EVT_CHECKBOX, OnExtRef)
2380                extSizer.Add(extRef,0,wx.ALIGN_CENTER_VERTICAL)
2381                extVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2382                    '%.2f'%(UseList[item]['Extinction'][0]),style=wx.TE_PROCESS_ENTER)
2383                Indx[extVal.GetId()] = item
2384                extVal.Bind(wx.EVT_TEXT_ENTER,OnExtVal)
2385                extVal.Bind(wx.EVT_KILL_FOCUS,OnExtVal)
2386                extSizer.Add(extVal,0,wx.ALIGN_CENTER_VERTICAL)
2387                mainSizer.Add(extSizer)
2388                mainSizer.Add((0,5),0)
2389            elif item[:4] == 'HKLF' and UseList[item]['Show']:
2390                pass
2391        mainSizer.Add((5,5),0)
2392
2393        dataDisplay.SetSizer(mainSizer)
2394        mainSizer.Fit(self.dataFrame)
2395        Size = mainSizer.GetMinSize()
2396        Size[0] += 40
2397        Size[1] = max(Size[1],250) + 20
2398        dataDisplay.SetSize(Size)
2399        DData.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2400        Size[1] = min(Size[1],450)
2401        self.dataFrame.setSizePosLeft(Size)
2402       
2403    def OnHklfAdd(event):
2404        UseList = data['Histograms']
2405        keyList = UseList.keys()
2406        TextList = []
2407        if self.PatternTree.GetCount():
2408            item, cookie = self.PatternTree.GetFirstChild(self.root)
2409            while item:
2410                name = self.PatternTree.GetItemText(item)
2411                if name not in keyList and 'HKLF' in name:
2412                    TextList.append(name)
2413                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)                       
2414            dlg = wx.MultiChoiceDialog(self, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2415            try:
2416                if dlg.ShowModal() == wx.ID_OK:
2417                    result = dlg.GetSelections()
2418                    for i in result:
2419                        histoName = TextList[i]
2420                        UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
2421                            'Extinction':['Lorentzian','Secondary Type I',{'Eg':[0.0,False]},]}                       
2422                    data['Histograms'] = UseList
2423                    UpdateDData()
2424            finally:
2425                dlg.Destroy()
2426       
2427    def OnPwdrAdd(event):
2428        generalData = data['General']
2429        SGData = generalData['SGData']
2430        UseList = data['Histograms']
2431        NShkl = len(G2spc.MustrainNames(SGData))
2432        keyList = UseList.keys()
2433        TextList = []
2434        if self.PatternTree.GetCount():
2435            item, cookie = self.PatternTree.GetFirstChild(self.root)
2436            while item:
2437                name = self.PatternTree.GetItemText(item)
2438                if name not in keyList and 'PWDR' in name:
2439                    TextList.append(name)
2440                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
2441            dlg = wx.MultiChoiceDialog(self, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2442            try:
2443                if dlg.ShowModal() == wx.ID_OK:
2444                    result = dlg.GetSelections()
2445                    for i in result: 
2446                        histoName = TextList[i]
2447                        UseList[histoName] = {'Histogram':histoName,'Show':False,
2448                            'Scale':[1.0,False],'MDtexture':[1.0,False,[0,0,1]],
2449                            'Size':['isotropic',[10000.,0,],[False,False],[0,0,1]],
2450                            'Mustrain':['isotropic',[1.0,0.0],[False,False],[0,0,1],
2451                                NShkl*[0.01,],NShkl*[False,]],                           
2452                            'Extinction':[0.0,False]}
2453                    data['Histograms'] = UseList
2454                    UpdateDData()
2455            finally:
2456                dlg.Destroy()
2457       
2458    def OnDataDelete(event):
2459        UseList = data['Histograms']
2460        keyList = UseList.keys()
2461        keyList.sort()
2462        DelList = []
2463        if UseList:
2464            DelList = []
2465            dlg = wx.MultiChoiceDialog(self, 
2466                'Which histogram to delete from this phase?', 'Delete histogram', 
2467                keyList, wx.CHOICEDLG_STYLE)
2468            try:
2469                if dlg.ShowModal() == wx.ID_OK:
2470                    result = dlg.GetSelections()
2471                    for i in result: DelList.append(keyList[i])
2472                    for i in DelList:
2473                        del UseList[i]
2474                    UpdateDData()
2475            finally:
2476                dlg.Destroy()
2477
2478    def FillPawleyReflectionsGrid():
2479        if data['Histograms']:
2480            self.dataFrame.PawleyMenu.FindItemById(G2gd.wxID_PAWLEYLOAD).Enable(True)
2481            self.dataFrame.PawleyMenu.FindItemById(G2gd.wxID_PAWLEYIMPORT).Enable(True)
2482        else:
2483            self.dataFrame.PawleyMenu.FindItemById(G2gd.wxID_PAWLEYLOAD).Enable(False)
2484            self.dataFrame.PawleyMenu.FindItemById(G2gd.wxID_PAWLEYIMPORT).Enable(False)
2485                       
2486        def KeyEditPawleyGrid(event):
2487            colList = PawleyRefl.GetSelectedCols()
2488            PawleyPeaks = data['Pawley ref']
2489            if event.GetKeyCode() == wx.WXK_RETURN:
2490                event.Skip(True)
2491            elif event.GetKeyCode() == wx.WXK_CONTROL:
2492                event.Skip(True)
2493            elif event.GetKeyCode() == wx.WXK_SHIFT:
2494                event.Skip(True)
2495            elif colList:
2496                PawleyRefl.ClearSelection()
2497                key = event.GetKeyCode()
2498                for col in colList:
2499                    if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
2500                        if key == 89: #'Y'
2501                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True
2502                        elif key == 78:  #'N'
2503                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False
2504                        FillPawleyReflectionsGrid()
2505           
2506        if 'Pawley ref' in data:
2507            PawleyPeaks = data['Pawley ref']                       
2508            rowLabels = []
2509            for i in range(len(PawleyPeaks)): rowLabels.append(str(i+1))
2510            colLabels = ['h','k','l','mul','2-theta','sigma','refine','Iobs','Icalc']
2511            Types = [wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,
2512                wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
2513                wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5']
2514            PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
2515            PawleyRefl.SetTable(PawleyTable, True)
2516            PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid)                 
2517            PawleyRefl.SetMargins(0,0)
2518            PawleyRefl.AutoSizeColumns(False)
2519            self.dataFrame.setSizePosLeft([500,300])
2520                   
2521    def OnPawleyLoad(event):
2522        sig = lambda Th,U,V,W: 1.17741*math.sqrt(U*tand(Th)**2+V*tand(Th)+W)/100.
2523        gam = lambda Th,X,Y: (X/cosd(Th)+Y*tand(Th))/100.
2524        gamFW = lambda s,g: math.sqrt(s**2+(0.4654996*g)**2)+.5345004*#Ubaldo Bafile - private communication
2525        choice = data['Histograms'].keys()
2526        dlg = wx.SingleChoiceDialog(self,'Select','Powder histogram',choice)
2527        if dlg.ShowModal() == wx.ID_OK:
2528            histogram = choice[dlg.GetSelection()]
2529            Id  = G2gd.GetPatternTreeItemId(self, self.root, histogram)
2530            Iparms = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,Id, 'Instrument Parameters'))
2531            try:                                            #try single wavelength
2532                lam = Iparms[1][Iparms[3].index('Lam')]
2533            except ValueError:                              #Ka1 & Ka2 present
2534                lam = Iparms[1][Iparms[3].index('Lam1')]
2535            GU = Iparms[1][Iparms[3].index('U')]               
2536            GV = Iparms[1][Iparms[3].index('V')]               
2537            GW = Iparms[1][Iparms[3].index('W')]               
2538            LX = Iparms[1][Iparms[3].index('X')]               
2539            LY = Iparms[1][Iparms[3].index('Y')]
2540        dlg.Destroy()
2541        generalData = data['General']
2542        dmin = generalData['Pawley dmin']
2543        cell = generalData['Cell'][1:7]
2544        A = G2lat.cell2A(cell)
2545        SGData = generalData['SGData']
2546        Laue = SGData['SGLaue']
2547        SGLatt = SGData['SGLatt']
2548        SGUniq = SGData['SGUniq']       
2549        HKLd = G2lat.GenHLaue(dmin,Laue,SGLatt,SGUniq,A)
2550        PawleyPeaks = []
2551        for h,k,l,d in HKLd:
2552            ext,mul = G2spc.GenHKL([h,k,l],SGData)[:2]
2553            if not ext:
2554                th = asind(lam/(2.0*d))
2555                H = gamFW(sig(th,GU,GV,GW),gam(th,LX,LY))/2.35482
2556                PawleyPeaks.append([h,k,l,mul,2*th,H,False,0,0])
2557        data['Pawley ref'] = PawleyPeaks
2558        FillPawleyReflectionsGrid()
2559               
2560           
2561    def OnPawleyImport(event):
2562        dlg = wx.FileDialog(self, 'Choose file with Pawley reflections', '.', '', 
2563            'GSAS Pawley files (*.RFL)|*.RFL',wx.OPEN)
2564        if self.dirname:
2565            dlg.SetDirectory(self.dirname)
2566        try:
2567            if dlg.ShowModal() == wx.ID_OK:
2568                PawleyFile = dlg.GetPath()
2569                self.dirname = dlg.GetDirectory()
2570                choice = data['Histograms'].keys()
2571                dlg2 = wx.SingleChoiceDialog(self,'Select','Powder histogram',choice)
2572                if dlg2.ShowModal() == wx.ID_OK:
2573                    histogram = choice[dlg2.GetSelection()]
2574                    Id  = G2gd.GetPatternTreeItemId(self, self.root, histogram)
2575                    Iparms = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,Id, 'Instrument Parameters'))
2576                dlg2.Destroy()
2577               
2578                PawleyPeaks = G2IO.GetPawleyPeaks(PawleyFile)
2579                data['Pawley ref'] = PawleyPeaks
2580                FillPawleyReflectionsGrid()
2581        finally:
2582            dlg.Destroy()
2583
2584    def OnPageChanged(event):
2585        page = event.GetSelection()
2586        text = self.dataDisplay.GetPageText(page)
2587        if text == 'Atoms':
2588            self.dataFrame.SetMenuBar(self.dataFrame.AtomsMenu)
2589            self.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
2590            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestAdd, id=G2gd.wxID_ATOMSTESTADD)
2591            self.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
2592            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestInsert, id=G2gd.wxID_ATONTESTINSERT)
2593            self.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
2594            self.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
2595            self.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
2596            self.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
2597            self.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS)
2598            FillAtomsGrid()
2599        elif text == 'General':
2600            UpdateGeneral()
2601            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2602        elif text == 'Data':
2603            self.dataFrame.SetMenuBar(self.dataFrame.DataMenu)
2604            self.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD)
2605            self.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD)
2606            self.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE)
2607            UpdateDData()
2608            G2plt.PlotStrain(self,data)
2609            G2plt.PlotTexture(self,data,newPlot=True)
2610        elif text == 'Draw Options':
2611            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2612            UpdateDrawOptions()
2613            G2plt.PlotStructure(self,data)
2614        elif text == 'Draw Atoms':
2615            self.dataFrame.SetMenuBar(self.dataFrame.DrawAtomsMenu)
2616            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE)
2617            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL)
2618            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR)
2619            self.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR)
2620            self.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT)
2621            self.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV)
2622            self.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM)
2623            self.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD)           
2624            self.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL)
2625            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE)
2626            UpdateDrawAtoms()
2627            G2plt.PlotStructure(self,data)
2628        elif text == 'Pawley/LeBail reflections':
2629            self.dataFrame.SetMenuBar(self.dataFrame.PawleyMenu)
2630            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD)
2631            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyImport, id=G2gd.wxID_PAWLEYIMPORT)
2632            FillPawleyReflectionsGrid()           
2633        else:
2634            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2635        event.Skip()
2636       
2637    General = wx.Window(self.dataDisplay)
2638    self.dataDisplay.AddPage(General,'General')
2639    SetupGeneral()
2640    GeneralData = data['General']
2641    UpdateGeneral()
2642
2643    if GeneralData['Type'] == 'Pawley':
2644        DData = wx.ScrolledWindow(self.dataDisplay)
2645        self.dataDisplay.AddPage(DData,'Data')
2646        PawleyRefl = G2gd.GSGrid(self.dataDisplay)
2647        self.dataDisplay.AddPage(PawleyRefl,'Pawley/LeBail reflections')
2648    else:
2649        DData = wx.ScrolledWindow(self.dataDisplay)
2650        self.dataDisplay.AddPage(DData,'Data')
2651        Atoms = G2gd.GSGrid(self.dataDisplay)
2652        self.dataDisplay.AddPage(Atoms,'Atoms')
2653        drawOptions = wx.Window(self.dataDisplay)
2654        self.dataDisplay.AddPage(drawOptions,'Draw Options')
2655        drawAtoms = G2gd.GSGrid(self.dataDisplay)
2656        self.dataDisplay.AddPage(drawAtoms,'Draw Atoms')
2657
2658    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
2659    self.dataDisplay.SetSelection(oldPage)
2660   
2661           
Note: See TracBrowser for help on using the repository browser.