source: trunk/GSASIIphsGUI.py @ 360

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

just backup before trip

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