source: trunk/GSASIIphsGUI.py @ 345

Last change on this file since 345 was 345, checked in by vondreele, 11 years ago

put new banner in GSASII.BAT
fix for vertical tilt & offset images
speedup of peak calcs
allow change from lam to lam1 & lam2
Pawley refinement fixes

  • Property svn:keywords set to Date Author Revision URL Id
File size: 133.2 KB
Line 
1#GSASII - phase data display routines
2########### SVN repository information ###################
3# $Date: 2011-08-19 01:54:16 +0000 (Fri, 19 Aug 2011) $
4# $Author: vondreele $
5# $Revision: 345 $
6# $URL: trunk/GSASIIphsGUI.py $
7# $Id: GSASIIphsGUI.py 345 2011-08-19 01:54:16Z 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,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 UpdateDData():
1846        UseList = data['Histograms']
1847        if UseList:
1848            self.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,True)
1849        else:
1850            self.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,False)           
1851        generalData = data['General']       
1852        SGData = generalData['SGData']
1853        try:
1854            textureData = generalData['SH Texture']
1855        except KeyError:            #fix old files!
1856            textureData = generalData['SH Texture'] = {'Order':0,'Model':'cylindrical',
1857                'Sample omega':[False,0.0],'Sample chi':[False,0.0],'Sample phi':[False,0.0],
1858                'SH Coeff':[False,{}],'SHShow':False,'PFhkl':[0,0,1],
1859                'PFxyz':[0,0,1.],'PlotType':'Pole figure'}
1860        if 'SHShow' not in textureData:     #another fix
1861            textureData.update({'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
1862        try:                        #another fix!
1863            x = textureData['PlotType']
1864        except KeyError:
1865            textureData.update({'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
1866        shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
1867        SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
1868       
1869        shAngles = ['omega','chi','phi']
1870        keyList = UseList.keys()
1871        keyList.sort()
1872        Indx = {}
1873       
1874        def SetSHCoef():
1875            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],SamSym[textureData['Model']],textureData['Order'])
1876            newSHCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
1877            SHCoeff = textureData['SH Coeff'][1]
1878            for cofName in SHCoeff:
1879                if cofName in  cofNames:
1880                    newSHCoef[cofName] = SHCoeff[cofName]
1881            return newSHCoef
1882       
1883        def OnShOrder(event):
1884            textureData['Order'] = int(shOrder.GetValue())
1885            textureData['SH Coeff'][1] = SetSHCoef()
1886            UpdateDData()
1887            G2plt.PlotTexture(self,data,newPlot=False)
1888                       
1889        def OnShModel(event):
1890            textureData['Model'] = shModel.GetValue()
1891            textureData['SH Coeff'][1] = SetSHCoef()
1892            UpdateDData()
1893            G2plt.PlotTexture(self,data,newPlot=False)
1894           
1895        def OnSHRefine(event):
1896            textureData['SH Coeff'][0] = shRef.GetValue()
1897           
1898        def OnSHShow(event):
1899            textureData['SHShow'] = shShow.GetValue()
1900            UpdateDData()
1901           
1902        def OnProjSel(event):
1903            self.Projection = projSel.GetValue()
1904            G2plt.PlotTexture(self,data,newPlot=False)
1905           
1906        def OnColorSel(event):
1907            self.ContourColor = colorSel.GetValue()
1908            G2plt.PlotTexture(self,data,newPlot=False)
1909           
1910        def OnAngRef(event):
1911            Obj = event.GetEventObject()
1912            textureData[angIndx[Obj.GetId()]][0] = Obj.GetValue()
1913           
1914        def OnAngValue(event):
1915            Obj = event.GetEventObject()
1916            try:
1917                value =  float(Obj.GetValue())
1918            except ValueError:
1919                value = textureData[valIndx[Obj.GetId()]][1]
1920            Obj.SetValue('%8.2f'%(value))
1921            textureData[valIndx[Obj.GetId()]][1] = value
1922           
1923        def OnODFValue(event): 
1924            Obj = event.GetEventObject()
1925            try:
1926                value =  float(Obj.GetValue())
1927            except ValueError:
1928                value = textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]]
1929            Obj.SetValue('%8.3f'%(value))
1930            textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] = value
1931            G2plt.PlotTexture(self,data,newPlot=False)
1932           
1933        def OnPfType(event):
1934            textureData['PlotType'] = pfType.GetValue()
1935            UpdateDData()
1936            G2plt.PlotTexture(self,data)
1937           
1938        def OnPFValue(event):
1939            Obj = event.GetEventObject()
1940            if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
1941                try:
1942                    value = '['+Obj.GetValue()+']'
1943                    hkl = eval(value)
1944                except:
1945                    value = str(textureData['PFhkl'])
1946                    hkl = eval(value)
1947                Obj.SetValue('%d,%d,%d'%(hkl[0],hkl[1],hkl[2]))
1948                textureData['PFhkl'] = hkl
1949            else:
1950                try:
1951                    value =  '['+Obj.GetValue()+']'
1952                    xyz = eval(value)
1953                except:
1954                    value = str(textureData['PFhkl'])
1955                    xyz = eval(value)
1956                Obj.SetValue('%3.1f,%3.1f,%3.1f'%(xyz[0],xyz[1],xyz[2]))
1957                textureData['PFxyz'] = xyz
1958            G2plt.PlotTexture(self,data)
1959       
1960        def OnShowData(event):
1961            Obj = event.GetEventObject()
1962            hist = Indx[Obj.GetId()]
1963            UseList[hist]['Show'] = Obj.GetValue()
1964            UpdateDData()
1965            G2plt.PlotStrain(self,data)
1966           
1967        def OnScaleRef(event):
1968            Obj = event.GetEventObject()
1969            UseList[Indx[Obj.GetId()]]['Scale'][1] = Obj.GetValue()
1970           
1971        def OnScaleVal(event):
1972            Obj = event.GetEventObject()
1973            try:
1974                scale = float(Obj.GetValue())
1975                if scale > 0:
1976                    UseList[Indx[Obj.GetId()]]['Scale'][0] = scale
1977            except ValueError:
1978                pass
1979            Obj.SetValue("%.4f"%(UseList[Indx[Obj.GetId()]]['Scale'][0]))          #reset in case of error
1980           
1981        def OnSizeType(event):
1982            Obj = event.GetEventObject()
1983            hist = Indx[Obj.GetId()]
1984            UseList[hist]['Size'][0] = Obj.GetValue()
1985            UpdateDData()
1986           
1987        def OnSizeRef(event):
1988            Obj = event.GetEventObject()
1989            hist,pid = Indx[Obj.GetId()]
1990            if UseList[hist]['Size'][0] == 'ellipsoidal':
1991                UseList[hist]['Size'][5][pid] = Obj.GetValue()               
1992            else:
1993                UseList[hist]['Size'][2][pid] = Obj.GetValue()
1994           
1995        def OnSizeVal(event):
1996            Obj = event.GetEventObject()
1997            hist,pid = Indx[Obj.GetId()]
1998            if UseList[hist]['Size'][0] == 'ellipsoidal':
1999                try:
2000                    size = float(Obj.GetValue())
2001                    if pid < 3 and size <= 0.01:            #10A lower limit!
2002                        raise ValueError                   
2003                except ValueError:
2004                    pass
2005            else:
2006                try:
2007                    size = float(Obj.GetValue())
2008                    if size <= 0.01:            #10A lower limit!
2009                        raise ValueError
2010                    UseList[hist]['Size'][1][pid] = size
2011                except ValueError:
2012                    pass
2013            Obj.SetValue("%.1f"%(UseList[hist]['Size'][1][pid]))          #reset in case of error
2014           
2015        def OnSizeAxis(event):           
2016            Obj = event.GetEventObject()
2017            hist = Indx[Obj.GetId()]
2018            Saxis = Obj.GetValue().split()
2019            try:
2020                hkl = [int(Saxis[i]) for i in range(3)]
2021            except (ValueError,IndexError):
2022                hkl = UseList[hist]['Size'][3]
2023            if not np.any(np.array(hkl)):
2024                hkl = UseList[hist]['Size'][3]
2025            UseList[hist]['Size'][3] = hkl
2026            h,k,l = hkl
2027            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2028                       
2029        def OnStrainType(event):
2030            Obj = event.GetEventObject()
2031            hist = Indx[Obj.GetId()]
2032            UseList[hist]['Mustrain'][0] = Obj.GetValue()
2033            UpdateDData()
2034            G2plt.PlotStrain(self,data)
2035           
2036        def OnStrainRef(event):
2037            Obj = event.GetEventObject()
2038            hist,pid = Indx[Obj.GetId()]
2039            if UseList[hist]['Mustrain'][0] == 'generalized':
2040                UseList[hist]['Mustrain'][5][pid] = Obj.GetValue()
2041            else:
2042                UseList[hist]['Mustrain'][2][pid] = Obj.GetValue()
2043           
2044        def OnStrainVal(event):
2045            Snames = G2spc.MustrainNames(SGData)
2046            Obj = event.GetEventObject()
2047            hist,pid = Indx[Obj.GetId()]
2048            try:
2049                strain = float(Obj.GetValue())
2050                if UseList[hist]['Mustrain'][0] == 'generalized':
2051                    if '4' in Snames[pid] and strain < 0:
2052                        raise ValueError
2053                    UseList[hist]['Mustrain'][4][pid] = strain
2054                else:
2055                    if strain <= 0:
2056                        raise ValueError
2057                    UseList[hist]['Mustrain'][1][pid] = strain
2058            except ValueError:
2059                pass
2060            if UseList[hist]['Mustrain'][0] == 'generalized':
2061                Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][4][pid]))          #reset in case of error
2062            else:
2063                Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][1][pid]))          #reset in case of error
2064            G2plt.PlotStrain(self,data)
2065           
2066        def OnStrainAxis(event):
2067            Obj = event.GetEventObject()
2068            hist = Indx[Obj.GetId()]
2069            Saxis = Obj.GetValue().split()
2070            try:
2071                hkl = [int(Saxis[i]) for i in range(3)]
2072            except (ValueError,IndexError):
2073                hkl = UseList[hist]['Mustrain'][3]
2074            if not np.any(np.array(hkl)):
2075                hkl = UseList[hist]['Mustrain'][3]
2076            UseList[hist]['Mustrain'][3] = hkl
2077            h,k,l = hkl
2078            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2079            G2plt.PlotStrain(self,data)
2080           
2081        def OnPOType(event):
2082            Obj = event.GetEventObject()
2083            hist = Indx[Obj.GetId()]
2084            if 'March' in POType.GetValue():
2085                UseList[hist]['Pref.Ori.'][0] = 'MD'
2086            else:
2087                UseList[hist]['Pref.Ori.'][0] = 'SH'
2088            UpdateDData()           
2089
2090        def OnPORef(event):
2091            Obj = event.GetEventObject()
2092            hist = Indx[Obj.GetId()]
2093            UseList[hist]['Pref.Ori.'][2] = Obj.GetValue()
2094           
2095        def OnPOVal(event):
2096            Obj = event.GetEventObject()
2097            hist = Indx[Obj.GetId()]
2098            try:
2099                mdVal = float(Obj.GetValue())
2100                if mdVal > 0:
2101                    UseList[hist]['Pref.Ori.'][1] = mdVal
2102            except ValueError:
2103                pass
2104            Obj.SetValue("%.3f"%(UseList[hist]['Pref.Ori.'][1]))          #reset in case of error
2105           
2106        def OnPOAxis(event):
2107            Obj = event.GetEventObject()
2108            hist = Indx[Obj.GetId()]
2109            Saxis = Obj.GetValue().split()
2110            try:
2111                hkl = [int(Saxis[i]) for i in range(3)]
2112            except (ValueError,IndexError):
2113                hkl = UseList[hist]['Pref.Ori.'][3]
2114            if not np.any(np.array(hkl)):
2115                hkl = UseList[hist]['Pref.Ori.'][3]
2116            UseList[hist]['Pref.Ori.'][3] = hkl
2117            h,k,l = hkl
2118            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2119           
2120        def OnPOOrder(event):
2121            Obj = event.GetEventObject()
2122            hist = Indx[Obj.GetId()]
2123            Order = int(Obj.GetValue())
2124            UseList[hist]['Pref.Ori.'][4] = Order
2125            UseList[hist]['Pref.Ori.'][5] = SetPOCoef(Order,hist)
2126            UpdateDData()
2127
2128        def SetPOCoef(Order,hist):
2129            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],None,Order)     #cylindrical sample symmetry
2130            newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
2131            POCoeff = UseList[hist]['Pref.Ori.'][5]
2132            for cofName in POCoeff:
2133                if cofName in  cofNames:
2134                    newPOCoef[cofName] = POCoeff[cofName]
2135            return newPOCoef
2136       
2137        def OnExtRef(event):
2138            Obj = event.GetEventObject()
2139            UseList[Indx[Obj.GetId()]]['Extinction'][1] = Obj.GetValue()
2140           
2141        def OnExtVal(event):
2142            Obj = event.GetEventObject()
2143            try:
2144                ext = float(Obj.GetValue())
2145                if ext >= 0:
2146                    UseList[Indx[Obj.GetId()]]['Extinction'][0] = ext
2147            except ValueError:
2148                pass
2149            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][0]))          #reset in case of error
2150           
2151        def checkAxis(axis):
2152            if not np.any(np.array(axis)):
2153                return False
2154            return axis
2155           
2156        DData.DestroyChildren()
2157        dataDisplay = wx.Panel(DData)
2158        mainSizer = wx.BoxSizer(wx.VERTICAL)
2159        titleSizer = wx.BoxSizer(wx.HORIZONTAL)
2160        titleSizer.Add(wx.StaticText(dataDisplay,-1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2161        titleSizer.Add(wx.StaticText(dataDisplay,-1,
2162            ' Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))),
2163            0,wx.ALIGN_CENTER_VERTICAL)
2164        mainSizer.Add(titleSizer,0)
2165        mainSizer.Add((0,5),0)
2166        shSizer = wx.BoxSizer(wx.HORIZONTAL)
2167        shSizer.Add(wx.StaticText(dataDisplay,-1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL)
2168        shModel = wx.ComboBox(dataDisplay,-1,value=textureData['Model'],choices=shModels,
2169            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2170        shModel.Bind(wx.EVT_COMBOBOX,OnShModel)
2171        shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL)
2172        shSizer.Add(wx.StaticText(dataDisplay,-1,'  Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2173        shOrder = wx.ComboBox(dataDisplay,-1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)],
2174            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2175        shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder)
2176        shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL)
2177        if textureData['Order']:
2178            shSizer.Add((5,0),0)
2179            shRef = wx.CheckBox(dataDisplay,label=' Refine texture?')
2180            shRef.SetValue(textureData['SH Coeff'][0])
2181            shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine)
2182            shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL)
2183            shShow = wx.CheckBox(dataDisplay,label=' Show coeff.?')
2184            shShow.SetValue(textureData['SHShow'])
2185            shShow.Bind(wx.EVT_CHECKBOX, OnSHShow)
2186            shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL)
2187            mainSizer.Add(shSizer,0,0)
2188            mainSizer.Add((0,5),0)
2189            PTSizer = wx.FlexGridSizer(2,4,5,5)
2190            PTSizer.Add(wx.StaticText(dataDisplay,-1,' Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL)
2191            choices = ['Axial pole distribution','Pole figure','Inverse pole figure']           
2192            pfType = wx.ComboBox(dataDisplay,-1,value=str(textureData['PlotType']),choices=choices,
2193                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2194            pfType.Bind(wx.EVT_COMBOBOX,OnPfType)
2195            PTSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL)
2196            PTSizer.Add(wx.StaticText(dataDisplay,-1,' Projection type: '),0,wx.ALIGN_CENTER_VERTICAL)
2197            projSel = wx.ComboBox(dataDisplay,-1,value=self.Projection,choices=['equal area','stereographic'],
2198                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2199            projSel.Bind(wx.EVT_COMBOBOX,OnProjSel)
2200            PTSizer.Add(projSel,0,wx.ALIGN_CENTER_VERTICAL)
2201            if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
2202                PTSizer.Add(wx.StaticText(dataDisplay,-1,' Pole figure HKL: '),0,wx.ALIGN_CENTER_VERTICAL)
2203                PH = textureData['PFhkl']
2204                pfVal = wx.TextCtrl(dataDisplay,-1,'%d,%d,%d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER)
2205            else:
2206                PTSizer.Add(wx.StaticText(dataDisplay,-1,' Inverse pole figure XYZ: '),0,wx.ALIGN_CENTER_VERTICAL)
2207                PX = textureData['PFxyz']
2208                pfVal = wx.TextCtrl(dataDisplay,-1,'%3.1f,%3.1f,%3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER)
2209            pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue)
2210            pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue)
2211            PTSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL)
2212            PTSizer.Add(wx.StaticText(dataDisplay,-1,' Color scheme'),0,wx.ALIGN_CENTER_VERTICAL)
2213            choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
2214            choice.sort()
2215            colorSel = wx.ComboBox(dataDisplay,-1,value=self.ContourColor,choices=choice,
2216                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2217            colorSel.Bind(wx.EVT_COMBOBOX,OnColorSel)
2218            PTSizer.Add(colorSel,0,wx.ALIGN_CENTER_VERTICAL)       
2219            mainSizer.Add(PTSizer,0,wx.ALIGN_CENTER_VERTICAL)
2220           
2221            mainSizer.Add((0,5),0)
2222            if textureData['SHShow']:
2223                mainSizer.Add(wx.StaticText(dataDisplay,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2224                mainSizer.Add((0,5),0)
2225                ODFSizer = wx.FlexGridSizer(2,8,2,2)
2226                ODFIndx = {}
2227                ODFkeys = textureData['SH Coeff'][1].keys()
2228                ODFkeys.sort()
2229                for item in ODFkeys:
2230                    ODFSizer.Add(wx.StaticText(dataDisplay,-1,item),0,wx.ALIGN_CENTER_VERTICAL)
2231                    ODFval = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER)
2232                    ODFIndx[ODFval.GetId()] = item
2233                    ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2234                    ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2235                    ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2236                mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2237                mainSizer.Add((0,5),0)
2238            mainSizer.Add((0,5),0)
2239            mainSizer.Add(wx.StaticText(dataDisplay,-1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL)
2240            mainSizer.Add((0,5),0)
2241            angSizer = wx.BoxSizer(wx.HORIZONTAL)
2242            angIndx = {}
2243            valIndx = {}
2244            for item in ['Sample omega','Sample chi','Sample phi']:
2245                angRef = wx.CheckBox(dataDisplay,label=item+': ')
2246                angRef.SetValue(textureData[item][0])
2247                angIndx[angRef.GetId()] = item
2248                angRef.Bind(wx.EVT_CHECKBOX, OnAngRef)
2249                angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL)
2250                angVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER)
2251                valIndx[angVal.GetId()] = item
2252                angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue)
2253                angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue)
2254                angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL)
2255                angSizer.Add((5,0),0)
2256            mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL)
2257        else:  #finish the texture output when order = 0
2258            mainSizer.Add(shSizer,0,0)
2259            mainSizer.Add((0,5),0)           
2260        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Histogram data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2261        for item in keyList:
2262            histData = UseList[item]
2263            mainSizer.Add((5,5),0)
2264            showData = wx.CheckBox(dataDisplay,label=' Show '+item)
2265            showData.SetValue(UseList[item]['Show'])
2266            Indx[showData.GetId()] = item
2267            showData.Bind(wx.EVT_CHECKBOX, OnShowData)
2268            mainSizer.Add(showData,0,wx.ALIGN_CENTER_VERTICAL)
2269            mainSizer.Add((0,5),0)
2270            if UseList[item]['Show']:
2271                scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
2272                scaleRef = wx.CheckBox(dataDisplay,label=' Phase fraction: ')
2273                scaleRef.SetValue(UseList[item]['Scale'][1])
2274                Indx[scaleRef.GetId()] = item
2275                scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
2276                scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
2277                scaleVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2278                    '%.4f'%(UseList[item]['Scale'][0]),style=wx.TE_PROCESS_ENTER)
2279                Indx[scaleVal.GetId()] = item
2280                scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
2281                scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
2282                scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
2283                mainSizer.Add(scaleSizer)
2284                mainSizer.Add((0,5),0)
2285               
2286            if item[:4] == 'PWDR' and UseList[item]['Show']:
2287                mainSizer.Add((0,5),0)
2288                sizeSizer = wx.BoxSizer(wx.HORIZONTAL)
2289                sizeSizer.Add(wx.StaticText(dataDisplay,-1,' Size model: '),0,wx.ALIGN_CENTER_VERTICAL)
2290                choices = ['isotropic','uniaxial','ellipsoidal']
2291                sizeType = wx.ComboBox(dataDisplay,wx.ID_ANY,value=UseList[item]['Size'][0],choices=choices,
2292                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2293                sizeType.Bind(wx.EVT_COMBOBOX, OnSizeType)
2294                Indx[sizeType.GetId()] = item
2295                sizeSizer.Add(sizeType)
2296                sizeSizer.Add((5,0),0)
2297                if UseList[item]['Size'][0] == 'isotropic':
2298                    sizeRef = wx.CheckBox(dataDisplay,label=' Cryst. size: ')
2299                    sizeRef.SetValue(UseList[item]['Size'][2][0])
2300                    Indx[sizeRef.GetId()] = [item,0]
2301                    sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2302                    sizeSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2303                    sizeVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2304                        '%.1f'%(UseList[item]['Size'][1][0]),style=wx.TE_PROCESS_ENTER)
2305                    Indx[sizeVal.GetId()] = [item,0]
2306                    sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2307                    sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2308                    sizeSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2309                    mainSizer.Add(sizeSizer)
2310                    mainSizer.Add((0,5),0)
2311                elif UseList[item]['Size'][0] == 'uniaxial':
2312                    sizeSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2313                    h,k,l = UseList[item]['Size'][3]
2314                    sizeAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2315                    Indx[sizeAxis.GetId()] = item
2316                    sizeAxis.Bind(wx.EVT_TEXT_ENTER,OnSizeAxis)
2317                    sizeAxis.Bind(wx.EVT_KILL_FOCUS,OnSizeAxis)
2318                    sizeSizer.Add(sizeAxis,0,wx.ALIGN_CENTER_VERTICAL)
2319                    mainSizer.Add(sizeSizer)
2320                    mainSizer.Add((0,5),0)
2321                    sizeSizer = wx.BoxSizer(wx.HORIZONTAL)
2322                    parms = zip([' Equatorial size: ',' Axial size: '],UseList[item]['Size'][1],
2323                        UseList[item]['Size'][2],range(2))
2324                    for Pa,val,ref,id in parms:
2325                        sizeRef = wx.CheckBox(dataDisplay,label=Pa)
2326                        sizeRef.SetValue(ref)
2327                        Indx[sizeRef.GetId()] = [item,id]
2328                        sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2329                        sizeSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2330                        sizeVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.1f'%(val),style=wx.TE_PROCESS_ENTER)
2331                        Indx[sizeVal.GetId()] = [item,id]
2332                        sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2333                        sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2334                        sizeSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2335                        sizeSizer.Add((5,0),0)
2336                    sizeSizer.Add((5,0),0)                   
2337                    mainSizer.Add(sizeSizer)
2338                elif UseList[item]['Size'][0] == 'ellipsoidal':
2339                    mainSizer.Add(sizeSizer)
2340                    mainSizer.Add((0,5),0)
2341                    sizeSizer = wx.BoxSizer(wx.HORIZONTAL)
2342                    parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[item]['Size'][4],
2343                        UseList[item]['Size'][5],range(6))
2344                    for Pa,val,ref,id in parms:
2345                        sizeRef = wx.CheckBox(dataDisplay,label=Pa)
2346                        sizeRef.SetValue(ref)
2347                        Indx[sizeRef.GetId()] = [item,id]
2348                        sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2349                        sizeSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2350                        sizeVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.1f'%(val),style=wx.TE_PROCESS_ENTER)
2351                        Indx[sizeVal.GetId()] = [item,id]
2352                        sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2353                        sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2354                        sizeSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2355                        sizeSizer.Add((5,0),0)
2356                    sizeSizer.Add((5,0),0)                   
2357                    mainSizer.Add(sizeSizer)
2358               
2359                strainSizer = wx.BoxSizer(wx.HORIZONTAL)
2360                strainSizer.Add(wx.StaticText(dataDisplay,-1,' Mustrain model: '),0,wx.ALIGN_CENTER_VERTICAL)
2361                choices = ['isotropic','uniaxial','generalized',]
2362                strainType = wx.ComboBox(dataDisplay,wx.ID_ANY,value=UseList[item]['Mustrain'][0],choices=choices,
2363                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2364                strainType.Bind(wx.EVT_COMBOBOX, OnStrainType)
2365                Indx[strainType.GetId()] = item
2366                strainSizer.Add(strainType)
2367                strainSizer.Add((5,0),0)
2368                if UseList[item]['Mustrain'][0] == 'isotropic':
2369                    strainRef = wx.CheckBox(dataDisplay,label=' microstrain: ')
2370                    strainRef.SetValue(UseList[item]['Mustrain'][2][0])
2371                    Indx[strainRef.GetId()] = [item,0]
2372                    strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2373                    strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2374                    strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2375                        '%.3f'%(UseList[item]['Mustrain'][1][0]),style=wx.TE_PROCESS_ENTER)
2376                    Indx[strainVal.GetId()] = [item,0]
2377                    strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2378                    strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2379                    strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2380                    mainSizer.Add(strainSizer)
2381                    mainSizer.Add((0,5),0)
2382                elif UseList[item]['Mustrain'][0] == 'uniaxial':
2383                    strainSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2384                    h,k,l = UseList[item]['Mustrain'][3]
2385                    strAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2386                    Indx[strAxis.GetId()] = item
2387                    strAxis.Bind(wx.EVT_TEXT_ENTER,OnStrainAxis)
2388                    strAxis.Bind(wx.EVT_KILL_FOCUS,OnStrainAxis)
2389                    strainSizer.Add(strAxis,0,wx.ALIGN_CENTER_VERTICAL)
2390                    mainSizer.Add(strainSizer)
2391                    mainSizer.Add((0,5),0)
2392                    strainSizer = wx.BoxSizer(wx.HORIZONTAL)
2393                    parms = zip([' Equatorial mustrain: ',' Axial mustrain: '],
2394                        UseList[item]['Mustrain'][1],UseList[item]['Mustrain'][2],range(2))
2395                    for Pa,val,ref,id in parms:
2396                        strainRef = wx.CheckBox(dataDisplay,label=Pa)
2397                        strainRef.SetValue(ref)
2398                        Indx[strainRef.GetId()] = [item,id]
2399                        strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2400                        strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2401                        strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER)
2402                        Indx[strainVal.GetId()] = [item,id]
2403                        strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2404                        strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2405                        strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2406                        strainSizer.Add((5,0),0)
2407                    strainSizer.Add((5,0),0)                   
2408                    mainSizer.Add(strainSizer)
2409                elif UseList[item]['Mustrain'][0] == 'generalized':
2410                    strainSizer.Add(wx.StaticText(dataDisplay,-1,' Coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2411                    mainSizer.Add(strainSizer)
2412                    mainSizer.Add((0,5),0)
2413                    Snames = G2spc.MustrainNames(SGData)
2414                    numb = len(Snames)
2415                    if len(UseList[item]['Mustrain'][4]) < numb:
2416                        UseList[item]['Mustrain'][4] = numb*[0.0,]
2417                        UseList[item]['Mustrain'][5] = numb*[False,]
2418                    parms = zip(Snames,UseList[item]['Mustrain'][4],UseList[item]['Mustrain'][5],range(numb))
2419                    strainSizer = wx.FlexGridSizer(numb%3+1,6,5,5)
2420                    for Pa,val,ref,id in parms:
2421                        strainRef = wx.CheckBox(dataDisplay,label=Pa)
2422                        strainRef.SetValue(ref)
2423                        Indx[strainRef.GetId()] = [item,id]
2424                        strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2425                        strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2426                        strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
2427                        Indx[strainVal.GetId()] = [item,id]
2428                        strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2429                        strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2430                        strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2431                    mainSizer.Add(strainSizer)
2432                #texture  'Pref. Ori.':['MD',1.0,False,[0,0,1],0,[]] last two for 'SH' are SHorder & coeff
2433#                poSizer = wx.BoxSizer(wx.HORIZONTAL)
2434                poSizer = wx.FlexGridSizer(1,6,5,5)
2435                POData = UseList[item]['Pref.Ori.']
2436                choice = ['March-Dollase','Spherical harmonics']
2437                POtype = choice[['MD','SH'].index(POData[0])]
2438                poSizer.Add(wx.StaticText(dataDisplay,-1,' Preferred orientation model '),0,wx.ALIGN_CENTER_VERTICAL)
2439                POType = wx.ComboBox(dataDisplay,wx.ID_ANY,value=POtype,choices=choice,
2440                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2441                Indx[POType.GetId()] = item
2442                POType.Bind(wx.EVT_COMBOBOX, OnPOType)
2443                poSizer.Add(POType)
2444                if POData[0] == 'MD':
2445                    mainSizer.Add(poSizer)
2446                    poSizer = wx.BoxSizer(wx.HORIZONTAL)
2447                    poRef = wx.CheckBox(dataDisplay,label=' March-Dollase ratio: ')
2448                    poRef.SetValue(POData[2])
2449                    Indx[poRef.GetId()] = item
2450                    poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
2451                    poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
2452                    poVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2453                        '%.3f'%(POData[1]),style=wx.TE_PROCESS_ENTER)
2454                    Indx[poVal.GetId()] = item
2455                    poVal.Bind(wx.EVT_TEXT_ENTER,OnPOVal)
2456                    poVal.Bind(wx.EVT_KILL_FOCUS,OnPOVal)
2457                    poSizer.Add(poVal,0,wx.ALIGN_CENTER_VERTICAL)
2458                    poSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2459                    h,k,l =POData[3]
2460                    poAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2461                    Indx[poAxis.GetId()] = item
2462                    poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOAxis)
2463                    poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOAxis)
2464                    poSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
2465                    mainSizer.Add(poSizer)
2466                else:           #'SH'
2467                    poSizer.Add(wx.StaticText(dataDisplay,-1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2468                    poOrder = wx.ComboBox(dataDisplay,wx.ID_ANY,value=str(POData[4]),choices=[str(2*i) for i in range(18)],
2469                        style=wx.CB_READONLY|wx.CB_DROPDOWN)
2470                    Indx[poOrder.GetId()] = item
2471                    poOrder.Bind(wx.EVT_COMBOBOX,OnPOOrder)
2472                    poSizer.Add(poOrder,0,wx.ALIGN_CENTER_VERTICAL)
2473                    poRef = wx.CheckBox(dataDisplay,label=' Refine? ')
2474                    poRef.SetValue(POData[2])
2475                    Indx[poRef.GetId()] = item
2476                    poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
2477                    poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
2478                    mainSizer.Add(poSizer)
2479                    if POData[4]:
2480                        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2481                        mainSizer.Add((0,5),0)
2482                        ODFSizer = wx.FlexGridSizer(2,8,2,2)
2483                        ODFIndx = {}
2484                        ODFkeys = POData[5].keys()
2485                        ODFkeys.sort()
2486                        for odf in ODFkeys:
2487                            ODFSizer.Add(wx.StaticText(dataDisplay,-1,odf),0,wx.ALIGN_CENTER_VERTICAL)
2488                            ODFval = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%8.3f'%(POData[5][odf]),style=wx.TE_PROCESS_ENTER)
2489                            ODFIndx[ODFval.GetId()] = odf
2490    #                        ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2491    #                        ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2492                            ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2493                        mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2494                        mainSizer.Add((0,5),0)
2495                mainSizer.Add((0,5),0)               
2496                #Extinction  'Extinction':[0.0,False]
2497                extSizer = wx.BoxSizer(wx.HORIZONTAL)
2498                extRef = wx.CheckBox(dataDisplay,label=' Extinction: ')
2499                extRef.SetValue(UseList[item]['Extinction'][1])
2500                Indx[extRef.GetId()] = item
2501                extRef.Bind(wx.EVT_CHECKBOX, OnExtRef)
2502                extSizer.Add(extRef,0,wx.ALIGN_CENTER_VERTICAL)
2503                extVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2504                    '%.2f'%(UseList[item]['Extinction'][0]),style=wx.TE_PROCESS_ENTER)
2505                Indx[extVal.GetId()] = item
2506                extVal.Bind(wx.EVT_TEXT_ENTER,OnExtVal)
2507                extVal.Bind(wx.EVT_KILL_FOCUS,OnExtVal)
2508                extSizer.Add(extVal,0,wx.ALIGN_CENTER_VERTICAL)
2509                mainSizer.Add(extSizer)
2510                mainSizer.Add((0,5),0)
2511            elif item[:4] == 'HKLF' and UseList[item]['Show']:
2512                pass
2513        mainSizer.Add((5,5),0)
2514
2515        dataDisplay.SetSizer(mainSizer)
2516        mainSizer.Fit(self.dataFrame)
2517        Size = mainSizer.GetMinSize()
2518        Size[0] += 40
2519        Size[1] = max(Size[1],250) + 20
2520        dataDisplay.SetSize(Size)
2521        DData.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2522        Size[1] = min(Size[1],450)
2523        self.dataFrame.setSizePosLeft(Size)
2524       
2525    def OnHklfAdd(event):
2526        UseList = data['Histograms']
2527        keyList = UseList.keys()
2528        TextList = []
2529        if self.PatternTree.GetCount():
2530            item, cookie = self.PatternTree.GetFirstChild(self.root)
2531            while item:
2532                name = self.PatternTree.GetItemText(item)
2533                if name not in keyList and 'HKLF' in name:
2534                    TextList.append(name)
2535                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)                       
2536            dlg = wx.MultiChoiceDialog(self, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2537            try:
2538                if dlg.ShowModal() == wx.ID_OK:
2539                    result = dlg.GetSelections()
2540                    for i in result:
2541                        histoName = TextList[i]
2542                        UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
2543                            'Extinction':['Lorentzian','Secondary Type I',{'Eg':[0.0,False]},]}                       
2544                    data['Histograms'] = UseList
2545                    UpdateDData()
2546            finally:
2547                dlg.Destroy()
2548       
2549    def OnPwdrAdd(event):
2550        generalData = data['General']
2551        SGData = generalData['SGData']
2552        UseList = data['Histograms']
2553        NShkl = len(G2spc.MustrainNames(SGData))
2554        keyList = UseList.keys()
2555        TextList = []
2556        if self.PatternTree.GetCount():
2557            item, cookie = self.PatternTree.GetFirstChild(self.root)
2558            while item:
2559                name = self.PatternTree.GetItemText(item)
2560                if name not in keyList and 'PWDR' in name:
2561                    TextList.append(name)
2562                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
2563            dlg = wx.MultiChoiceDialog(self, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2564            try:
2565                if dlg.ShowModal() == wx.ID_OK:
2566                    result = dlg.GetSelections()
2567                    for i in result: 
2568                        histoName = TextList[i]
2569                        pId = G2gd.GetPatternTreeItemId(self,self.root,histoName)
2570                        UseList[histoName] = {'Histogram':histoName,'Show':False,
2571                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{}],
2572                            'Size':['isotropic',[10.,10.,],[False,False],[0,0,1],6*[0.0,],6*[False,]],
2573                            'Mustrain':['isotropic',[1.0,1.0],[False,False],[0,0,1],
2574                                NShkl*[0.01,],NShkl*[False,]],                           
2575                            'Extinction':[0.0,False]}
2576                        refList = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,pId,'Reflection Lists'))
2577                        refList[generalData['Name']] = []                       
2578                    data['Histograms'] = UseList
2579                    UpdateDData()
2580            finally:
2581                dlg.Destroy()
2582       
2583    def OnDataDelete(event):
2584        UseList = data['Histograms']
2585        keyList = UseList.keys()
2586        keyList.sort()
2587        DelList = []
2588        if UseList:
2589            DelList = []
2590            dlg = wx.MultiChoiceDialog(self, 
2591                'Which histogram to delete from this phase?', 'Delete histogram', 
2592                keyList, wx.CHOICEDLG_STYLE)
2593            try:
2594                if dlg.ShowModal() == wx.ID_OK:
2595                    result = dlg.GetSelections()
2596                    for i in result: DelList.append(keyList[i])
2597                    for i in DelList:
2598                        del UseList[i]
2599                    UpdateDData()
2600            finally:
2601                dlg.Destroy()
2602
2603    def FillPawleyReflectionsGrid():
2604                       
2605        def KeyEditPawleyGrid(event):
2606            colList = self.PawleyRefl.GetSelectedCols()
2607            PawleyPeaks = data['Pawley ref']
2608            if event.GetKeyCode() == wx.WXK_RETURN:
2609                event.Skip(True)
2610            elif event.GetKeyCode() == wx.WXK_CONTROL:
2611                event.Skip(True)
2612            elif event.GetKeyCode() == wx.WXK_SHIFT:
2613                event.Skip(True)
2614            elif colList:
2615                self.PawleyRefl.ClearSelection()
2616                key = event.GetKeyCode()
2617                for col in colList:
2618                    if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
2619                        if key == 89: #'Y'
2620                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True
2621                        elif key == 78:  #'N'
2622                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False
2623                        FillPawleyReflectionsGrid()
2624           
2625        if 'Pawley ref' in data:
2626            PawleyPeaks = data['Pawley ref']                       
2627            rowLabels = []
2628            for i in range(len(PawleyPeaks)): rowLabels.append(str(i+1))
2629            colLabels = ['h','k','l','mul','d','refine','Fsq(hkl)','sig(Fsq)']
2630            Types = 4*[wg.GRID_VALUE_LONG,]+[wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,]+ \
2631                2*[wg.GRID_VALUE_FLOAT+':10,2',]
2632            PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
2633            self.PawleyRefl.SetTable(PawleyTable, True)
2634            self.PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid)                 
2635            self.PawleyRefl.SetMargins(0,0)
2636            self.PawleyRefl.AutoSizeColumns(False)
2637            self.dataFrame.setSizePosLeft([500,300])
2638                   
2639    def OnPawleyLoad(event):
2640        generalData = data['General']
2641        dmin = generalData['Pawley dmin']
2642        cell = generalData['Cell'][1:7]
2643        A = G2lat.cell2A(cell)
2644        SGData = generalData['SGData']
2645        HKLd = np.array(G2lat.GenHLaue(dmin,SGData,A))
2646        PawleyPeaks = []
2647        wx.BeginBusyCursor()
2648        try:
2649            for h,k,l,d in HKLd:
2650                ext,mul = G2spc.GenHKLf([h,k,l],SGData)[:2]
2651                if not ext:
2652                    PawleyPeaks.append([h,k,l,mul,d,False,100.0,1.0])
2653        finally:
2654            wx.EndBusyCursor()
2655        data['Pawley ref'] = PawleyPeaks
2656        FillPawleyReflectionsGrid()
2657                           
2658    def OnPawleyDelete(event):
2659        dlg = wx.MessageDialog(self,'Do you really want to delete Pawley reflections?','Delete', 
2660            wx.YES_NO | wx.ICON_QUESTION)
2661        try:
2662            result = dlg.ShowModal()
2663        finally:
2664            dlg.Destroy()
2665        if result == wx.ID_YES: 
2666            data['Pawley ref'] = []
2667            FillPawleyReflectionsGrid()
2668
2669    def OnPageChanged(event):
2670        page = event.GetSelection()
2671        text = self.dataDisplay.GetPageText(page)
2672        if text == 'Atoms':
2673            self.dataFrame.SetMenuBar(self.dataFrame.AtomsMenu)
2674            self.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
2675            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestAdd, id=G2gd.wxID_ATOMSTESTADD)
2676            self.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
2677            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestInsert, id=G2gd.wxID_ATONTESTINSERT)
2678            self.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
2679            self.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
2680            self.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
2681            self.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
2682            self.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS)
2683            FillAtomsGrid()
2684        elif text == 'General':
2685            UpdateGeneral()
2686            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2687        elif text == 'Data':
2688            self.dataFrame.SetMenuBar(self.dataFrame.DataMenu)
2689            self.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD)
2690            self.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD)
2691            self.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE)
2692            UpdateDData()
2693            G2plt.PlotStrain(self,data)
2694            G2plt.PlotTexture(self,data,Start=True)
2695        elif text == 'Draw Options':
2696            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2697            UpdateDrawOptions()
2698            G2plt.PlotStructure(self,data)
2699        elif text == 'Draw Atoms':
2700            self.dataFrame.SetMenuBar(self.dataFrame.DrawAtomsMenu)
2701            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE)
2702            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL)
2703            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR)
2704            self.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR)
2705            self.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT)
2706            self.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV)
2707            self.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM)
2708            self.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD)           
2709            self.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL)
2710            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE)
2711            UpdateDrawAtoms()
2712            G2plt.PlotStructure(self,data)
2713        elif text == 'Pawley reflections':
2714            self.dataFrame.SetMenuBar(self.dataFrame.PawleyMenu)
2715            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD)
2716            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyDelete, id=G2gd.wxID_PAWLEYDELETE)           
2717            FillPawleyReflectionsGrid()           
2718        else:
2719            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2720        event.Skip()
2721       
2722    General = wx.Window(self.dataDisplay)
2723    self.dataDisplay.AddPage(General,'General')
2724    SetupGeneral()
2725    GeneralData = data['General']
2726    UpdateGeneral()
2727
2728    if GeneralData['Type'] == 'Pawley':
2729        DData = wx.ScrolledWindow(self.dataDisplay)
2730        self.dataDisplay.AddPage(DData,'Data')
2731        self.PawleyRefl = G2gd.GSGrid(self.dataDisplay)
2732        self.dataDisplay.AddPage(self.PawleyRefl,'Pawley reflections')
2733    else:
2734        DData = wx.ScrolledWindow(self.dataDisplay)
2735        self.dataDisplay.AddPage(DData,'Data')
2736        Atoms = G2gd.GSGrid(self.dataDisplay)
2737        self.dataDisplay.AddPage(Atoms,'Atoms')
2738        drawOptions = wx.Window(self.dataDisplay)
2739        self.dataDisplay.AddPage(drawOptions,'Draw Options')
2740        drawAtoms = G2gd.GSGrid(self.dataDisplay)
2741        self.dataDisplay.AddPage(drawAtoms,'Draw Atoms')
2742
2743    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
2744    self.dataDisplay.SetSelection(oldPage)
2745   
2746           
Note: See TracBrowser for help on using the repository browser.