source: trunk/GSASIIphsGUI.py @ 190

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

fill Pawley reflections grid
fix Item vs item

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