source: trunk/GSASIIphsGUI.py @ 158

Last change on this file since 158 was 158, checked in by vondreele, 15 years ago

implement drawing options:
select atom hilites
movable test point & atom insertion

File size: 72.4 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 cPickle
9import GSASIIpath
10import GSASIIlattice as G2lat
11import GSASIIspc as G2spc
12import GSASIIElem as G2elem
13import GSASIIplot as G2plt
14import GSASIIgrid as G2gd
15import numpy as np
16import numpy.linalg as nl
17
18VERY_LIGHT_GREY = wx.Colour(235,235,235)
19WHITE = wx.Colour(255,255,255)
20
21# trig functions in degrees
22sind = lambda x: math.sin(x*math.pi/180.)
23tand = lambda x: math.tan(x*math.pi/180.)
24cosd = lambda x: math.cos(x*math.pi/180.)
25asind = lambda x: 180.*math.asin(x)/math.pi
26
27class SymOpDialog(wx.Dialog):
28    def __init__(self,parent,SGData,New=True):
29        wx.Dialog.__init__(self,parent,-1,'Select symmetry operator',
30            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
31        panel = wx.Panel(self)
32        self.SGData = SGData
33        self.New = New
34        self.OpSelected = [0,0,0,0,0,0]
35        mainSizer = wx.BoxSizer(wx.VERTICAL)
36        mainSizer.Add((5,5),0)
37        if SGData['SGInv']:
38            choice = ['No','Yes']
39            self.inv = wx.RadioBox(panel,-1,'Choose inversion?',choices=choice)
40            self.inv.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
41            mainSizer.Add(self.inv,0,wx.ALIGN_CENTER_VERTICAL)
42        mainSizer.Add((5,5),0)
43        if SGData['SGLatt'] != 'P':
44            LattOp = G2spc.Latt2text(SGData['SGLatt']).split(';')
45            self.latt = wx.RadioBox(panel,-1,'Choose cell centering?',choices=LattOp)
46            self.latt.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
47            mainSizer.Add(self.latt,0,wx.ALIGN_CENTER_VERTICAL)
48        mainSizer.Add((5,5),0)
49        if SGData['SGLaue'] in ['-1','2/m','mmm','4/m','4/mmm']:
50            Ncol = 2
51        else:
52            Ncol = 3
53        OpList = []
54        for M,T in SGData['SGOps']:
55            OpList.append(G2spc.MT2text(M,T))
56        self.oprs = wx.RadioBox(panel,-1,'Choose space group operator?',choices=OpList,
57            majorDimension=Ncol)
58        self.oprs.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
59        mainSizer.Add(self.oprs,0,wx.ALIGN_CENTER_VERTICAL)
60        mainSizer.Add((5,5),0)
61        mainSizer.Add(wx.StaticText(panel,-1,"   Choose unit cell?"),0,wx.ALIGN_CENTER_VERTICAL)
62        mainSizer.Add((5,5),0)
63        cellSizer = wx.BoxSizer(wx.HORIZONTAL)
64        cellSizer.Add((5,0),0)
65        cellName = ['X','Y','Z']
66        self.cell = []
67        for i in range(3):
68            self.cell.append(wx.SpinCtrl(panel,-1,cellName[i],size=wx.Size(50,20)))
69            self.cell[-1].SetRange(-3,3)
70            self.cell[-1].SetValue(0)
71            self.cell[-1].Bind(wx.EVT_SPINCTRL, self.OnOpSelect)
72            cellSizer.Add(self.cell[-1],0,wx.ALIGN_CENTER_VERTICAL)
73        mainSizer.Add(cellSizer,0,)
74        if self.New:
75            choice = ['No','Yes']
76            self.new = wx.RadioBox(panel,-1,'Generate new positions?',choices=choice)
77            self.new.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
78            mainSizer.Add(self.new,0,wx.ALIGN_CENTER_VERTICAL)
79        mainSizer.Add((5,5),0)
80
81        OkBtn = wx.Button(panel,-1,"Ok")
82        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
83        cancelBtn = wx.Button(panel,-1,"Cancel")
84        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
85        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
86        btnSizer.Add((20,20),1)
87        btnSizer.Add(OkBtn)
88        btnSizer.Add((20,20),1)
89        btnSizer.Add(cancelBtn)
90        btnSizer.Add((20,20),1)
91
92        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
93        panel.SetSizer(mainSizer)
94        panel.Fit()
95        self.Fit()
96
97    def OnOpSelect(self,event):
98        self.OpSelected = [0,0,0,[]]
99        if self.SGData['SGInv']:
100            self.OpSelected[0] = self.inv.GetSelection()
101        if self.SGData['SGLatt'] != 'P':
102            self.OpSelected[1] = self.latt.GetSelection()
103        self.OpSelected[2] = self.oprs.GetSelection()
104        for i in range(3):
105            self.OpSelected[3].append(float(self.cell[i].GetValue()))
106        if self.New:
107            self.OpSelected.append(self.new.GetSelection())
108
109    def GetSelection(self):
110        return self.OpSelected
111
112    def OnOk(self,event):
113        parent = self.GetParent()
114        parent.Raise()
115        self.EndModal(wx.ID_OK)
116        self.Destroy()
117
118    def OnCancel(self,event):
119        parent = self.GetParent()
120        parent.Raise()
121        self.EndModal(wx.ID_CANCEL)
122        self.Destroy()
123
124def UpdatePhaseData(self,item,data,oldPage):
125
126    Atoms = []
127    self.SelectedRow = 0
128
129    def BookResize(event):
130        w,h = self.GetSize()
131        self.dataDisplay.SetSize(wx.Size(w,h))
132       
133    def UpdateGeneral():
134        generalData = data['General']
135        atomData = data['Atoms']
136        generalData['AtomTypes'] = []
137        generalData['NoAtoms'] = {}
138        generalData['BondRadii'] = []
139        generalData['AngleRadii'] = []
140        generalData['vdWRadii'] = []
141        generalData['AtomMass'] = []
142        generalData['Color'] = []
143        colType = 1
144        colSS = 7
145        if generalData['Type'] =='macromolecular':
146            colType = 4
147            colSS = 10
148        for atom in atomData:
149            atom[colType] = atom[colType].lower().capitalize()              #force to standard form
150            if generalData['AtomTypes'].count(atom[colType]):
151                generalData['NoAtoms'][atom[colType]] += atom[colSS-1]*float(atom[colSS+1])
152            elif atom[colType] != 'UNK':
153                Info = G2elem.GetAtomInfo(atom[colType])
154                generalData['AtomTypes'].append(atom[colType])
155                generalData['BondRadii'].append(Info['Drad'])
156                generalData['AngleRadii'].append(Info['Arad'])
157                generalData['vdWRadii'].append(Info['Vdrad'])
158                generalData['AtomMass'].append(Info['Mass'])
159                generalData['NoAtoms'][atom[colType]] = atom[colSS-1]*float(atom[colSS+1])
160                generalData['Color'].append(Info['Color'])
161
162    def FillGeneralGrid():
163        rowLabels = ['Phase name','Phase type','Space group',
164            'Lattice ',' parameters','Scale factor','Density','Elements','No. per cell',
165            'Atom weight','Bond radii','Angle radii','vdw radii','Color']
166        def SetLatticeParametersStyle(SGData,table):
167            clist = [1,2,3,4,5,6]
168            if SGData['SGLaue'] in ['m3','m3m']:
169                table[4][2] = table[4][3] = table[4][1]
170                table[4][4] = table[4][5] = table[4][6] = 90.
171                clist = [2,3,4,5,6]
172            elif SGData['SGLaue'] in ['3R','3mR']:
173                table[4][2] = table[4][3] = table[4][1]
174                table[4][5] = table[4][6] = table[4][4]
175                clist = [2,3,5,6]
176            elif SGData['SGLaue'] in ['3','3m1','31m','6/m','6/mmm']:
177                table[4][2] = table[4][1]
178                table[4][4] = table[4][5] = 90.
179                table[4][6] = 120.
180                clist = [2,4,5,6]
181            elif SGData['SGLaue'] in ['4/m','4/mmm']:
182                table[4][2] = table[4][1]
183                table[4][4] = table[4][5] = table[4][6] = 90.
184                clist = [2,4,5,6]
185            elif SGData['SGLaue'] in ['mmm']:
186                table[4][4] = table[4][5] = table[4][6] = 90.
187                clist = [4,5,6]
188            elif SGData['SGLaue'] in ['2/m']:
189                if SGData['SGUniq'] == 'a':
190                    table[4][5]= table[4][6] = 90.
191                    clist = [5,6]
192                if SGData['SGUniq'] == 'b':
193                    table[4][4]= table[4][6] = 90.
194                    clist = [4,6]
195                if SGData['SGUniq'] == 'c':
196                    table[4][4]= table[4][5] = 90.
197                    clist = [4,5]
198            for c in clist:
199                General.SetCellStyle(4,c,VERY_LIGHT_GREY,True)
200
201        def RefreshGeneralGrid(event):
202
203            r,c =  event.GetRow(),event.GetCol()
204            generalData['Name'] = table[0][0]
205            self.PatternTree.SetItemText(item,generalData['Name'])
206            generalData['Type'] = table[1][0]
207            SpcGp = table[2][0]
208            SGErr,SGData = G2spc.SpcGroup(SpcGp)
209            if r == 0:
210                self.G2plotNB.Rename(oldName,generalData['Name'])
211            elif r == 2 and c == 0:
212                if SGErr:
213                    text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous']
214                    table[2][0] = generalData['SGData']['SpGrp']
215                    msg = 'Space Group Error'
216                    Style = wx.ICON_EXCLAMATION
217                else:
218                    text = G2spc.SGPrint(SGData)
219                    generalData['SGData'] = SGData
220                    msg = 'Space Group Information'
221                    Style = wx.ICON_INFORMATION
222                Text = ''
223                for line in text:
224                    Text += line+'\n'
225                wx.MessageBox(Text,caption=msg,style=Style)
226            General.SetCellValue(4,0,str(generalData['Cell'][0]))
227            for c in range(1,7):
228                General.SetCellStyle(4,c,"white",False)
229                generalData['Cell'][c] = float(General.GetCellValue(4,c))
230            generalData['Cell'][7] = G2lat.calc_V(G2lat.cell2A(generalData['Cell'][1:7]))
231            SetLatticeParametersStyle(SGData,table)
232            generalData['Scale'][1] = float(General.GetCellValue(5,1))
233            General.ForceRefresh()
234
235        UpdateGeneral()
236        generalData = data['General']
237        self.dataFrame.setSizePosLeft([750,340])
238        colLabels = []
239        colLabels += ['' for i in range(max(8,len(generalData['AtomTypes'])))]
240        table = []
241        table.append([generalData['Name'],'','','','','','','',''])      #phase name
242        table.append([generalData['Type'],'','','','','','','',''])      #phase type
243        E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
244        table.append([SGData['SpGrp'],'','','','','','','',''])     #space group symbol
245        table.append(['refine','a    ','b    ','c    ','alpha ','beta ','gamma','volume  '])
246        table.append(generalData['Cell'])                      #lattice parameters
247        table.append([generalData['Scale'][0],generalData['Scale'][1],'','','','','',''])   #scale factor
248        line = []
249        if generalData['Type'] == 'Pawley':
250            table.append(max(0.25,generalData['Pawley dmin']))
251            rowLabels[6] = 'd min'
252        else:
253            mass = 0.
254            for i,elem in enumerate(generalData['AtomTypes']):
255                mass += generalData['NoAtoms'][elem]*generalData['AtomMass'][i]
256            Volume = generalData['Cell'][7]
257            if generalData['Type'] == 'macromolecular' and mass > 0.0:
258                table.append([mass/(0.6022137*Volume),'Matthews coeff.',Volume/mass,'','','','','',''])
259            else:
260                table.append([mass/(0.6022137*Volume),'','','','','','','',''])
261            for i,elem in enumerate(generalData['AtomTypes']):
262                line.append(generalData['NoAtoms'][elem])
263            table.append(generalData['AtomTypes']+['' for i in range(max(8,len(generalData['AtomTypes'])))]) #element list
264            table.append(line+['' for i in range(max(8,len(generalData['AtomTypes'])))]) #No. per cell
265            table.append(generalData['AtomMass']+['' for i in range(max(8,len(generalData['AtomTypes'])))])  #At. wt.
266            table.append(generalData['BondRadii']+['' for i in range(max(8,len(generalData['AtomTypes'])))])
267            table.append(generalData['AngleRadii']+['' for i in range(max(8,len(generalData['AtomTypes'])))])
268            table.append(generalData['vdWRadii']+['' for i in range(max(8,len(generalData['AtomTypes'])))])
269            table.append(['','','','','','','',''])                        #contains colors
270        Types = [wg.GRID_VALUE_STRING for i in range(max(8,len(generalData['AtomTypes'])))]
271        generalTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
272        General.SetTable(generalTable, True)
273        General.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshGeneralGrid)
274        General.SetMargins(0,0)
275        General.SetColSize(0,100)
276        General.SetColLabelSize(0)
277        attr = wg.GridCellAttr()
278        for c in range(max(8,len(generalData['AtomTypes']))):
279            if c > 0:
280                General.SetReadOnly(0,c,isReadOnly=True)
281                General.SetReadOnly(1,c,isReadOnly=True)
282                General.SetReadOnly(2,c,isReadOnly=True)
283            General.SetReadOnly(3,c,isReadOnly=True)                         #unit cell labels
284            General.SetCellAlignment(3,c,wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
285            if c < 4:
286                General.SetCellRenderer(4,c,wg.GridCellFloatRenderer(10,5))
287                General.SetCellEditor(4,c,wg.GridCellFloatEditor(10,5))
288            else:
289                General.SetCellRenderer(4,c,wg.GridCellFloatRenderer(10,3))
290                General.SetCellEditor(4,c,wg.GridCellFloatEditor(10,3))
291            for r in range(6,13):
292                General.SetReadOnly(r,c,isReadOnly=True)
293        r = rowLabels.index('Color')
294        for c in range(len(generalData['AtomTypes'])):
295            General.SetCellBackgroundColour(r,c,generalData['Color'][c])
296
297        General.SetReadOnly(4,7,isReadOnly=True)                            #cell volume - no edit
298        General.SetCellEditor(1,0,wg.GridCellChoiceEditor(['nuclear','modulated',   #phase type
299            'magnetic','macromolecular','Pawley'],False))                           #- change only if no atoms
300        if line:                                                    #no.of atoms not zero!
301            General.SetReadOnly(1,0,isReadOnly=True)                #can't change phase type
302        General.SetCellRenderer(4,0,wg.GridCellBoolRenderer())              #lattice parameters
303        General.SetCellEditor(4,0,wg.GridCellBoolEditor())
304        SetLatticeParametersStyle(SGData,table)
305        General.SetCellRenderer(5,1,wg.GridCellFloatRenderer(10,4))         #scale factor
306        General.SetCellEditor(5,1,wg.GridCellFloatEditor(10,4))
307        General.SetCellRenderer(5,0,wg.GridCellBoolRenderer())
308        General.SetCellEditor(5,0,wg.GridCellBoolEditor())
309        General.SetCellRenderer(6,0,wg.GridCellFloatRenderer(8,3))
310        General.SetCellRenderer(6,2,wg.GridCellFloatRenderer(8,3))
311
312    def FillAtomsGrid():
313
314        self.dataFrame.setSizePosLeft([700,300])
315        generalData = data['General']
316        atomData = data['Atoms']
317        AAchoice = ": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK"
318        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",
319            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
320            wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+":I,A",
321            wg.GRID_VALUE_FLOAT+':10,4',                                                            #Uiso
322            wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,                         #Uij - placeholders
323            wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING]
324        colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23']
325        if generalData['Type'] == 'magnetic':
326            colLabels += ['Mx','My','Mz']
327            Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU,"
328            Types += [
329                wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4']
330        elif generalData['Type'] == 'macromolecular':
331            colLabels = ['res no','residue','chain'] + colLabels
332            Types = [wg.GRID_VALUE_STRING,
333                wg.GRID_VALUE_CHOICE+AAchoice,
334                wg.GRID_VALUE_STRING] + Types
335        elif generalData['Type'] == 'modulated':
336            Types += []
337            colLabels += []
338
339        def RefreshAtomGrid(event):
340
341            def chkUij(Uij,CSI):
342                return Uij
343
344            r,c =  event.GetRow(),event.GetCol()
345            if r < 0 and c < 0:
346                for row in range(Atoms.GetNumberRows()):
347                    Atoms.SelectRow(row,True)                   
348            if r < 0:                          #double click on col label! Change all atoms!
349                sel = -1
350                noSkip = True
351                if Atoms.GetColLabelValue(c) == 'refine':
352                    Type = generalData['Type']
353                    if Type in ['nuclear','macromolecular']:
354                        choice = ['F - site fraction','X - coordinates','U - thermal parameters']
355                    elif Type in ['magnetic',]:
356                        choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
357                    dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice)
358                    if dlg.ShowModal() == wx.ID_OK:
359                        sel = dlg.GetSelections()
360                        parms = ''
361                        for x in sel:
362                            parms += choice[x][0]
363                    dlg.Destroy()
364                elif Atoms.GetColLabelValue(c) == 'I/A':
365                    choice = ['Isotropic','Anisotropic']
366                    dlg = wx.SingleChoiceDialog(self,'Select','Thermal Motion',choice)
367                    if dlg.ShowModal() == wx.ID_OK:
368                        sel = dlg.GetSelection()
369                        parms = choice[sel][0]
370                    dlg.Destroy()
371                elif Atoms.GetColLabelValue(c) == 'Type':
372                    choice = generalData['AtomTypes']
373                    dlg = wx.SingleChoiceDialog(self,'Select','Atom types',choice)
374                    if dlg.ShowModal() == wx.ID_OK:
375                        sel = dlg.GetSelection()
376                        parms = choice[sel]
377                        noSkip = False
378                        Atoms.ClearSelection()
379                        for row in range(Atoms.GetNumberRows()):
380                            if parms == atomData[row][c]:
381                                Atoms.SelectRow(row,True)
382                elif Atoms.GetColLabelValue(c) == 'residue':
383                    choice = []
384                    for r in range(Atoms.GetNumberRows()):
385                        if str(atomData[r][c]) not in choice:
386                            choice.append(str(atomData[r][c]))
387                    choice.sort()
388                    dlg = wx.SingleChoiceDialog(self,'Select','Residue',choice)
389                    if dlg.ShowModal() == wx.ID_OK:
390                        sel = dlg.GetSelection()
391                        parms = choice[sel]
392                        noSkip = False
393                        Atoms.ClearSelection()
394                        for row in range(Atoms.GetNumberRows()):
395                            if parms == atomData[row][c]:
396                                Atoms.SelectRow(row,True)
397                elif Atoms.GetColLabelValue(c) == 'res no':
398                    choice = []
399                    for r in range(Atoms.GetNumberRows()):
400                        if str(atomData[r][c]) not in choice:
401                            choice.append(str(atomData[r][c]))
402                    dlg = wx.SingleChoiceDialog(self,'Select','Residue no.',choice)
403                    if dlg.ShowModal() == wx.ID_OK:
404                        sel = dlg.GetSelection()
405                        parms = choice[sel]
406                        noSkip = False
407                        Atoms.ClearSelection()
408                        for row in range(Atoms.GetNumberRows()):
409                            if int(parms) == atomData[row][c]:
410                                Atoms.SelectRow(row,True)
411                elif Atoms.GetColLabelValue(c) == 'chain':
412                    choice = []
413                    for r in range(Atoms.GetNumberRows()):
414                        if atomData[r][c] not in choice:
415                            choice.append(atomData[r][c])
416                    dlg = wx.SingleChoiceDialog(self,'Select','Chain',choice)
417                    if dlg.ShowModal() == wx.ID_OK:
418                        sel = dlg.GetSelection()
419                        parms = choice[sel]
420                        noSkip = False
421                        Atoms.ClearSelection()
422                        for row in range(Atoms.GetNumberRows()):
423                            if parms == atomData[row][c]:
424                                Atoms.SelectRow(row,True)
425                    dlg.Destroy()
426                elif Atoms.GetColLabelValue(c) == 'Uiso':       #this needs to ask for value
427                    pass                                        #& then change all 'I' atoms
428                if sel >= 0 and noSkip:
429                    ui = colLabels.index('U11')
430                    us = colLabels.index('Uiso')
431                    ss = colLabels.index('site sym')
432                    for r in range(Atoms.GetNumberRows()):
433                        if parms != atomData[r][c] and Atoms.GetColLabelValue(c) == 'I/A':
434                            if parms == 'A':                #'I' --> 'A'
435                                Uiso = atomData[r][us]
436                                sytsym = atomData[r][ss]
437                                CSI = G2spc.GetCSuinel(sytsym)
438                                atomData[r][ui:ui+6] = Uiso*np.array(CSI[3])
439                                atomData[r][us] = ''
440                                Atoms.SetCellRenderer(r,us,wg.GridCellStringRenderer())
441                                Atoms.SetCellStyle(r,us,VERY_LIGHT_GREY,True)
442                                for i in range(6):
443                                    ci = ui+i
444                                    Atoms.SetCellRenderer(r,ci,wg.GridCellFloatRenderer(10,4))
445                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
446                                    if CSI[2][i]:
447                                        Atoms.SetCellStyle(r,ci,WHITE,False)
448                            else:                           #'A' --> 'I'
449                                Uij = atomData[r][ui:ui+6]
450                                atomData[r][us] = (Uij[0]+Uij[1]+Uij[2])/3.0
451                                atomData[r][ui:ui+6] = [0,0,0,0,0,0]
452                                Atoms.SetCellRenderer(r,us,wg.GridCellFloatRenderer(10,4))
453                                Atoms.SetCellStyle(r,us,WHITE,False)
454                                for i in range(6):
455                                    ci = ui+i
456                                    Atoms.SetCellRenderer(r,ci,wg.GridCellStringRenderer())
457                                    Atoms.SetCellValue(r,ci,'')
458                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
459                        Atoms.SetCellValue(r,c,parms)
460            elif Atoms.GetColLabelValue(c) in ['Name']:
461                atomData[r][c] = Atoms.GetCellValue(r,c)
462            elif Atoms.GetColLabelValue(c) in ['x','y','z']:
463                atomData[r][c] = float(Atoms.GetCellValue(r,c))
464                ci = colLabels.index('x')
465                XYZ = atomData[r][ci:ci+3]
466                if None in XYZ:
467                    XYZ = [0,0,0]
468                SScol = colLabels.index('site sym')
469                Mulcol = colLabels.index('mult')
470                E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
471                Sytsym,Mult = G2spc.SytSym(XYZ,SGData)
472                atomData[r][SScol] = Sytsym
473                atomData[r][Mulcol] = Mult
474                Atoms.SetCellValue(r,SScol,Sytsym)
475                Atoms.SetCellValue(r,Mulcol,str(Mult))
476                if atomData[r][colLabels.index('I/A')] == 'A':
477                    ui = colLabels.index('U11')
478                    CSI = G2spc.GetCSuinel(Sytsym)
479                    atomData[r][ui:ui+6] = chkUij(atomData[r][ui:ui+6],Sytsym)
480                    for i in range(6):
481                        ci = i+ui
482                        Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
483                        if CSI[2][i]:
484                            Atoms.SetCellStyle(r,ci,WHITE,False)
485                UpdateGeneral()
486            elif Atoms.GetColLabelValue(c) == 'I/A':
487                atomData[r][c] = Atoms.GetCellValue(r,c)
488                if atomData[r][c] == 'I':
489                    Uij = atomData[r][c+2:c+8]
490                    atomData[r][c+1] = (Uij[0]+Uij[1]+Uij[2])/3.0
491                    atomData[r][c+2:c+8] = [0,0,0,0,0,0]
492                    Atoms.SetCellRenderer(r,c+1,wg.GridCellFloatRenderer(10,4))
493                    Atoms.SetCellStyle(r,c+1,WHITE,False)
494                    for i in range(6):
495                        ci = i+colLabels.index('U11')
496                        Atoms.SetCellRenderer(r,ci,wg.GridCellStringRenderer())
497                        Atoms.SetCellValue(r,ci,'')
498                        Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
499                else:
500                    Uiso = atomData[r][c+1]
501                    atomData[r][c+1] = ''
502                    CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
503                    atomData[r][c+2:c+8] = Uiso*np.array(CSI[3])
504                    Atoms.SetCellRenderer(r,c+1,wg.GridCellStringRenderer())
505                    Atoms.SetCellStyle(r,c+1,VERY_LIGHT_GREY,True)
506                    for i in range(6):
507                        ci = i+colLabels.index('U11')
508                        Atoms.SetCellRenderer(r,ci,wg.GridCellFloatRenderer(10,4))
509                        Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
510                        if CSI[2][i]:
511                            Atoms.SetCellStyle(r,ci,WHITE,False)
512            elif Atoms.GetColLabelValue(c) in ['U11','U22','U33','U12','U13','U23']:
513                atomData[r][c] = float(Atoms.GetCellValue(r,c))
514                CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
515                iUij = CSI[0][c-colLabels.index('U11')]
516                for i in range(6):
517                    if iUij == CSI[0][i]:
518                        atomData[r][i+colLabels.index('U11')] = value*CSI[1][i]
519            elif Atoms.GetColLabelValue(c) == 'Uiso':
520                atomData[r][c] = float(Atoms.GetCellValue(r,c))               
521            data['Atoms'] = atomData
522
523        def RowSelect(event):
524            r,c =  event.GetRow(),event.GetCol()
525            if r < 0 and c < 0:
526                if Atoms.IsSelection():
527                    Atoms.ClearSelection()
528            elif c < 0:                   #only row clicks
529                if event.ControlDown():                   
530                    if r in Atoms.GetSelectedRows():
531                        Atoms.DeselectRow(r)
532                    else:
533                        Atoms.SelectRow(r,True)
534                elif event.ShiftDown():
535                    for row in range(r+1):
536                        Atoms.SelectRow(row,True)
537                else:
538                    Atoms.ClearSelection()
539                    Atoms.SelectRow(r,True)               
540               
541        def ChangeSelection(event):
542            r,c =  event.GetRow(),event.GetCol()
543            if r < 0 and c < 0:
544                Atoms.ClearSelection()
545            if c < 0:
546                if r in Atoms.GetSelectedRows():
547                    Atoms.DeselectRow(r)
548                else:
549                    Atoms.SelectRow(r,True)
550            if r < 0:
551                if c in Atoms.GetSelectedCols():
552                    Atoms.DeselectCol(c)
553                else:
554                    Atoms.SelectCol(c,True)
555
556        def AtomTypeSelect(event):
557            r,c =  event.GetRow(),event.GetCol()
558            if Atoms.GetColLabelValue(c) == 'Type':
559                PE = G2elem.PickElement(self)
560                if PE.ShowModal() == wx.ID_OK:
561                    atomData[r][c] = PE.Elem.strip()
562                    name = atomData[r][c]
563                    if len(name) in [2,4]:
564                        atomData[r][c-1] = name[:2]+'(%d)'%(r+1)
565                    else:
566                        atomData[r][c-1] = name[:1]+'(%d)'%(r+1)
567                PE.Destroy()
568                UpdateGeneral()
569                FillAtomsGrid()
570            else:
571                event.Skip()
572
573        table = []
574        rowLabels = []
575        for i,atom in enumerate(atomData):
576            if atom[colLabels.index('I/A')] == 'I':
577                table.append(atom[:colLabels.index('U11')]+['','','','','',''])
578            else:
579                table.append(atom)
580            rowLabels.append(str(i+1))
581        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
582        Atoms.SetTable(atomTable, True)
583        Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
584        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
585        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
586        Atoms.Bind(wg.EVT_GRID_LABEL_RIGHT_CLICK, ChangeSelection)
587        Atoms.Bind(wg.EVT_GRID_SELECT_CELL, AtomTypeSelect)
588        Atoms.SetMargins(0,0)
589        Atoms.AutoSizeColumns(True)
590        colType = colLabels.index('Type')
591        colSS = colLabels.index('site sym')
592        colIA = colLabels.index('I/A')
593        colU11 = colLabels.index('U11')
594        colUiso = colLabels.index('Uiso')
595        attr = wg.GridCellAttr()                                #to set Uij defaults
596        attr.SetBackgroundColour(VERY_LIGHT_GREY)
597        attr.SetReadOnly(True)
598        for i in range(colU11,colU11+6):
599            Atoms.SetColAttr(i,attr)
600        for row in range(Atoms.GetNumberRows()):
601            Atoms.SetReadOnly(row,colSS,True)                         #site sym
602            Atoms.SetReadOnly(row,colSS+1,True)                       #Mult
603            if Atoms.GetCellValue(row,colIA) == 'A':
604                CSI = G2spc.GetCSuinel(atomData[row][colLabels.index('site sym')])
605                Atoms.SetCellRenderer(row,colUiso,wg.GridCellStringRenderer())
606                Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True)
607                Atoms.SetCellValue(row,colUiso,'')
608                for i in range(6):
609                    ci = colU11+i
610                    Atoms.SetCellRenderer(row,ci,wg.GridCellFloatRenderer(10,4))
611                    if CSI[2][i]:
612                        Atoms.SetCellStyle(row,ci,WHITE,False)
613
614    def OnAtomAdd(event):
615        AtomAdd(0,0,0)
616        FillAtomsGrid()
617        event.StopPropagation()
618       
619    def OnAtomTestAdd(event):
620        try:
621            drawData = data['Drawing']
622            x,y,z = drawData['testPos']
623            AtomAdd(x,y,z)
624        except:
625            AtomAdd(0,0,0)
626        FillAtomsGrid()
627        event.StopPropagation()
628               
629    def AtomAdd(x,y,z):
630        atomData = data['Atoms']
631        generalData = data['General']
632        Ncol = Atoms.GetNumberCols()
633        E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
634        Sytsym,Mult = G2spc.SytSym([x,y,z],SGData)
635        if generalData['Type'] == 'macromolecular':
636            atomData.append([0,'UNK','','UNK','H','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0])
637        elif generalData['Type'] == 'nuclear':
638            atomData.append(['UNK','H','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0])
639        elif generalData['Type'] == 'magnetic':
640            atomData.append(['UNK','H','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0])
641        UpdateGeneral()
642
643    def OnAtomInsert(event):
644        AtomInsert(0,0,0)
645        FillAtomsGrid()
646        event.StopPropagation()
647       
648    def OnAtomTestInsert(event):
649        try:
650            drawData = data['Drawing']
651            x,y,z = drawData['testPos']
652            AtomAdd(x,y,z)
653        except:
654            AtomAdd(0,0,0)
655        FillAtomsGrid()
656        event.StopPropagation()
657           
658    def AtomInsert(x,y,z):
659        indx = Atoms.GetSelectedRows()
660        if indx:
661            indx = indx[0]
662            atomData = data['Atoms']
663            generalData = data['General']
664            Ncol = Atoms.GetNumberCols()
665            E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
666            Sytsym,Mult = G2spc.SytSym([0,0,0],SGData)
667            if generalData['Type'] == 'macromolecular':
668                atomData.insert(indx,[0,'UNK','','UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0])
669            elif generalData['Type'] == 'nuclear':
670                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0])
671            elif generalData['Type'] == 'magnetic':
672                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0])
673            UpdateGeneral()
674
675    def AtomDelete(event):
676        indx = Atoms.GetSelectedRows()
677        if indx:
678            atomData = data['Atoms']
679            indx.reverse()
680            for ind in indx:
681                atom = atomData[ind]
682                del atomData[ind]
683            FillAtomsGrid()
684        event.StopPropagation()
685
686    def AtomRefine(event):
687        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
688        c = colLabels.index('refine')
689        indx = Atoms.GetSelectedRows()
690        if indx:
691            atomData = data['Atoms']
692            generalData = data['General']
693            Type = generalData['Type']
694            if Type in ['nuclear','macromolecular']:
695                choice = ['F - site fraction','X - coordinates','U - thermal parameters']
696            elif Type == 'magnetic':
697                choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
698            dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice)
699            if dlg.ShowModal() == wx.ID_OK:
700                sel = dlg.GetSelections()
701                parms = ''
702                for x in sel:
703                    parms += choice[x][0]
704                for r in indx:
705                    atomData[r][c] = parms
706                Atoms.ForceRefresh()
707            dlg.Destroy()
708
709    def AtomModify(event):                  #intent to implement global modifications (+,-,*,/, etc.)?
710        indx = Atoms.GetSelectedRows()
711        if indx:
712            atomData = data['Atoms']
713            generalData = data['General']
714
715    def AtomTransform(event):
716        indx = Atoms.GetSelectedRows()
717        if indx:
718            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
719            cx = colLabels.index('x')
720            cuia = colLabels.index('I/A')
721            cuij = colLabels.index('U11')
722            css = colLabels.index('site sym')
723            atomData = data['Atoms']
724            generalData = data['General']
725            SGData = generalData['SGData']
726            dlg = SymOpDialog(self,SGData,True)
727            try:
728                if dlg.ShowModal() == wx.ID_OK:
729                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
730                    Cell = np.array(Cell)
731                    cent = SGData['SGCen'][Cent]
732                    M,T = SGData['SGOps'][Opr]
733                    print M,T
734                    for ind in indx:
735                        XYZ = np.array(atomData[ind][cx:cx+3])
736                        XYZ = np.inner(M,XYZ)+T
737                        if Inv:
738                            XYZ = -XYZ
739                        XYZ = XYZ+cent+Cell
740                        if New:
741                            atom = copy.copy(atomData[ind])
742                        else:
743                            atom = atomData[ind]
744                        atom[cx:cx+3] = XYZ
745                        atom[css:css+2] = G2spc.SytSym(XYZ,SGData)
746                        if atom[cuia] == 'A':
747                            Uij = atom[cuij:cuij+6]
748                            U = G2spc.Uij2U(Uij)
749                            U = np.inner(np.inner(M,U),M)
750                            Uij = G2spc.U2Uij(U)
751                            atom[cuij:cuij+6] = Uij
752                        if New:
753                            atomData.append(atom)
754            finally:
755                dlg.Destroy()
756            Atoms.ClearSelection()
757            if New:
758                FillAtomsGrid()
759            else:
760                Atoms.ForceRefresh()
761
762    def SetupDrawingData():
763        generalData = data['General']
764        atomData = data['Atoms']
765        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
766            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
767        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
768            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
769        defaultDrawing = {'viewPoint':[[0.5,0.5,0.5],[]],'showHydrogen':True,'backColor':[0,0,0],'depthFog':False,
770            'Zclip':50.0,'cameraPos':50.,'pickItem':'Atoms','showBadContacts':False,
771            'bondRadius':0.1,'ballScale':0.33,'vdwScale':0.67,'ellipseProb':50,'sizeH':0.50,
772            'unitCellBox':False,'showABC':True,'showSymElem':False,'selectedAtoms':[],
773            'Rotation':[0.0,0.0,0.0,[]],'bondList':{},'testPos':[-.1,-.1,-.1]}
774        try:
775            drawingData = data['Drawing']
776        except KeyError:
777            data['Drawing'] = {}
778            drawingData = data['Drawing']
779        if not drawingData:                 #fill with defaults if empty
780            drawingData = copy.copy(defaultDrawing)
781            drawingData['Atoms'] = []
782        if not drawingData['Atoms']:
783            for atom in atomData:
784                if generalData['Type'] == 'nuclear':
785                    drawingData['Atoms'].append(atom[:2]+atom[3:6]+['1',]+['lines',]+
786                        ['',]+atom[9:17]+[[]])
787                    drawingData['atomPtrs'] = [2,1,6]         #x, type & style
788                elif generalData['Type'] == 'macromolecular':
789                    try:
790                        oneLetter = AA3letter.index(atom[1])
791                    except ValueError:
792                        oneLetter = -1
793                    drawingData['Atoms'].append([atom[1].strip()+atom[0],]+
794                        [AA1letter[oneLetter]+atom[0],]+atom[2:5]+
795                        atom[6:9]+['1',]+['lines',]+['',]+atom[12:20]+[[]])
796                    drawingData['atomPtrs'] = [5,4,9]         #x, type & style
797                elif generalData['Type'] == 'magnetic':
798                    drawingData['Atoms'].append(atom[:2]+atom[3:6]+['lines',]+['',]+atom[9:20]+[[]])
799#            elif generalData['Type'] == 'modulated':
800#                ?????   for future
801            data['Drawing'] = drawingData
802
803    def UpdateDrawAtoms():
804        generalData = data['General']
805        SetupDrawingData()
806        drawingData = data['Drawing']
807        atomData = drawingData['Atoms']
808        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,
809            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',    #x,y,z
810            wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,polyhedra",
811            wg.GRID_VALUE_CHOICE+": ,type,name,number",wg.GRID_VALUE_STRING,]
812        styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
813        labelChoice = [' ','type','name','number']
814        colLabels = ['Name','Type','x','y','z','Sym Op','Style','Label','I/A']
815        if generalData['Type'] == 'macromolecular':
816            colLabels = ['Residue','1-letter','Chain'] + colLabels
817            Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING]+Types
818            Types[8] = wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,backbone,ribbons,schematic"
819            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','backbone','ribbons','schematic']
820            labelChoice = [' ','type','name','number','residue','1-letter','chain']
821            Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1-letter,chain"
822#        elif generalData['Type'] == 'modulated':
823#            Types += []
824#            colLabels += []
825
826        def RefreshAtomGrid(event):
827
828            def SetChoice(name,c,n=0):
829                choice = []
830                for r in range(len(atomData)):
831                    if n:
832                        srchStr = str(atomData[r][c][:n])
833                    else:
834                        srchStr = str(atomData[r][c])
835                    if srchStr not in choice:
836                        if n:
837                            choice.append(str(atomData[r][c][:n]))
838                        else:
839                            choice.append(str(atomData[r][c]))
840                choice.sort()
841
842                dlg = wx.MultiChoiceDialog(self,'Select',name,choice)
843                if dlg.ShowModal() == wx.ID_OK:
844                    sel = dlg.GetSelections()
845                    parms = []
846                    for x in sel:
847                        parms.append(choice[x])
848                    noSkip = False
849                    drawAtoms.ClearSelection()
850                    drawingData['selectedAtoms'] = []
851                    for row in range(len(atomData)):
852                        test = atomData[row][c]
853                        if n:
854                            test = test[:n]
855                        if  test in parms:
856                            drawAtoms.SelectRow(row,True)
857                            drawingData['selectedAtoms'].append(row)
858                    G2plt.PlotStructure(self,data)                   
859                dlg.Destroy()
860               
861            r,c =  event.GetRow(),event.GetCol()
862            if r < 0 and c < 0:
863                for row in range(drawAtoms.GetNumberRows()):
864                    drawingData['selectedAtoms'].append(row)
865                    drawAtoms.SelectRow(row,True)                   
866            elif r < 0:                          #dclick on col label
867                sel = -1
868                Parms = False
869                noSkip = True
870                if drawAtoms.GetColLabelValue(c) == 'Style':
871                    dlg = wx.SingleChoiceDialog(self,'Select','Atom drawing style',styleChoice)
872                    if dlg.ShowModal() == wx.ID_OK:
873                        sel = dlg.GetSelection()
874                        parms = styleChoice[sel]
875                        for r in range(len(atomData)):
876                            atomData[r][c] = parms
877                            drawAtoms.SetCellValue(r,c,parms)
878                        FindBonds()
879                        G2plt.PlotStructure(self,data)
880                    dlg.Destroy()
881                elif drawAtoms.GetColLabelValue(c) == 'Label':
882                    dlg = wx.SingleChoiceDialog(self,'Select','Atom labelling style',labelChoice)
883                    if dlg.ShowModal() == wx.ID_OK:
884                        sel = dlg.GetSelection()
885                        parms = labelChoice[sel]
886                        for r in range(len(atomData)):
887                            atomData[r][c] = parms
888                            drawAtoms.SetCellValue(r,c,parms)
889                    dlg.Destroy()                   
890                elif drawAtoms.GetColLabelValue(c) == 'Residue':
891                    SetChoice('Residue',c,3)
892                elif drawAtoms.GetColLabelValue(c) == '1-letter':
893                    SetChoice('1-letter',c,1)
894                elif drawAtoms.GetColLabelValue(c) == 'Chain':
895                    SetChoice('Chain',c)
896                elif drawAtoms.GetColLabelValue(c) == 'Name':
897                    SetChoice('Name',c)
898                elif drawAtoms.GetColLabelValue(c) == 'Sym Op':
899                    SetChoice('Name',c)
900                elif drawAtoms.GetColLabelValue(c) == 'Type':
901                    SetChoice('Type',c)
902                elif drawAtoms.GetColLabelValue(c) in ['x','y','z','I/A']:
903                    drawAtoms.ClearSelection()
904            else:
905                if drawAtoms.GetColLabelValue(c) in ['Style','Label']:
906                    atomData[r][c] = drawAtoms.GetCellValue(r,c)
907                    FindBonds()
908            G2plt.PlotStructure(self,data)
909                   
910        def RowSelect(event):
911            r,c =  event.GetRow(),event.GetCol()
912            if r < 0 and c < 0:
913                if drawAtoms.IsSelection():
914                    drawAtoms.ClearSelection()
915            elif c < 0:                   #only row clicks
916                if event.ControlDown():                   
917                    if r in drawAtoms.GetSelectedRows():
918                        drawAtoms.DeselectRow(r)
919                    else:
920                        drawAtoms.SelectRow(r,True)
921                elif event.ShiftDown():
922                    for row in range(r+1):
923                        drawAtoms.SelectRow(row,True)
924                else:
925                    drawAtoms.ClearSelection()
926                    drawAtoms.SelectRow(r,True)               
927            drawingData['selectedAtoms'] = []
928            drawingData['selectedAtoms'] = drawAtoms.GetSelectedRows()
929            G2plt.PlotStructure(self,data)                   
930               
931        table = []
932        rowLabels = []
933        for i,atom in enumerate(drawingData['Atoms']):
934            table.append(atom[:colLabels.index('I/A')+1])
935            rowLabels.append(str(i+1))
936
937        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
938        drawAtoms.SetTable(atomTable, True)
939        drawAtoms.SetMargins(0,0)
940        drawAtoms.AutoSizeColumns(True)
941        drawAtoms.SetColSize(colLabels.index('Style'),80)
942        drawAtoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
943        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
944        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
945        indx = drawingData['selectedAtoms']
946        if indx:
947            for r in range(len(atomData)):
948                if r in indx:
949                    drawAtoms.SelectRow(r)
950        for c in range(len(colLabels)):
951            if colLabels[c] not in ['Style','Label']:
952                attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
953                attr.SetReadOnly(True)
954                attr.SetBackgroundColour(VERY_LIGHT_GREY)
955                drawAtoms.SetColAttr(c,attr)
956        self.dataFrame.setSizePosLeft([600,300])
957        FindBonds()
958        G2plt.PlotStructure(self,data)
959
960    def DrawAtomStyle(event):
961        indx = drawAtoms.GetSelectedRows()
962        if indx:
963            generalData = data['General']
964            atomData = data['Drawing']['Atoms']
965            cx,ct,cs = data['Drawing']['atomPtrs']
966            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
967            if generalData['Type'] == 'macromolecular':
968                styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids',
969                'backbone','ribbons','schematic']
970            dlg = wx.SingleChoiceDialog(self,'Select','Atom drawing style',styleChoice)
971            if dlg.ShowModal() == wx.ID_OK:
972                sel = dlg.GetSelection()
973                parms = styleChoice[sel]
974                for r in indx:
975                    atomData[r][cs] = parms
976                    drawAtoms.SetCellValue(r,cs,parms)
977            dlg.Destroy()
978            FindBonds()
979            G2plt.PlotStructure(self,data)
980
981    def DrawAtomLabel(event):
982        indx = drawAtoms.GetSelectedRows()
983        if indx:
984            generalData = data['General']
985            atomData = data['Drawing']['Atoms']
986            cx,ct,cs = data['Drawing']['atomPtrs']
987            styleChoice = [' ','type','name','number']
988            if generalData['Type'] == 'macromolecular':
989                styleChoice = [' ','type','name','number','residue','1-letter','chain']
990            dlg = wx.SingleChoiceDialog(self,'Select','Atom label style',styleChoice)
991            if dlg.ShowModal() == wx.ID_OK:
992                sel = dlg.GetSelection()
993                parms = styleChoice[sel]
994                for r in indx:
995                    atomData[r][cs+1] = parms
996                    drawAtoms.SetCellValue(r,cs+1,parms)
997            dlg.Destroy()
998            G2plt.PlotStructure(self,data)
999
1000    def SetViewPoint(event):
1001        indx = drawAtoms.GetSelectedRows()
1002        if indx:
1003            atomData = data['Drawing']['Atoms']
1004            cx = data['Drawing']['atomPtrs'][0]
1005            data['Drawing']['viewPoint'] = [atomData[indx[0]][cx:cx+3],[indx[0],0]]
1006            drawAtoms.ClearSelection()                                  #do I really want to do this?
1007            G2plt.PlotStructure(self,data)
1008           
1009    def noDuplicate(xyz,atomData):                  #be careful where this is used - it's slow
1010        cx = data['Drawing']['atomPtrs'][0]
1011        if True in [np.allclose(np.array(xyz),np.array(atom[cx:cx+3]),atol=0.0002) for atom in atomData]:
1012            return False
1013        else:
1014            return True
1015               
1016    def AddSymEquiv(event):
1017        indx = drawAtoms.GetSelectedRows()
1018        indx.sort()
1019        if indx:
1020            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1021            cx = colLabels.index('x')
1022            cuia = colLabels.index('I/A')
1023            cuij = cuia+2
1024            atomData = data['Drawing']['Atoms']
1025            generalData = data['General']
1026            SGData = generalData['SGData']
1027            dlg = SymOpDialog(self,SGData,False)
1028            try:
1029                if dlg.ShowModal() == wx.ID_OK:
1030                    Inv,Cent,Opr,Cell = dlg.GetSelection()
1031                    Cell = np.array(Cell)
1032                    cent = SGData['SGCen'][Cent]
1033                    M,T = SGData['SGOps'][Opr]
1034                    for ind in indx:
1035                        XYZ = np.array(atomData[ind][cx:cx+3])
1036                        XYZ = np.inner(M,XYZ)+T
1037                        if Inv:
1038                            XYZ = -XYZ
1039                        XYZ = XYZ+cent+Cell
1040                        if noDuplicate(XYZ,atomData):
1041                            atom = copy.copy(atomData[ind])
1042                            atom[cx:cx+3] = XYZ
1043                            atom[cx+3] = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1044                                str(int(Cell[0]))+str(int(Cell[1]))+str(int(Cell[2]))
1045                            if atom[cuia] == 'A':
1046                                Uij = atom[cuij:cuij+6]
1047                                U = G2spc.Uij2U(Uij)
1048                                U = np.inner(np.inner(M,U),M)
1049                                Uij = G2spc.U2Uij(U)
1050                                atom[cuij:cuij+6] = Uij
1051                            atomData.append(atom)
1052            finally:
1053                dlg.Destroy()
1054            UpdateDrawAtoms()
1055            G2plt.PlotStructure(self,data)
1056           
1057    def TransformSymEquiv(event):
1058        indx = drawAtoms.GetSelectedRows()
1059        indx.sort()
1060        if indx:
1061            atomData = data['Drawing']['Atoms']
1062            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1063            cx = colLabels.index('x')
1064            cuia = colLabels.index('I/A')
1065            cuij = cuia+2
1066            atomData = data['Drawing']['Atoms']
1067            generalData = data['General']
1068            SGData = generalData['SGData']
1069            dlg = SymOpDialog(self,SGData,False)
1070            try:
1071                if dlg.ShowModal() == wx.ID_OK:
1072                    Inv,Cent,Opr,Cell = dlg.GetSelection()
1073                    Cell = np.array(Cell)
1074                    cent = SGData['SGCen'][Cent]
1075                    M,T = SGData['SGOps'][Opr]
1076                    for ind in indx:
1077                        XYZ = np.array(atomData[ind][cx:cx+3])
1078                        XYZ = np.inner(M,XYZ)+T
1079                        if Inv:
1080                            XYZ = -XYZ
1081                        XYZ = XYZ+cent+Cell
1082                        atom = atomData[ind]
1083                        atom[cx:cx+3] = XYZ
1084                        atom[cx+3] = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1085                            str(int(Cell[0]))+str(int(Cell[1]))+str(int(Cell[2]))
1086                        if atom[cuia] == 'A':
1087                            Uij = atom[cuij:cuij+6]
1088                            U = G2spc.Uij2U(Uij)
1089                            U = np.inner(np.inner(M,U),M)
1090                            Uij = G2spc.U2Uij(U)
1091                            atom[cuij:cuij+6] = Uij
1092                    data['Drawing']['Atoms'] = atomData
1093            finally:
1094                dlg.Destroy()
1095            UpdateDrawAtoms()
1096            G2plt.PlotStructure(self,data)
1097           
1098    def FillCoordSphere(event):
1099        generalData = data['General']
1100        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1101        radii = generalData['BondRadii']
1102        atomTypes = generalData['AtomTypes']
1103        try:
1104            indH = atomTypes.index('H')
1105            radii[indH] = 0.5
1106        except:
1107            pass           
1108        indx = drawAtoms.GetSelectedRows()
1109        if indx:
1110            indx.sort()
1111            atomData = data['Drawing']['Atoms']
1112            numAtoms = len(atomData)
1113            cx,ct,cs = data['Drawing']['atomPtrs']
1114            generalData = data['General']
1115            SGData = generalData['SGData']
1116            cellArray = G2lat.CellBlock(1)
1117            for ind in indx:
1118                atomA = atomData[ind]
1119                xyzA = np.array(atomA[cx:cx+3])
1120                indA = atomTypes.index(atomA[ct])
1121                for atomB in atomData[:numAtoms]:
1122                    indB = atomTypes.index(atomB[ct])
1123                    sumR = radii[indA]+radii[indB]
1124                    xyzB = np.array(atomB[cx:cx+3])
1125                    for xyz in cellArray+xyzB:
1126                        dist = np.sqrt(np.sum(np.inner(Amat,xyz-xyzA)**2))
1127                        if 0 < dist <= 0.85*sumR:
1128                            if noDuplicate(xyz,atomData):
1129                                newAtom = atomB[:]
1130                                newAtom[cx:cx+3] = xyz
1131                                atomData.append(newAtom)
1132            data['Drawing']['Atoms'] = atomData
1133            UpdateDrawAtoms()
1134            FindBonds()
1135            G2plt.PlotStructure(self,data)
1136           
1137    def FillUnitCell(event):
1138        indx = drawAtoms.GetSelectedRows()
1139        indx.sort()
1140        if indx:
1141            atomData = data['Drawing']['Atoms']
1142            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1143            cx = colLabels.index('x')
1144            cuia = colLabels.index('I/A')
1145            cuij = cuia+2
1146            generalData = data['General']
1147            SGData = generalData['SGData']
1148            for ind in indx:
1149                atom = atomData[ind]
1150                XYZ = np.array(atom[cx:cx+3])
1151                if atom[cuia] == 'A':
1152                    Uij = atom[cuij:cuij+6]
1153                    result = G2spc.GenAtom(XYZ,SGData,False,Uij)
1154                    for item in result:
1155                        atom = copy.copy(atomData[ind])
1156                        atom[cx:cx+3] = item[0]
1157                        atom[cx+3] = str(item[2])+'+000'
1158                        atom[cuij:cuij+6] = item[1]
1159                        Opp = G2spc.Opposite(item[0])
1160                        for xyz in Opp:
1161                            if noDuplicate(xyz,atomData):
1162                                atom[cx:cx+3] = xyz
1163                                atomData.append(atom[:])
1164                else:
1165                    result = G2spc.GenAtom(XYZ,SGData,False)
1166                    for item in result:
1167                        atom = copy.copy(atomData[ind])
1168                        atom[cx:cx+3] = item[0]
1169                        atom[cx+3] = str(item[1])+'+000'
1170                        Opp = G2spc.Opposite(item[0])
1171                        for xyz in Opp:
1172                            if noDuplicate(xyz,atomData):
1173                                atom[cx:cx+3] = xyz
1174                                atomData.append(atom[:])               
1175                data['Drawing']['Atoms'] = atomData
1176               
1177            UpdateDrawAtoms()
1178            G2plt.PlotStructure(self,data)
1179           
1180    def FindBondsToo():                         #works but slow for large structures - keep as reference
1181        cx,ct,cs = data['Drawing']['atomPtrs']
1182        atomData = data['Drawing']['Atoms']
1183        generalData = data['General']
1184        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1185        radii = generalData['BondRadii']
1186        atomTypes = generalData['AtomTypes']
1187        try:
1188            indH = atomTypes.index('H')
1189            radii[indH] = 0.5
1190        except:
1191            pass           
1192        for atom in atomData:
1193            atom[-1] = []
1194        Atoms = []
1195        for i,atom in enumerate(atomData):
1196            Atoms.append([i,np.array(atom[cx:cx+3]),atom[cs],radii[atomTypes.index(atom[ct])]])
1197        for atomA in Atoms:
1198            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
1199                for atomB in Atoms:                   
1200                    Dx = atomB[1]-atomA[1]
1201                    DX = np.inner(Amat,Dx)
1202                    dist = np.sqrt(np.sum(DX**2))
1203                    sumR = atomA[3]+atomB[3]
1204                    if 0.5 < dist <= 0.85*sumR:
1205                        i = atomA[0]
1206                        if atomA[2] == 'polyhedra':
1207                            atomData[i][-1].append(DX)
1208                        elif atomB[1] != 'polyhedra':
1209                            j = atomB[0]
1210                            atomData[i][-1].append(Dx*atomA[3]/sumR)
1211                            atomData[j][-1].append(-Dx*atomB[3]/sumR)
1212                   
1213    def FindBonds():                    #uses numpy & masks - very fast even for proteins!
1214        import numpy.ma as ma
1215        cx,ct,cs = data['Drawing']['atomPtrs']
1216        atomData = data['Drawing']['Atoms']
1217        generalData = data['General']
1218        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1219        radii = generalData['BondRadii']
1220        atomTypes = generalData['AtomTypes']
1221        try:
1222            indH = atomTypes.index('H')
1223            radii[indH] = 0.5
1224        except:
1225            pass           
1226        for atom in atomData:
1227            atom[-1] = []               #clear out old bonds
1228        Indx = range(len(atomData))
1229        Atoms = []
1230        Types = []
1231        Radii = []
1232        for atom in atomData:
1233            Atoms.append(np.array(atom[cx:cx+3]))
1234            Types.append(atom[cs])
1235            Radii.append(radii[atomTypes.index(atom[ct])])
1236        Atoms = np.array(Atoms)
1237        Radii = np.array(Radii)
1238        IATR = zip(Indx,Atoms,Types,Radii)
1239        for atomA in IATR:
1240            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
1241                Dx = Atoms-atomA[1]
1242                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
1243                sumR = atomA[3]+Radii
1244                IndB = ma.nonzero(ma.masked_greater(dist-0.85*sumR,0.))                 #get indices of bonded atoms
1245                i = atomA[0]
1246                for j in IndB[0]:
1247                    if j > i:
1248                        if Types[i] == 'polyhedra':
1249                            atomData[i][-1].append(np.inner(Amat,Dx[j]))
1250                        elif Types[j] != 'polyhedra':
1251                            atomData[i][-1].append(Dx[j]*Radii[i]/sumR[j])
1252                            atomData[j][-1].append(-Dx[j]*Radii[j]/sumR[j])
1253
1254    def DrawAtomsDelete(event):   
1255        indx = drawAtoms.GetSelectedRows()
1256        indx.sort()
1257        if indx:
1258            atomData = data['Drawing']['Atoms']
1259            indx.reverse()
1260            for ind in indx:
1261                atom = atomData[ind]
1262                del atomData[ind]
1263            UpdateDrawAtoms()
1264            G2plt.PlotStructure(self,data)
1265        event.StopPropagation()
1266
1267    def UpdateDrawOptions():
1268        import copy
1269        import wx.lib.colourselect as wcs
1270        self.dataFrame.setSizePosLeft([300,430])
1271        generalData = data['General']
1272        SetupDrawingData()
1273        drawingData = data['Drawing']
1274        if generalData['Type'] == 'nuclear':
1275            pickChoice = ['Atoms','Bonds','Torsions','Planes']
1276        elif generalData['Type'] == 'macromolecular':
1277            pickChoice = ['Atoms','Residues','Chains','Bonds','Torsions','Planes','phi/psi']
1278
1279        def OnZclip(event):
1280            drawingData['Zclip'] = Zclip.GetValue()
1281            ZclipTxt.SetLabel('Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1282            G2plt.PlotStructure(self,data)
1283           
1284        def OnCameraPos(event):
1285            drawingData['cameraPos'] = cameraPos.GetValue()
1286            cameraPosTxt.SetLabel('Camera Position: '+'%.2f'%(drawingData['cameraPos']))
1287            ZclipTxt.SetLabel('Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1288            G2plt.PlotStructure(self,data)
1289
1290        def OnBackColor(event):
1291            drawingData['backColor'] = event.GetValue()
1292            G2plt.PlotStructure(self,data)
1293
1294
1295        def OnBallScale(event):
1296            drawingData['ballScale'] = ballScale.GetValue()/100.
1297            ballScaleTxt.SetLabel('Ball scale: '+'%.2f'%(drawingData['ballScale']))
1298            G2plt.PlotStructure(self,data)
1299
1300        def OnVdWScale(event):
1301            drawingData['vdwScale'] = vdwScale.GetValue()/100.
1302            vdwScaleTxt.SetLabel('van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
1303            G2plt.PlotStructure(self,data)
1304
1305        def OnEllipseProb(event):
1306            drawingData['ellipseProb'] = ellipseProb.GetValue()
1307            ellipseProbTxt.SetLabel('Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
1308            G2plt.PlotStructure(self,data)
1309
1310        def OnBondRadius(event):
1311            drawingData['bondRadius'] = bondRadius.GetValue()/100.
1312            bondRadiusTxt.SetLabel('Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
1313            G2plt.PlotStructure(self,data)
1314
1315        def OnShowABC(event):
1316            drawingData['showABC'] = showABC.GetValue()
1317            G2plt.PlotStructure(self,data)
1318
1319        def OnShowUnitCell(event):
1320            drawingData['unitCellBox'] = unitCellBox.GetValue()
1321            G2plt.PlotStructure(self,data)
1322
1323        def OnShowBadContacts(event):
1324            drawingData['showBadContacts'] = showBadContacts.GetValue()
1325
1326        def OnShowSymElem(event):
1327            drawingData['showSymElem'] = showSymElem.GetValue()
1328
1329        def OnShowHyd(event):
1330            drawingData['showHydrogen'] = showHydrogen.GetValue()
1331            G2plt.PlotStructure(self,data)
1332
1333        def OnSizeHatoms(event):
1334            try:
1335                value = max(0.1,min(1.2,float(sizeH.GetValue())))
1336            except ValueError:
1337                value = 0.5
1338            drawingData['sizeH'] = value
1339            sizeH.SetValue("%.2f"%(value))
1340            G2plt.PlotStructure(self,data)
1341
1342        def OnPickItem(event):
1343            drawingData['pickItem'] = pickChoice[pickItem.GetSelection()]
1344
1345        dataDisplay = wx.Panel(drawOptions)
1346        mainSizer = wx.BoxSizer(wx.VERTICAL)
1347        mainSizer.Add((5,5),0)
1348        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Drawing controls:'),0,wx.ALIGN_CENTER_VERTICAL)
1349        mainSizer.Add((5,5),0)
1350       
1351        slopSizer = wx.BoxSizer(wx.HORIZONTAL)
1352        slideSizer = wx.FlexGridSizer(6,2,5,0)
1353        slideSizer.AddGrowableCol(1,1)
1354
1355        cameraPosTxt = wx.StaticText(dataDisplay,-1,
1356            'Camera Position: '+'%.2f'%(drawingData['cameraPos']),name='cameraPos')
1357        slideSizer.Add(cameraPosTxt,0,wx.ALIGN_CENTER_VERTICAL)
1358        cameraPos = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['cameraPos'],name='cameraSlider')
1359        cameraPos.SetRange(10,500)
1360        cameraPos.Bind(wx.EVT_SLIDER, OnCameraPos)
1361        slideSizer.Add(cameraPos,1,wx.EXPAND|wx.RIGHT)
1362       
1363        ZclipTxt = wx.StaticText(dataDisplay,-1,'Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1364        slideSizer.Add(ZclipTxt,0,wx.ALIGN_CENTER_VERTICAL)
1365        Zclip = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['Zclip'])
1366        Zclip.SetRange(1,99)
1367        Zclip.Bind(wx.EVT_SLIDER, OnZclip)
1368        slideSizer.Add(Zclip,1,wx.EXPAND|wx.RIGHT)
1369       
1370        vdwScaleTxt = wx.StaticText(dataDisplay,-1,'van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
1371        slideSizer.Add(vdwScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
1372        vdwScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['vdwScale']))
1373        vdwScale.Bind(wx.EVT_SLIDER, OnVdWScale)
1374        slideSizer.Add(vdwScale,1,wx.EXPAND|wx.RIGHT)
1375
1376        ellipseProbTxt = wx.StaticText(dataDisplay,-1,'Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
1377        slideSizer.Add(ellipseProbTxt,0,wx.ALIGN_CENTER_VERTICAL)
1378        ellipseProb = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['ellipseProb'])
1379        ellipseProb.SetRange(1,99)
1380        ellipseProb.Bind(wx.EVT_SLIDER, OnEllipseProb)
1381        slideSizer.Add(ellipseProb,1,wx.EXPAND|wx.RIGHT)
1382
1383        ballScaleTxt = wx.StaticText(dataDisplay,-1,'Ball scale: '+'%.2f'%(drawingData['ballScale']))
1384        slideSizer.Add(ballScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
1385        ballScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['ballScale']))
1386        ballScale.Bind(wx.EVT_SLIDER, OnBallScale)
1387        slideSizer.Add(ballScale,1,wx.EXPAND|wx.RIGHT)
1388
1389        bondRadiusTxt = wx.StaticText(dataDisplay,-1,'Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
1390        slideSizer.Add(bondRadiusTxt,0,wx.ALIGN_CENTER_VERTICAL)
1391        bondRadius = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['bondRadius']))
1392        bondRadius.SetRange(1,25)
1393        bondRadius.Bind(wx.EVT_SLIDER, OnBondRadius)
1394        slideSizer.Add(bondRadius,1,wx.EXPAND|wx.RIGHT)
1395       
1396        slopSizer.Add(slideSizer,1,wx.EXPAND|wx.RIGHT)
1397        slopSizer.Add((10,5),0)
1398        slopSizer.SetMinSize(wx.Size(300,180))
1399        mainSizer.Add(slopSizer,1,wx.EXPAND)
1400
1401        flexSizer = wx.FlexGridSizer(6,2,5,0)
1402        flexSizer.Add(wx.StaticText(dataDisplay,-1,'View Point:  '),0,wx.ALIGN_CENTER_VERTICAL)
1403        VP = drawingData['viewPoint'][0]
1404        viewPoint = wx.TextCtrl(dataDisplay,value='%.3f, %.3f, %.3f'%(VP[0],VP[1],VP[2]),
1405            style=wx.TE_READONLY,size=wx.Size(120,20),name='viewPoint')
1406        viewPoint.SetBackgroundColour(VERY_LIGHT_GREY)
1407        flexSizer.Add(viewPoint,0,wx.ALIGN_CENTER_VERTICAL)
1408       
1409        lineSizer = wx.BoxSizer(wx.HORIZONTAL)
1410        lineSizer.Add(wx.StaticText(dataDisplay,-1,'Background color:'),0,wx.ALIGN_CENTER_VERTICAL)
1411        backColor = wcs.ColourSelect(dataDisplay, -1,colour=drawingData['backColor'],size=wx.Size(25,25))
1412        backColor.Bind(wcs.EVT_COLOURSELECT, OnBackColor)
1413        lineSizer.Add(backColor,0,wx.ALIGN_CENTER_VERTICAL)
1414        flexSizer.Add(lineSizer,0,)
1415
1416        showABC = wx.CheckBox(dataDisplay,-1,label='Show test point?')
1417        showABC.Bind(wx.EVT_CHECKBOX, OnShowABC)
1418        showABC.SetValue(drawingData['showABC'])
1419        flexSizer.Add(showABC,0,wx.ALIGN_CENTER_VERTICAL)
1420
1421        unitCellBox = wx.CheckBox(dataDisplay,-1,label='Show unit cell?')
1422        unitCellBox.Bind(wx.EVT_CHECKBOX, OnShowUnitCell)
1423        unitCellBox.SetValue(drawingData['unitCellBox'])
1424        flexSizer.Add(unitCellBox,0,wx.ALIGN_CENTER_VERTICAL)
1425
1426        showBadContacts = wx.CheckBox(dataDisplay,-1,label='Show bad contacts?')
1427        showBadContacts.Bind(wx.EVT_CHECKBOX, OnShowBadContacts)
1428        showBadContacts.SetValue(drawingData['showBadContacts'])
1429        flexSizer.Add(showBadContacts,0,wx.ALIGN_CENTER_VERTICAL)
1430
1431        showSymElem = wx.CheckBox(dataDisplay,-1,label='Show sym. elem.?')
1432        showSymElem.Bind(wx.EVT_CHECKBOX, OnShowSymElem)
1433        showSymElem.SetValue(drawingData['showSymElem'])
1434        flexSizer.Add(showSymElem,0,wx.ALIGN_CENTER_VERTICAL)
1435
1436        showHydrogen = wx.CheckBox(dataDisplay,-1,label='Show hydrogens?')
1437        showHydrogen.Bind(wx.EVT_CHECKBOX, OnShowHyd)
1438        showHydrogen.SetValue(drawingData['showHydrogen'])
1439        flexSizer.Add(showHydrogen,0,wx.ALIGN_CENTER_VERTICAL)
1440
1441        flexSizer.Add(wx.StaticText(dataDisplay,-1,'Hydrogen radius, A:  '),0,wx.ALIGN_CENTER_VERTICAL)
1442        sizeH = wx.TextCtrl(dataDisplay,-1,value='%.2f'%(drawingData['sizeH']),style=wx.TE_PROCESS_ENTER)
1443        sizeH.Bind(wx.EVT_TEXT_ENTER,OnSizeHatoms)
1444        sizeH.Bind(wx.EVT_KILL_FOCUS,OnSizeHatoms)
1445        flexSizer.Add(sizeH,0,wx.ALIGN_CENTER_VERTICAL)
1446
1447        flexSizer.Add(wx.StaticText(dataDisplay,-1,'Pick items on drawing by:  '),0,wx.ALIGN_CENTER_VERTICAL)
1448        pickItem = wx.Choice(dataDisplay,-1,choices=pickChoice)
1449        pickItem.Bind(wx.EVT_CHOICE, OnPickItem)
1450        pickItem.SetSelection(pickChoice.index(drawingData['pickItem']))
1451        flexSizer.Add(pickItem,0,wx.ALIGN_CENTER_VERTICAL)
1452        mainSizer.Add(flexSizer,0,)
1453#        mainSizer.SetMinSize(wx.Size(300,340))          #to get sliders long enough
1454
1455        dataDisplay.SetSizer(mainSizer)
1456        self.dataFrame.SetSize(dataDisplay.Fit())
1457
1458    def FillPawleyReflectionsGrid():
1459        generalData = data['General']
1460
1461        print 'Pawley reflections'
1462
1463    def OnPageChanged(event):
1464        page = event.GetSelection()
1465        text = self.dataDisplay.GetPageText(page)
1466        if text == 'Atoms':
1467            self.dataFrame.SetMenuBar(self.dataFrame.AtomsMenu)
1468            self.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
1469            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestAdd, id=G2gd.wxID_ATOMSTESTADD)
1470            self.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
1471            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestInsert, id=G2gd.wxID_ATONTESTINSERT)
1472            self.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
1473            self.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
1474            self.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
1475            self.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
1476            FillAtomsGrid()
1477        elif text == 'General':
1478            FillGeneralGrid()
1479            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1480        elif text == 'Draw Options':
1481            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1482            UpdateDrawOptions()
1483            G2plt.PlotStructure(self,data)
1484        elif text == 'Draw Atoms':
1485            self.dataFrame.SetMenuBar(self.dataFrame.DrawAtomsMenu)
1486            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE)
1487            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL)
1488            self.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT)
1489            self.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV)
1490            self.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM)
1491            self.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD)           
1492            self.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL)
1493            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE)
1494            UpdateDrawAtoms()
1495            G2plt.PlotStructure(self,data)
1496        else:
1497            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1498        event.Skip()
1499
1500    if self.dataDisplay:
1501        self.dataDisplay.Destroy()
1502    PhaseName = self.PatternTree.GetItemText(item)
1503    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1504    self.dataFrame.SetLabel('Phase Data for '+PhaseName)
1505    self.dataFrame.CreateStatusBar()
1506    self.dataDisplay = G2gd.GSNoteBook(parent=self.dataFrame,size=self.dataFrame.GetClientSize())
1507
1508    General = G2gd.GSGrid(self.dataDisplay)
1509    FillGeneralGrid()
1510    self.dataDisplay.AddPage(General,'General')
1511
1512    GeneralData = data['General']
1513    if GeneralData['Type'] == 'Pawley':
1514        PawleyRefl = G2gd.GSGrid(self.dataDisplay)
1515        self.dataDisplay.AddPage(PawleyRefl,'Pawley reflections')
1516    else:
1517        Atoms = G2gd.GSGrid(self.dataDisplay)
1518        self.dataDisplay.AddPage(Atoms,'Atoms')
1519        drawOptions = wx.Window(self.dataDisplay)
1520        self.dataDisplay.AddPage(drawOptions,'Draw Options')
1521        drawAtoms = G2gd.GSGrid(self.dataDisplay)
1522        self.dataDisplay.AddPage(drawAtoms,'Draw Atoms')
1523
1524    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
1525    self.dataDisplay.SetSelection(oldPage)
1526   
1527           
Note: See TracBrowser for help on using the repository browser.