source: trunk/GSASIIphsGUI.py @ 185

Last change on this file since 185 was 185, checked in by vondreele, 13 years ago

testpos & atom color fixes

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