source: trunk/GSASIIphsGUI.py @ 458

Last change on this file since 458 was 458, checked in by vondreele, 10 years ago

finish dist angle calculations

  • Property svn:keywords set to Date Author Revision URL Id
File size: 148.1 KB
Line 
1#GSASII - phase data display routines
2########### SVN repository information ###################
3# $Date: 2012-01-27 22:43:30 +0000 (Fri, 27 Jan 2012) $
4# $Author: vondreele $
5# $Revision: 458 $
6# $URL: trunk/GSASIIphsGUI.py $
7# $Id: GSASIIphsGUI.py 458 2012-01-27 22:43:30Z vondreele $
8########### SVN repository information ###################
9import wx
10import wx.grid as wg
11import matplotlib as mpl
12import math
13import copy
14import time
15import sys
16import random as ran
17import cPickle
18import GSASIIpath
19import GSASIIlattice as G2lat
20import GSASIIspc as G2spc
21import GSASIIElem as G2elem
22import GSASIIplot as G2plt
23import GSASIIgrid as G2gd
24import GSASIIIO as G2IO
25import GSASIIstruct as G2str
26import numpy as np
27import numpy.linalg as nl
28
29VERY_LIGHT_GREY = wx.Colour(235,235,235)
30WHITE = wx.Colour(255,255,255)
31BLACK = wx.Colour(0,0,0)
32
33# trig functions in degrees
34sind = lambda x: math.sin(x*math.pi/180.)
35tand = lambda x: math.tan(x*math.pi/180.)
36cosd = lambda x: math.cos(x*math.pi/180.)
37asind = lambda x: 180.*math.asin(x)/math.pi
38
39class SymOpDialog(wx.Dialog):
40    def __init__(self,parent,SGData,New=True):
41        wx.Dialog.__init__(self,parent,-1,'Select symmetry operator',
42            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
43        panel = wx.Panel(self)
44        self.SGData = SGData
45        self.New = New
46        self.OpSelected = [0,0,0,[0,0,0],False]
47        mainSizer = wx.BoxSizer(wx.VERTICAL)
48        mainSizer.Add((5,5),0)
49        if SGData['SGInv']:
50            choice = ['No','Yes']
51            self.inv = wx.RadioBox(panel,-1,'Choose inversion?',choices=choice)
52            self.inv.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
53            mainSizer.Add(self.inv,0,wx.ALIGN_CENTER_VERTICAL)
54        mainSizer.Add((5,5),0)
55        if SGData['SGLatt'] != 'P':
56            LattOp = G2spc.Latt2text(SGData['SGLatt']).split(';')
57            self.latt = wx.RadioBox(panel,-1,'Choose cell centering?',choices=LattOp)
58            self.latt.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
59            mainSizer.Add(self.latt,0,wx.ALIGN_CENTER_VERTICAL)
60        mainSizer.Add((5,5),0)
61        if SGData['SGLaue'] in ['-1','2/m','mmm','4/m','4/mmm']:
62            Ncol = 2
63        else:
64            Ncol = 3
65        OpList = []
66        for M,T in SGData['SGOps']:
67            OpList.append(G2spc.MT2text(M,T))
68        self.oprs = wx.RadioBox(panel,-1,'Choose space group operator?',choices=OpList,
69            majorDimension=Ncol)
70        self.oprs.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
71        mainSizer.Add(self.oprs,0,wx.ALIGN_CENTER_VERTICAL)
72        mainSizer.Add((5,5),0)
73        mainSizer.Add(wx.StaticText(panel,-1,"   Choose unit cell?"),0,wx.ALIGN_CENTER_VERTICAL)
74        mainSizer.Add((5,5),0)
75        cellSizer = wx.BoxSizer(wx.HORIZONTAL)
76        cellSizer.Add((5,0),0)
77        cellName = ['X','Y','Z']
78        self.cell = []
79        for i in range(3):
80            self.cell.append(wx.SpinCtrl(panel,-1,cellName[i],size=wx.Size(50,20)))
81            self.cell[-1].SetRange(-3,3)
82            self.cell[-1].SetValue(0)
83            self.cell[-1].Bind(wx.EVT_SPINCTRL, self.OnOpSelect)
84            cellSizer.Add(self.cell[-1],0,wx.ALIGN_CENTER_VERTICAL)
85        mainSizer.Add(cellSizer,0,)
86        if self.New:
87            choice = ['No','Yes']
88            self.new = wx.RadioBox(panel,-1,'Generate new positions?',choices=choice)
89            self.new.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
90            mainSizer.Add(self.new,0,wx.ALIGN_CENTER_VERTICAL)
91        mainSizer.Add((5,5),0)
92
93        OkBtn = wx.Button(panel,-1,"Ok")
94        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
95        cancelBtn = wx.Button(panel,-1,"Cancel")
96        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
97        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
98        btnSizer.Add((20,20),1)
99        btnSizer.Add(OkBtn)
100        btnSizer.Add((20,20),1)
101        btnSizer.Add(cancelBtn)
102        btnSizer.Add((20,20),1)
103
104        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
105        panel.SetSizer(mainSizer)
106        panel.Fit()
107        self.Fit()
108
109    def OnOpSelect(self,event):
110        if self.SGData['SGInv']:
111            self.OpSelected[0] = self.inv.GetSelection()
112        if self.SGData['SGLatt'] != 'P':
113            self.OpSelected[1] = self.latt.GetSelection()
114        self.OpSelected[2] = self.oprs.GetSelection()
115        for i in range(3):
116            self.OpSelected[3][i] = float(self.cell[i].GetValue())
117        if self.New:
118            self.OpSelected[4] = self.new.GetSelection()
119
120    def GetSelection(self):
121        return self.OpSelected
122
123    def OnOk(self,event):
124        parent = self.GetParent()
125        parent.Raise()
126        self.EndModal(wx.ID_OK)
127        self.Destroy()
128
129    def OnCancel(self,event):
130        parent = self.GetParent()
131        parent.Raise()
132        self.EndModal(wx.ID_CANCEL)
133        self.Destroy()
134
135class DisAglDialog(wx.Dialog):
136    def __init__(self,parent,data):
137        wx.Dialog.__init__(self,parent,-1,'Distance Angle Controls', 
138            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
139        self.data = data
140        panel = wx.Panel(self)
141        mainSizer = wx.BoxSizer(wx.VERTICAL)
142        mainSizer.Add(wx.StaticText(panel,-1,'Controls for phase '+data['Name']),
143            0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
144        mainSizer.Add((10,10),1)
145       
146        radiiSizer = wx.FlexGridSizer(2,3,5,5)
147        radiiSizer.Add(wx.StaticText(panel,-1,' Type'),0,wx.ALIGN_CENTER_VERTICAL)
148        radiiSizer.Add(wx.StaticText(panel,-1,'Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
149        radiiSizer.Add(wx.StaticText(panel,-1,'Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
150        self.objList = {}
151        for id,item in enumerate(self.data['AtomTypes']):
152            radiiSizer.Add(wx.StaticText(panel,-1,' '+item),0,wx.ALIGN_CENTER_VERTICAL)
153            bRadii = wx.TextCtrl(panel,-1,value='%.3f'%(data['BondRadii'][id]),style=wx.TE_PROCESS_ENTER)
154            self.objList[bRadii.GetId()] = ['BondRadii',id]
155            bRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
156            bRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
157            radiiSizer.Add(bRadii,0,wx.ALIGN_CENTER_VERTICAL)
158            aRadii = wx.TextCtrl(panel,-1,value='%.3f'%(data['AngleRadii'][id]),style=wx.TE_PROCESS_ENTER)
159            self.objList[aRadii.GetId()] = ['AngleRadii',id]
160            aRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
161            aRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
162            radiiSizer.Add(aRadii,0,wx.ALIGN_CENTER_VERTICAL)
163        mainSizer.Add(radiiSizer,0,wx.EXPAND)
164        factorSizer = wx.FlexGridSizer(2,2,5,5)
165        Names = ['Bond','Angle']
166        for i,name in enumerate(Names):
167            factorSizer.Add(wx.StaticText(panel,-1,name+' search factor'),0,wx.ALIGN_CENTER_VERTICAL)
168            bondFact = wx.TextCtrl(panel,-1,value='%.3f'%(data['Factors'][i]),style=wx.TE_PROCESS_ENTER)
169            self.objList[bondFact.GetId()] = ['Factors',i]
170            bondFact.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
171            bondFact.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
172            factorSizer.Add(bondFact)
173        mainSizer.Add(factorSizer,0,wx.EXPAND)
174       
175        OkBtn = wx.Button(panel,-1,"Ok")
176        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
177        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
178        btnSizer.Add((20,20),1)
179        btnSizer.Add(OkBtn)
180        btnSizer.Add((20,20),1)       
181        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
182        panel.SetSizer(mainSizer)
183        panel.Fit()
184        self.Fit()
185   
186    def OnRadiiVal(self,event):
187        Obj = event.GetEventObject()
188        item = self.objList[Obj.GetId()]
189        try:
190            self.data[item[0]][item[1]] = float(Obj.GetValue())
191        except ValueError:
192            pass
193        Obj.SetValue("%.3f"%(self.data[item[0]][item[1]]))          #reset in case of error
194       
195    def getData(self):
196        return self.Data
197       
198    def OnOk(self,event):
199        parent = self.GetParent()
200        parent.Raise()
201        self.EndModal(wx.ID_OK)             
202        self.Destroy()
203       
204def UpdatePhaseData(self,Item,data,oldPage):
205
206    Atoms = []
207    if self.dataDisplay:
208        self.dataDisplay.Destroy()
209    PhaseName = self.PatternTree.GetItemText(Item)
210    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
211    self.dataFrame.SetLabel('Phase Data for '+PhaseName)
212    self.dataFrame.CreateStatusBar()
213    self.dataDisplay = G2gd.GSNoteBook(parent=self.dataFrame,size=self.dataFrame.GetClientSize())
214
215    def SetupGeneral():
216        generalData = data['General']
217        atomData = data['Atoms']
218        generalData['AtomTypes'] = []
219        generalData['Isotopes'] = {}
220        if 'Isotope' not in generalData:
221            generalData['Isotope'] = {}
222        if 'Data plot type' not in generalData:
223            generalData['Data plot type'] = 'Mustrain'
224        if 'POhkl' not in generalData:
225            generalData['POhkl'] = [0,0,1]
226        generalData['NoAtoms'] = {}
227        generalData['BondRadii'] = []
228        generalData['AngleRadii'] = []
229        generalData['vdWRadii'] = []
230        generalData['AtomMass'] = []
231        generalData['Color'] = []
232        generalData['Mydir'] = self.dirname
233        cx,ct,cs,cia = [3,1,7,9]
234        generalData['AtomPtrs'] = [cx,ct,cs,cia]
235        if generalData['Type'] =='macromolecular':
236            cx,ct,cs,cia = [6,4,10,12]
237            generalData['AtomPtrs'] = [cx,ct,cs,cia]
238        for atom in atomData:
239            atom[ct] = atom[ct].lower().capitalize()              #force to standard form
240            if generalData['AtomTypes'].count(atom[ct]):
241                generalData['NoAtoms'][atom[ct]] += atom[cs-1]*float(atom[cs+1])
242            elif atom[ct] != 'UNK':
243                Info = G2elem.GetAtomInfo(atom[ct])
244                generalData['AtomTypes'].append(atom[ct])
245                generalData['Isotopes'][atom[ct]] = Info['Isotopes']
246                generalData['BondRadii'].append(Info['Drad'])
247                generalData['AngleRadii'].append(Info['Arad'])
248                generalData['vdWRadii'].append(Info['Vdrad'])
249                if atom[ct] in generalData['Isotope']:
250                    generalData['AtomMass'].append(Info['Isotopes'][generalData['Isotope'][atom[ct]]][0])
251                else:
252                    generalData['AtomMass'].append(Info['Mass'])
253                generalData['NoAtoms'][atom[ct]] = atom[cs-1]*float(atom[cs+1])
254                generalData['Color'].append(Info['Color'])
255
256    def UpdateGeneral():
257       
258        ''' default dictionary structure for phase data: (taken from GSASII.py)
259        'General':{
260            'Name':PhaseName
261            'Type':'nuclear'
262            'SGData':SGData
263            'Cell':[False,10.,10.,10.,90.,90.,90,1000.]
264            'AtomPtrs':[]
265            'Histogram list':['',]
266            'Pawley dmin':1.0}
267        'Atoms':[]
268        'Drawing':{}
269        '''
270        self.dataFrame.SetMenuBar(self.dataFrame.DataGeneral) # do this here, since this is called from all over
271       
272        phaseTypes = ['nuclear','modulated','magnetic','macromolecular','Pawley']
273        SetupGeneral()
274        generalData = data['General']
275       
276        def OnPhaseName(event):
277            oldName = generalData['Name']
278            generalData['Name'] = NameTxt.GetValue()
279            self.G2plotNB.Rename(oldName,generalData['Name'])
280            self.dataFrame.SetLabel('Phase Data for '+generalData['Name'])
281            self.PatternTree.SetItemText(Item,generalData['Name'])
282            #Hmm, need to change phase name key in Reflection Lists for each histogram
283                       
284        def OnPhaseType(event):
285            if not generalData['AtomTypes']:             #can change only if no atoms!
286                generalData['Type'] = TypeTxt.GetValue()
287                dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
288                UpdateGeneral()         #must use this way!
289                if generalData['Type'] == 'Pawley':
290                    if self.dataDisplay.FindPage('Atoms'):
291                        self.dataDisplay.DeletePage(self.dataDisplay.FindPage('Atoms'))
292                        self.dataDisplay.DeletePage(self.dataDisplay.FindPage('Draw Options'))
293                        self.dataDisplay.DeletePage(self.dataDisplay.FindPage('Draw Atoms'))
294                    if not self.dataDisplay.FindPage('Pawley reflections'):
295                        self.PawleyRefl = G2gd.GSGrid(self.dataDisplay)     
296                        self.dataDisplay.AddPage(self.PawleyRefl,'Pawley reflections')
297            else:
298                TypeTxt.SetValue(generalData['Type'])               
299               
300        def OnSpaceGroup(event):
301            SpcGp = SGTxt.GetValue()
302            SGErr,SGData = G2spc.SpcGroup(SpcGp)
303            if SGErr:
304                text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous']
305                SGTxt.SetValue(generalData['SGData']['SpGrp'])
306                msg = 'Space Group Error'
307                Style = wx.ICON_EXCLAMATION
308            else:
309                text = G2spc.SGPrint(SGData)
310                generalData['SGData'] = SGData
311                msg = 'Space Group Information'
312                Style = wx.ICON_INFORMATION
313            Text = ''
314            for line in text:
315                Text += line+'\n'
316            wx.MessageBox(Text,caption=msg,style=Style)
317            dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
318            UpdateGeneral()
319           
320        def OnCellRef(event):
321            generalData['Cell'][0] = cellRef.GetValue()
322           
323        def OnCellChange(event):
324            SGData = generalData['SGData']
325            laue = SGData['SGLaue']
326            if laue == '2/m':
327                laue += SGData['SGUniq']
328            cell = generalData['Cell']
329            Obj = event.GetEventObject()
330            ObjId = cellList.index(Obj.GetId())
331            try:
332                value = max(1.0,float(Obj.GetValue()))
333            except ValueError:
334                if ObjId < 3:               #bad cell edge - reset
335                    value = controls[6+ObjId]
336                else:                       #bad angle
337                    value = 90.
338            if laue in ['m3','m3m']:
339                cell[1] = cell[2] = cell[3] = value
340                cell[4] = cell[5] = cell[6] = 90.0
341                Obj.SetValue("%.5f"%(cell[1]))
342            elif laue in ['3R','3mR']:
343                if ObjId == 0:
344                    cell[1] = cell[2] = cell[3] = value
345                    Obj.SetValue("%.5f"%(cell[1]))
346                else:
347                    cell[4] = cell[5] = cell[6] = value
348                    Obj.SetValue("%.5f"%(cell[4]))
349            elif laue in ['3','3m1','31m','6/m','6/mmm','4/m','4/mmm']:                   
350                cell[4] = cell[5] = 90.
351                cell[6] = 120.
352                if ObjId == 0:
353                    cell[1] = cell[2] = value
354                    Obj.SetValue("%.5f"%(cell[1]))
355                else:
356                    cell[3] = value
357                    Obj.SetValue("%.5f"%(cell[3]))
358            elif laue in ['mmm']:
359                cell[ObjId+1] = value
360                cell[4] = cell[5] = cell[6] = 90.
361                Obj.SetValue("%.5f"%(cell[ObjId+1]))
362            elif laue in ['2/m'+'a']:
363                cell[5] = cell[6] = 90.
364                if ObjId != 3:
365                    cell[ObjId+1] = value
366                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
367                else:
368                    cell[4] = value
369                    Obj.SetValue("%.3f"%(cell[4]))
370            elif laue in ['2/m'+'b']:
371                cell[4] = cell[6] = 90.
372                if ObjId != 3:
373                    cell[ObjId+1] = value
374                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
375                else:
376                    cell[5] = value
377                    Obj.SetValue("%.3f"%(cell[5]))
378            elif laue in ['2/m'+'c']:
379                cell[5] = cell[6] = 90.
380                if ObjId != 3:
381                    cell[ObjId+1] = value
382                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
383                else:
384                    cell[6] = value
385                    Obj.SetValue("%.3f"%(cell[6]))
386            else:
387                cell[ObjId+1] = value
388                if ObjId < 3:
389                    Obj.SetValue("%.5f"%(cell[1+ObjId]))
390                else:
391                    Obj.SetValue("%.3f"%(cell[1+ObjId]))
392            cell[7] = G2lat.calc_V(G2lat.cell2A(cell[1:7]))
393            volVal.SetValue("%.3f"%(cell[7]))
394            generalData['Cell'] = cell
395            dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
396            UpdateGeneral()
397                       
398        def OnPawleyVal(event):
399            try:
400                dmin = float(pawlVal.GetValue())
401                if 0.25 <= dmin <= 20.:
402                    generalData['Pawley dmin'] = dmin
403            except ValueError:
404                pass
405            pawlVal.SetValue("%.3f"%(generalData['Pawley dmin']))          #reset in case of error       
406           
407        def OnIsotope(event):
408            Obj = event.GetEventObject()
409            item = Indx[Obj.GetId()]
410            isotope = Obj.GetValue()
411            generalData['Isotope'][item] = isotope
412            indx = generalData['AtomTypes'].index(item)
413            data['General']['AtomMass'][indx] = generalData['Isotopes'][item][isotope][0]
414            UpdateGeneral()
415                                               
416        cellGUIlist = [[['m3','m3m'],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
417        [['3R','3mR'],6,zip([" a = "," alpha = "," Vol = "],["%.5f","%.3f","%.3f"],[True,True,False],[0,2,0])],
418        [['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])],
419        [['mmm'],8,zip([" a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
420            [True,True,True,False],[0,1,2,0])],
421        [['2/m'+'a'],10,zip([" a = "," b = "," c = "," alpha = "," Vol = "],
422            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
423        [['2/m'+'b'],10,zip([" a = "," b = "," c = "," beta = "," Vol = "],
424            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
425        [['2/m'+'c'],10,zip([" a = "," b = "," c = "," gamma = "," Vol = "],
426            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
427        [['-1'],8,zip([" a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
428            ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
429            [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
430       
431        General.DestroyChildren()
432        dataDisplay = wx.Panel(General)
433        mainSizer = wx.BoxSizer(wx.VERTICAL)
434        mainSizer.Add((5,5),0)
435        mainSizer.Add(wx.StaticText(dataDisplay,-1,'General phase data:'),0,wx.ALIGN_CENTER_VERTICAL)
436        mainSizer.Add((5,5),0)
437        nameSizer = wx.BoxSizer(wx.HORIZONTAL)
438        nameSizer.Add(wx.StaticText(dataDisplay,-1,' Phase name: '),0,wx.ALIGN_CENTER_VERTICAL)
439        NameTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['Name'],style=wx.TE_PROCESS_ENTER)
440        NameTxt.Bind(wx.EVT_TEXT_ENTER,OnPhaseName)
441        NameTxt.Bind(wx.EVT_KILL_FOCUS,OnPhaseName)
442        nameSizer.Add(NameTxt,0,wx.ALIGN_CENTER_VERTICAL)
443        nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Phase type: '),0,wx.ALIGN_CENTER_VERTICAL)
444        if len(data['Atoms']):
445            choices = phaseTypes[:-1]
446        else:
447            choices = phaseTypes           
448        TypeTxt = wx.ComboBox(dataDisplay,-1,value=generalData['Type'],choices=choices,
449            style=wx.CB_READONLY|wx.CB_DROPDOWN)
450        TypeTxt.Bind(wx.EVT_COMBOBOX, OnPhaseType)
451        nameSizer.Add(TypeTxt,0,wx.ALIGN_CENTER_VERTICAL)
452        nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Space group: '),0,wx.ALIGN_CENTER_VERTICAL)
453        SGTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['SGData']['SpGrp'],style=wx.TE_PROCESS_ENTER)
454        SGTxt.Bind(wx.EVT_TEXT_ENTER,OnSpaceGroup)
455        nameSizer.Add(SGTxt,0,wx.ALIGN_CENTER_VERTICAL)
456        mainSizer.Add(nameSizer,0)
457        mainSizer.Add((5,5),0)
458        cell = generalData['Cell']
459        laue = generalData['SGData']['SGLaue']
460        if laue == '2/m':
461            laue += generalData['SGData']['SGUniq']
462        for cellGUI in cellGUIlist:
463            if laue in cellGUI[0]:
464                useGUI = cellGUI
465        cellList = []
466        cellSizer = wx.FlexGridSizer(2,useGUI[1]+1,5,5)
467        cellRef = wx.CheckBox(dataDisplay,-1,label='Refine unit cell:')
468        cellSizer.Add(cellRef,0,wx.ALIGN_CENTER_VERTICAL)
469        cellRef.Bind(wx.EVT_CHECKBOX, OnCellRef)
470        cellRef.SetValue(cell[0])
471        for txt,fmt,ifEdit,Id in useGUI[2]:
472            cellSizer.Add(wx.StaticText(dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL)
473            if ifEdit:          #a,b,c,etc.
474                cellVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[Id+1])),
475                    style=wx.TE_PROCESS_ENTER)
476                cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
477                cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
478                cellSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL)
479                cellList.append(cellVal.GetId())
480            else:               #volume
481                volVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[7])),style=wx.TE_READONLY)
482                volVal.SetBackgroundColour(VERY_LIGHT_GREY)
483                cellSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL)
484        mainSizer.Add(cellSizer,0)
485        mainSizer.Add((5,5),0)
486       
487        Indx = {}
488        if len(generalData['AtomTypes']):
489            mass = 0.
490            for i,elem in enumerate(generalData['AtomTypes']):
491                mass += generalData['NoAtoms'][elem]*generalData['AtomMass'][i]
492            denSizer = wx.BoxSizer(wx.HORIZONTAL)
493            denSizer.Add(wx.StaticText(dataDisplay,-1,' Density: '),0,wx.ALIGN_CENTER_VERTICAL)
494            Volume = generalData['Cell'][7]
495            density = mass/(0.6022137*Volume)
496            denTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(density),style=wx.TE_READONLY)
497            denTxt.SetBackgroundColour(VERY_LIGHT_GREY)
498            denSizer.Add(denTxt,0,wx.ALIGN_CENTER_VERTICAL)       
499            if generalData['Type'] == 'macromolecular' and mass > 0.0:
500                denSizer.Add(wx.StaticText(dataDisplay,-1,' Matthews coeff.: '),
501                    0,wx.ALIGN_CENTER_VERTICAL)
502                mattTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(Volume/mass),style=wx.TE_READONLY)
503                mattTxt.SetBackgroundColour(VERY_LIGHT_GREY)
504                denSizer.Add(mattTxt,0,wx.ALIGN_CENTER_VERTICAL)
505            mainSizer.Add(denSizer)
506            mainSizer.Add((5,5),0)
507           
508            elemSizer = wx.FlexGridSizer(8,len(generalData['AtomTypes'])+1,1,1)
509            elemSizer.Add(wx.StaticText(dataDisplay,label='Elements'),0,wx.ALIGN_CENTER_VERTICAL)
510            for elem in generalData['AtomTypes']:
511                typTxt = wx.TextCtrl(dataDisplay,value=elem,style=wx.TE_READONLY)
512                typTxt.SetBackgroundColour(VERY_LIGHT_GREY)
513                elemSizer.Add(typTxt,0,wx.ALIGN_CENTER_VERTICAL)
514            elemSizer.Add(wx.StaticText(dataDisplay,label='Isotope'),0,wx.ALIGN_CENTER_VERTICAL)
515            for elem in generalData['AtomTypes']:
516                choices = generalData['Isotopes'][elem].keys()
517                if elem not in generalData['Isotope']:
518                    generalData['Isotope'][elem] = 'Nat. Abund.'
519                isoSel = wx.ComboBox(dataDisplay,-1,value=generalData['Isotope'][elem],choices=choices,
520                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
521                isoSel.Bind(wx.EVT_COMBOBOX,OnIsotope)
522                Indx[isoSel.GetId()] = elem
523                elemSizer.Add(isoSel,1,wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
524            elemSizer.Add(wx.StaticText(dataDisplay,label='No. per cell'),0,wx.ALIGN_CENTER_VERTICAL)
525            for elem in generalData['AtomTypes']:
526                numbTxt = wx.TextCtrl(dataDisplay,value='%.1f'%(generalData['NoAtoms'][elem]),
527                    style=wx.TE_READONLY)
528                numbTxt.SetBackgroundColour(VERY_LIGHT_GREY)
529                elemSizer.Add(numbTxt,0,wx.ALIGN_CENTER_VERTICAL)
530            elemSizer.Add(wx.StaticText(dataDisplay,label='Atom weight'),0,wx.ALIGN_CENTER_VERTICAL)
531            for wt in generalData['AtomMass']:
532                wtTxt = wx.TextCtrl(dataDisplay,value='%.3f'%(wt),style=wx.TE_READONLY)
533                wtTxt.SetBackgroundColour(VERY_LIGHT_GREY)
534                elemSizer.Add(wtTxt,0,wx.ALIGN_CENTER_VERTICAL)
535            elemSizer.Add(wx.StaticText(dataDisplay,label='Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
536            for rad in generalData['BondRadii']:
537                bondRadii = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
538                bondRadii.SetBackgroundColour(VERY_LIGHT_GREY)
539                elemSizer.Add(bondRadii,0,wx.ALIGN_CENTER_VERTICAL)
540            elemSizer.Add(wx.StaticText(dataDisplay,label='Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
541            for rad in generalData['AngleRadii']:
542                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
543                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
544                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
545            elemSizer.Add(wx.StaticText(dataDisplay,label='van der Waals radii'),0,wx.ALIGN_CENTER_VERTICAL)
546            for rad in generalData['vdWRadii']:
547                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
548                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
549                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
550            elemSizer.Add(wx.StaticText(dataDisplay,label='Default color'),0,wx.ALIGN_CENTER_VERTICAL)
551            for color in generalData['Color']:
552                colorTxt = wx.TextCtrl(dataDisplay,value='',style=wx.TE_READONLY)
553                colorTxt.SetBackgroundColour(color)
554                elemSizer.Add(colorTxt,0,wx.ALIGN_CENTER_VERTICAL)
555            mainSizer.Add(elemSizer)
556           
557        elif generalData['Type'] == 'Pawley':
558            pawlSizer = wx.BoxSizer(wx.HORIZONTAL)
559            pawlSizer.Add(wx.StaticText(dataDisplay,label=' Pawley dmin: '),0,wx.ALIGN_CENTER_VERTICAL)
560            pawlVal = wx.TextCtrl(dataDisplay,value='%.3f'%(generalData['Pawley dmin']),style=wx.TE_PROCESS_ENTER)
561            pawlVal.Bind(wx.EVT_TEXT_ENTER,OnPawleyVal)       
562            pawlVal.Bind(wx.EVT_KILL_FOCUS,OnPawleyVal)
563            pawlSizer.Add(pawlVal,0,wx.ALIGN_CENTER_VERTICAL)
564            mainSizer.Add(pawlSizer)
565
566        dataDisplay.SetSizer(mainSizer)
567        Size = mainSizer.Fit(self.dataFrame)
568        Size[1] += 26                           #compensate for status bar
569        dataDisplay.SetSize(Size)
570        self.dataFrame.setSizePosLeft(Size)
571
572    def FillAtomsGrid():
573
574        self.dataFrame.setSizePosLeft([700,300])
575        generalData = data['General']
576        atomData = data['Atoms']
577        Items = [G2gd.wxID_ATOMSEDITINSERT, G2gd.wxID_ATOMSEDITDELETE, G2gd.wxID_ATOMSREFINE, 
578            G2gd.wxID_ATOMSMODIFY, G2gd.wxID_ATOMSTRANSFORM, G2gd.wxID_ATONTESTINSERT]
579        if atomData:
580            for item in Items:   
581                self.dataFrame.AtomsMenu.Enable(item,True)
582        else:
583            for item in Items:
584                self.dataFrame.AtomsMenu.Enable(item,False)           
585           
586        AAchoice = ": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK"
587        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",]+ \
588            3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_FLOAT+':10,4', #x,y,z,frac
589            wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+":I,A",]
590        Types += 7*[wg.GRID_VALUE_FLOAT+':10,5',]
591        colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23']
592        if generalData['Type'] == 'magnetic':
593            colLabels += ['Mx','My','Mz']
594            Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU,"
595            Types += 3*[wg.GRID_VALUE_FLOAT+':10,4',]
596        elif generalData['Type'] == 'macromolecular':
597            colLabels = ['res no','residue','chain'] + colLabels
598            Types = [wg.GRID_VALUE_STRING,
599                wg.GRID_VALUE_CHOICE+AAchoice,
600                wg.GRID_VALUE_STRING] + Types
601        elif generalData['Type'] == 'modulated':
602            Types += []
603            colLabels += []
604
605        def RefreshAtomGrid(event):
606
607            r,c =  event.GetRow(),event.GetCol()
608            if r < 0 and c < 0:
609                for row in range(Atoms.GetNumberRows()):
610                    Atoms.SelectRow(row,True)                   
611            if r < 0:                          #double click on col label! Change all atoms!
612                sel = -1
613                noSkip = True
614                if Atoms.GetColLabelValue(c) == 'refine':
615                    Type = generalData['Type']
616                    if Type in ['nuclear','macromolecular']:
617                        choice = ['F - site fraction','X - coordinates','U - thermal parameters']
618                    elif Type in ['magnetic',]:
619                        choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
620                    dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice)
621                    if dlg.ShowModal() == wx.ID_OK:
622                        sel = dlg.GetSelections()
623                        parms = ''
624                        for x in sel:
625                            parms += choice[x][0]
626                    dlg.Destroy()
627                elif Atoms.GetColLabelValue(c) == 'I/A':
628                    choice = ['Isotropic','Anisotropic']
629                    dlg = wx.SingleChoiceDialog(self,'Select','Thermal Motion',choice)
630                    if dlg.ShowModal() == wx.ID_OK:
631                        sel = dlg.GetSelection()
632                        parms = choice[sel][0]
633                    dlg.Destroy()
634                elif Atoms.GetColLabelValue(c) == 'Type':
635                    choice = generalData['AtomTypes']
636                    dlg = wx.SingleChoiceDialog(self,'Select','Atom types',choice)
637                    if dlg.ShowModal() == wx.ID_OK:
638                        sel = dlg.GetSelection()
639                        parms = choice[sel]
640                        noSkip = False
641                        Atoms.ClearSelection()
642                        for row in range(Atoms.GetNumberRows()):
643                            if parms == atomData[row][c]:
644                                Atoms.SelectRow(row,True)
645                elif Atoms.GetColLabelValue(c) == 'residue':
646                    choice = []
647                    for r in range(Atoms.GetNumberRows()):
648                        if str(atomData[r][c]) not in choice:
649                            choice.append(str(atomData[r][c]))
650                    choice.sort()
651                    dlg = wx.SingleChoiceDialog(self,'Select','Residue',choice)
652                    if dlg.ShowModal() == wx.ID_OK:
653                        sel = dlg.GetSelection()
654                        parms = choice[sel]
655                        noSkip = False
656                        Atoms.ClearSelection()
657                        for row in range(Atoms.GetNumberRows()):
658                            if parms == atomData[row][c]:
659                                Atoms.SelectRow(row,True)
660                elif Atoms.GetColLabelValue(c) == 'res no':
661                    choice = []
662                    for r in range(Atoms.GetNumberRows()):
663                        if str(atomData[r][c]) not in choice:
664                            choice.append(str(atomData[r][c]))
665                    dlg = wx.SingleChoiceDialog(self,'Select','Residue no.',choice)
666                    if dlg.ShowModal() == wx.ID_OK:
667                        sel = dlg.GetSelection()
668                        parms = choice[sel]
669                        noSkip = False
670                        Atoms.ClearSelection()
671                        for row in range(Atoms.GetNumberRows()):
672                            if int(parms) == atomData[row][c]:
673                                Atoms.SelectRow(row,True)
674                elif Atoms.GetColLabelValue(c) == 'chain':
675                    choice = []
676                    for r in range(Atoms.GetNumberRows()):
677                        if atomData[r][c] not in choice:
678                            choice.append(atomData[r][c])
679                    dlg = wx.SingleChoiceDialog(self,'Select','Chain',choice)
680                    if dlg.ShowModal() == wx.ID_OK:
681                        sel = dlg.GetSelection()
682                        parms = choice[sel]
683                        noSkip = False
684                        Atoms.ClearSelection()
685                        for row in range(Atoms.GetNumberRows()):
686                            if parms == atomData[row][c]:
687                                Atoms.SelectRow(row,True)
688                    dlg.Destroy()
689                elif Atoms.GetColLabelValue(c) == 'Uiso':       #this needs to ask for value
690                    pass                                        #& then change all 'I' atoms
691                if sel >= 0 and noSkip:
692                    ui = colLabels.index('U11')
693                    us = colLabels.index('Uiso')
694                    ss = colLabels.index('site sym')
695                    for r in range(Atoms.GetNumberRows()):
696                        ID = atomData[r][-1]
697                        if parms != atomData[r][c] and Atoms.GetColLabelValue(c) == 'I/A':
698                            if parms == 'A':                #'I' --> 'A'
699                                Uiso = float(Atoms.GetCellValue(r,us))
700                                sytsym = atomData[r][ss]
701                                CSI = G2spc.GetCSuinel(sytsym)
702                                atomData[r][ui:ui+6] = Uiso*np.array(CSI[3])
703                                atomData[r][us] = 0.0
704                                Atoms.SetCellStyle(r,us,VERY_LIGHT_GREY,True)
705                                for i in range(6):
706                                    ci = ui+i
707                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
708                                    if CSI[2][i]:
709                                        Atoms.SetCellStyle(r,ci,WHITE,False)
710                            else:                           #'A' --> 'I'
711                                Uij = atomData[r][ui:ui+6]
712                                Uiso = (Uij[0]+Uij[1]+Uij[2])/3.0
713                                atomData[r][us] = Uiso
714                                Atoms.SetCellStyle(r,us,WHITE,False)
715                                for i in range(6):
716                                    ci = ui+i
717                                    atomData[r][ci] = 0.0
718                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
719                        atomData[r][c] = parms
720                        if 'Atoms' in data['Drawing']:
721                            DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
722                    FillAtomsGrid()
723                   
724        def ChangeAtomCell(event):
725           
726            def chkUij(Uij,CSI): #needs to do something!!!
727                return Uij
728
729            r,c =  event.GetRow(),event.GetCol()
730            if r >= 0 and c >= 0:
731                ID = atomData[r][-1]
732                if Atoms.GetColLabelValue(c) in ['x','y','z']:
733                    ci = colLabels.index('x')
734                    XYZ = atomData[r][ci:ci+3]
735                    if None in XYZ:
736                        XYZ = [0,0,0]
737                    SScol = colLabels.index('site sym')
738                    Mulcol = colLabels.index('mult')
739                    E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
740                    Sytsym,Mult = G2spc.SytSym(XYZ,SGData)
741                    atomData[r][SScol] = Sytsym
742                    atomData[r][Mulcol] = Mult
743                    if atomData[r][colLabels.index('I/A')] == 'A':
744                        ui = colLabels.index('U11')
745                        CSI = G2spc.GetCSuinel(Sytsym)
746                        atomData[r][ui:ui+6] = chkUij(atomData[r][ui:ui+6],Sytsym)
747                        for i in range(6):
748                            ci = i+ui
749                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
750                            if CSI[2][i]:
751                                Atoms.SetCellStyle(r,ci,WHITE,False)
752                    SetupGeneral()
753                elif Atoms.GetColLabelValue(c) == 'I/A':            #note use of text color to make it vanish!
754                    if atomData[r][c] == 'I':
755                        Uij = atomData[r][c+2:c+8]
756                        atomData[r][c+1] = (Uij[0]+Uij[1]+Uij[2])/3.0
757                        Atoms.SetCellStyle(r,c+1,WHITE,False)
758                        Atoms.SetCellTextColour(r,c+1,BLACK)
759                        for i in range(6):
760                            ci = i+colLabels.index('U11')
761                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
762                            Atoms.SetCellTextColour(r,ci,VERY_LIGHT_GREY)
763                            atomData[r][ci] = 0.0
764                    else:
765                        value = atomData[r][c+1]
766                        CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
767                        atomData[r][c+1] =  0.0
768                        Atoms.SetCellStyle(r,c+1,VERY_LIGHT_GREY,True)
769                        Atoms.SetCellTextColour(r,c+1,VERY_LIGHT_GREY)
770                        for i in range(6):
771                            ci = i+colLabels.index('U11')
772                            atomData[r][ci] = value*CSI[3][i]
773                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
774                            Atoms.SetCellTextColour(r,ci,BLACK)
775                            if CSI[2][i]:
776                                Atoms.SetCellStyle(r,ci,WHITE,False)
777                elif Atoms.GetColLabelValue(c) in ['U11','U22','U33','U12','U13','U23']:
778                    value = atomData[r][c]
779                    CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
780                    iUij = CSI[0][c-colLabels.index('U11')]
781                    for i in range(6):
782                        if iUij == CSI[0][i]:
783                            atomData[r][i+colLabels.index('U11')] = value*CSI[1][i]
784                if 'Atoms' in data['Drawing']:
785                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
786                    FindBondsDraw()
787                   
788        def AtomTypeSelect(event):
789            r,c =  event.GetRow(),event.GetCol()
790            if Atoms.GetColLabelValue(c) == 'Type':
791                PE = G2elem.PickElement(self)
792                if PE.ShowModal() == wx.ID_OK:
793                    atomData[r][c] = PE.Elem.strip()
794                    name = atomData[r][c]
795                    if len(name) in [2,4]:
796                        atomData[r][c-1] = name[:2]+'(%d)'%(r+1)
797                    else:
798                        atomData[r][c-1] = name[:1]+'(%d)'%(r+1)
799                PE.Destroy()
800                SetupGeneral()
801                FillAtomsGrid()
802                value = Atoms.GetCellValue(r,c)
803                atomData[r][c] = value
804                ID = atomData[r][-1]
805                if 'Atoms' in data['Drawing']:
806                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
807            else:
808                event.Skip()
809
810        def RowSelect(event):
811            r,c =  event.GetRow(),event.GetCol()
812            if r < 0 and c < 0:
813                if Atoms.IsSelection():
814                    Atoms.ClearSelection()
815            elif c < 0:                   #only row clicks
816                if event.ControlDown():                   
817                    if r in Atoms.GetSelectedRows():
818                        Atoms.DeselectRow(r)
819                    else:
820                        Atoms.SelectRow(r,True)
821                elif event.ShiftDown():
822                    for row in range(r+1):
823                        Atoms.SelectRow(row,True)
824                else:
825                    Atoms.ClearSelection()
826                    Atoms.SelectRow(r,True)               
827               
828        def ChangeSelection(event):
829            r,c =  event.GetRow(),event.GetCol()
830            if r < 0 and c < 0:
831                Atoms.ClearSelection()
832            if c < 0:
833                if r in Atoms.GetSelectedRows():
834                    Atoms.DeselectRow(r)
835                else:
836                    Atoms.SelectRow(r,True)
837            if r < 0:
838                if c in Atoms.GetSelectedCols():
839                    Atoms.DeselectCol(c)
840                else:
841                    Atoms.SelectCol(c,True)
842       
843        SGData = data['General']['SGData']
844        if SGData['SGPolax']:
845            self.dataFrame.SetStatusText('Warning: The location of the origin is arbitrary in '+SGData['SGPolax'])
846        table = []
847        rowLabels = []
848        for i,atom in enumerate(atomData):
849            table.append(atom)
850            rowLabels.append(str(i))
851        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
852        Atoms.SetTable(atomTable, True)
853        Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeAtomCell)
854        Atoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, AtomTypeSelect)
855        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
856        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
857        Atoms.Bind(wg.EVT_GRID_LABEL_RIGHT_CLICK, ChangeSelection)
858        Atoms.SetMargins(0,0)
859        Atoms.AutoSizeColumns(False)
860        colType = colLabels.index('Type')
861        colSS = colLabels.index('site sym')
862        colIA = colLabels.index('I/A')
863        colU11 = colLabels.index('U11')
864        colUiso = colLabels.index('Uiso')
865        for i in range(colU11-1,colU11+6):
866            Atoms.SetColSize(i,50)           
867        for row in range(Atoms.GetNumberRows()):
868            Atoms.SetReadOnly(row,colType,True)
869            Atoms.SetReadOnly(row,colSS,True)                         #site sym
870            Atoms.SetReadOnly(row,colSS+1,True)                       #Mult
871            if Atoms.GetCellValue(row,colIA) == 'A':
872                CSI = G2spc.GetCSuinel(atomData[row][colLabels.index('site sym')])
873                Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True)
874                Atoms.SetCellTextColour(row,colUiso,VERY_LIGHT_GREY)
875                for i in range(6):
876                    ci = colU11+i
877                    Atoms.SetCellTextColour(row,ci,BLACK)
878                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
879                    if CSI[2][i]:
880                        Atoms.SetCellStyle(row,ci,WHITE,False)
881            else:
882                Atoms.SetCellStyle(row,colUiso,WHITE,False)
883                Atoms.SetCellTextColour(row,colUiso,BLACK)
884                for i in range(6):
885                    ci = colU11+i
886                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
887                    Atoms.SetCellTextColour(row,ci,VERY_LIGHT_GREY)
888
889    def OnAtomAdd(event):
890        AtomAdd(0,0,0)
891        FillAtomsGrid()
892        event.StopPropagation()
893       
894    def OnAtomTestAdd(event):
895        try:
896            drawData = data['Drawing']
897            x,y,z = drawData['testPos'][0]
898            AtomAdd(x,y,z)
899        except:
900            AtomAdd(0,0,0)
901        FillAtomsGrid()
902        event.StopPropagation()
903               
904    def AtomAdd(x,y,z):
905        atomData = data['Atoms']
906        generalData = data['General']
907        Ncol = Atoms.GetNumberCols()
908        atId = ran.randint(0,sys.maxint)
909        E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
910        Sytsym,Mult = G2spc.SytSym([x,y,z],SGData)
911        if generalData['Type'] == 'macromolecular':
912            atomData.append([0,'UNK','','UNK','H','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
913        elif generalData['Type'] == 'nuclear':
914            atomData.append(['UNK','H','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
915        elif generalData['Type'] == 'magnetic':
916            atomData.append(['UNK','H','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId])
917        SetupGeneral()
918        if 'Atoms' in data['Drawing']:           
919            DrawAtomAdd(data['Drawing'],atomData[-1])
920            G2plt.PlotStructure(self,data)
921
922    def OnAtomInsert(event):
923        AtomInsert(0,0,0)
924        FillAtomsGrid()
925        event.StopPropagation()
926       
927    def OnAtomTestInsert(event):
928        if 'Drawing' in data:
929            drawData = data['Drawing']
930            x,y,z = drawData['testPos'][0]
931            AtomAdd(x,y,z)
932            FillAtomsGrid()
933        event.StopPropagation()
934           
935    def AtomInsert(x,y,z):
936        indx = Atoms.GetSelectedRows()
937        if indx:
938            indx = indx[0]
939            atomData = data['Atoms']
940            generalData = data['General']
941            Ncol = Atoms.GetNumberCols()
942            E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
943            Sytsym,Mult = G2spc.SytSym([0,0,0],SGData)
944            atId = ran.randint(0,sys.maxint)
945            if generalData['Type'] == 'macromolecular':
946                atomData.insert(indx,[0,'UNK','','UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
947            elif generalData['Type'] == 'nuclear':
948                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
949            elif generalData['Type'] == 'magnetic':
950                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])
951            SetupGeneral()
952
953    def AtomDelete(event):
954        indx = Atoms.GetSelectedRows()
955        IDs = []
956        if indx:
957            atomData = data['Atoms']
958            indx.reverse()
959            for ind in indx:
960                atom = atomData[ind]
961                IDs.append(atom[-1])
962                del atomData[ind]
963            if 'Atoms' in data['Drawing']:
964                DrawAtomsDeleteByIDs(IDs)
965                FillAtomsGrid()
966                G2plt.PlotStructure(self,data)
967        event.StopPropagation()
968
969    def AtomRefine(event):
970        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
971        c = colLabels.index('refine')
972        indx = Atoms.GetSelectedRows()
973        if indx:
974            atomData = data['Atoms']
975            generalData = data['General']
976            Type = generalData['Type']
977            if Type in ['nuclear','macromolecular']:
978                choice = ['F - site fraction','X - coordinates','U - thermal parameters']
979            elif Type == 'magnetic':
980                choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
981            dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice)
982            if dlg.ShowModal() == wx.ID_OK:
983                sel = dlg.GetSelections()
984                parms = ''
985                for x in sel:
986                    parms += choice[x][0]
987                for r in indx:
988                    atomData[r][c] = parms
989                Atoms.ForceRefresh()
990            dlg.Destroy()
991
992    def AtomModify(event):                  #intent to implement global modifications (+,-,*,/, etc.)?
993        indx = Atoms.GetSelectedRows()
994        if indx:
995            atomData = data['Atoms']
996            generalData = data['General']
997
998    def AtomTransform(event):
999        indx = Atoms.GetSelectedRows()
1000        if indx:
1001            generalData = data['General']
1002            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1003            cx = colLabels.index('x')
1004            cuia = colLabels.index('I/A')
1005            cuij = colLabels.index('U11')
1006            css = colLabels.index('site sym')
1007            atomData = data['Atoms']
1008            generalData = data['General']
1009            SGData = generalData['SGData']
1010            dlg = SymOpDialog(self,SGData,True)
1011            try:
1012                if dlg.ShowModal() == wx.ID_OK:
1013                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1014                    Cell = np.array(Cell)
1015                    cent = SGData['SGCen'][Cent]
1016                    M,T = SGData['SGOps'][Opr]
1017                    for ind in indx:
1018                        XYZ = np.array(atomData[ind][cx:cx+3])
1019                        XYZ = np.inner(M,XYZ)+T
1020                        if Inv:
1021                            XYZ = -XYZ
1022                        XYZ = XYZ+cent+Cell
1023                        if New:
1024                            atom = copy.copy(atomData[ind])
1025                        else:
1026                            atom = atomData[ind]
1027                        atom[cx:cx+3] = XYZ
1028                        atom[css:css+2] = G2spc.SytSym(XYZ,SGData)
1029                        if atom[cuia] == 'A':
1030                            Uij = atom[cuij:cuij+6]
1031                            U = G2spc.Uij2U(Uij)
1032                            U = np.inner(np.inner(M,U),M)
1033                            Uij = G2spc.U2Uij(U)
1034                            atom[cuij:cuij+6] = Uij
1035                        if New:
1036                            atomData.append(atom)
1037            finally:
1038                dlg.Destroy()
1039            Atoms.ClearSelection()
1040            if New:
1041                FillAtomsGrid()
1042            else:
1043                Atoms.ForceRefresh()
1044
1045    def OnDistAngle(event):
1046        indx = Atoms.GetSelectedRows()
1047        Oxyz = []
1048        xyz = []
1049        DisAglData = {}
1050        if indx:
1051            generalData = data['General']
1052            DisAglData['OrigIndx'] = indx
1053            DisAglData['Name'] = generalData['Name']
1054            DisAglData['Factors'] = [0.85,0.85]
1055            DisAglData['AtomTypes'] = generalData['AtomTypes']
1056            DisAglData['BondRadii'] = generalData['BondRadii']
1057            DisAglData['AngleRadii'] = generalData['AngleRadii']
1058            DisAglDialog(self,DisAglData).ShowModal()
1059            atomData = data['Atoms']
1060            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1061            cx = colLabels.index('x')
1062            cn = colLabels.index('Name')
1063            for i,atom in enumerate(atomData):
1064                xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1065                if i in indx:
1066                    Oxyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1067            DisAglData['OrigAtoms'] = Oxyz
1068            DisAglData['TargAtoms'] = xyz
1069            generalData = data['General']
1070            DisAglData['SGData'] = generalData['SGData']
1071            DisAglData['Cell'] = generalData['Cell'][1:] #+ volume
1072            if 'pId' in data:
1073                DisAglData['pId'] = data['pId']
1074                DisAglData['covData'] = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,self.root, 'Covariance'))
1075            G2str.DistAngle(DisAglData)
1076               
1077#Structure drawing GUI stuff               
1078
1079    def SetupDrawingData():
1080        generalData = data['General']
1081        atomData = data['Atoms']
1082        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
1083            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
1084        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
1085            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
1086        defaultDrawing = {'viewPoint':[[0.5,0.5,0.5],[]],'showHydrogen':True,'backColor':[0,0,0],'depthFog':False,
1087            'Zclip':50.0,'cameraPos':50.,'radiusFactor':0.85,
1088            'bondRadius':0.1,'ballScale':0.33,'vdwScale':0.67,'ellipseProb':50,'sizeH':0.50,
1089            'unitCellBox':False,'showABC':True,'selectedAtoms':[],
1090            'Rotation':[0.0,0.0,0.0,[]],'bondList':{},'testPos':[[-.1,-.1,-.1],[0.0,0.0,0.0],[0,0]]}
1091        try:
1092            drawingData = data['Drawing']
1093        except KeyError:
1094            data['Drawing'] = {}
1095            drawingData = data['Drawing']
1096        if not drawingData:                 #fill with defaults if empty
1097            drawingData = copy.copy(defaultDrawing)
1098            drawingData['Atoms'] = []
1099        cx,ct,cs = [0,0,0]
1100        if generalData['Type'] == 'nuclear':
1101            cx,ct,cs = [2,1,6]         #x, type & style
1102        elif generalData['Type'] == 'macromolecular':
1103            cx,ct,cs = [5,4,9]         #x, type & style
1104        elif generalData['Type'] == 'magnetic':
1105            cx,ct,cs = [2,1,6]         #x, type & style
1106#        elif generalData['Type'] == 'modulated':
1107#           ?????   for future
1108        if not drawingData['Atoms']:
1109            for atom in atomData:
1110                DrawAtomAdd(drawingData,atom)
1111            drawingData['atomPtrs'] = [cx,ct,cs]
1112            data['Drawing'] = drawingData
1113           
1114    def MakeDrawAtom(atom,oldatom=None):
1115        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
1116            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
1117        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
1118            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
1119        generalData = data['General']
1120        SGData = generalData['SGData']
1121        if generalData['Type'] == 'nuclear':
1122            if oldatom:
1123                opr = oldatom[5]
1124                if atom[9] == 'A':                   
1125                    X,U = G2spc.ApplyStringOps(opr,SGData,atom[3:6],atom[11:17])
1126                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:11]+list(U)+oldatom[17:]][0]
1127                else:
1128                    X = G2spc.ApplyStringOps(opr,SGData,atom[3:6])
1129                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:]+[oldatom[-1]]][0]
1130            else:
1131                atomInfo = [atom[:2]+atom[3:6]+['1',]+['vdW balls',]+
1132                    ['',]+[[255,255,255],]+atom[9:]+[[],[]]][0]
1133            ct,cs = [1,8]         #type & color
1134        elif generalData['Type'] == 'macromolecular':
1135            try:
1136                oneLetter = AA3letter.index(atom[1])
1137            except ValueError:
1138                oneLetter = -1
1139            atomInfo = [[atom[1].strip()+atom[0],]+
1140                [AA1letter[oneLetter]+atom[0],]+atom[2:5]+
1141                atom[6:9]+['1',]+['sticks',]+['',]+[[255,255,255],]+atom[12:]+[[],[]]][0]
1142            ct,cs = [4,11]         #type & color
1143        elif generalData['Type'] == 'magnetic':
1144            if oldatom:
1145                atomInfo = [atom[:2]+oldatom[3:]][0]
1146            else:
1147                atomInfo = [atom[:2]+atom[3:6]+['vdW balls',]+['',]+atom[9:]+[[],[]]][0]
1148            ct,cs = [1,8]         #type & color
1149#        elif generalData['Type'] == 'modulated':
1150#           ?????   for future
1151        atNum = generalData['AtomTypes'].index(atom[ct])
1152        atomInfo[cs] = list(generalData['Color'][atNum])
1153        return atomInfo
1154           
1155    def DrawAtomAdd(drawingData,atom):
1156        drawingData['Atoms'].append(MakeDrawAtom(atom))
1157       
1158    def DrawAtomsReplaceByID(drawingData,atom,ID):
1159        IDs = [ID,]
1160        atomData = drawingData['Atoms']
1161        indx = FindAtomIndexByIDs(atomData,IDs)
1162        for ind in indx:
1163            atomData[ind] = MakeDrawAtom(atom,atomData[ind])
1164           
1165    def UpdateDrawAtoms():
1166        generalData = data['General']
1167        SetupDrawingData()
1168        drawingData = data['Drawing']
1169        cx,ct,cs = drawingData['atomPtrs']
1170        atomData = drawingData['Atoms']
1171        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',]+ \
1172            [wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,polyhedra",
1173            wg.GRID_VALUE_CHOICE+": ,type,name,number",wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]
1174        styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1175        labelChoice = [' ','type','name','number']
1176        colLabels = ['Name','Type','x','y','z','Sym Op','Style','Label','Color','I/A']
1177        if generalData['Type'] == 'macromolecular':
1178            colLabels = ['Residue','1-letter','Chain'] + colLabels
1179            Types = 3*[wg.GRID_VALUE_STRING,]+Types
1180            Types[8] = wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,backbone,ribbons,schematic"
1181            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','backbone','ribbons','schematic']
1182            labelChoice = [' ','type','name','number','residue','1-letter','chain']
1183            Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1-letter,chain"
1184#        elif generalData['Type'] == 'modulated':
1185#            Types += []
1186#            colLabels += []
1187
1188        def RefreshAtomGrid(event):
1189
1190            def SetChoice(name,c,n=0):
1191                choice = []
1192                for r in range(len(atomData)):
1193                    if n:
1194                        srchStr = str(atomData[r][c][:n])
1195                    else:
1196                        srchStr = str(atomData[r][c])
1197                    if srchStr not in choice:
1198                        if n:
1199                            choice.append(str(atomData[r][c][:n]))
1200                        else:
1201                            choice.append(str(atomData[r][c]))
1202                choice.sort()
1203
1204                dlg = wx.MultiChoiceDialog(self,'Select',name,choice)
1205                if dlg.ShowModal() == wx.ID_OK:
1206                    sel = dlg.GetSelections()
1207                    parms = []
1208                    for x in sel:
1209                        parms.append(choice[x])
1210                    noSkip = False
1211                    drawAtoms.ClearSelection()
1212                    drawingData['selectedAtoms'] = []
1213                    for row in range(len(atomData)):
1214                        test = atomData[row][c]
1215                        if n:
1216                            test = test[:n]
1217                        if  test in parms:
1218                            drawAtoms.SelectRow(row,True)
1219                            drawingData['selectedAtoms'].append(row)
1220                    G2plt.PlotStructure(self,data)                   
1221                dlg.Destroy()
1222               
1223            r,c =  event.GetRow(),event.GetCol()
1224            if r < 0 and c < 0:
1225                for row in range(drawAtoms.GetNumberRows()):
1226                    drawingData['selectedAtoms'].append(row)
1227                    drawAtoms.SelectRow(row,True)                   
1228            elif r < 0:                          #dclick on col label
1229                sel = -1
1230                Parms = False
1231                noSkip = True
1232                if drawAtoms.GetColLabelValue(c) == 'Style':
1233                    dlg = wx.SingleChoiceDialog(self,'Select','Atom drawing style',styleChoice)
1234                    if dlg.ShowModal() == wx.ID_OK:
1235                        sel = dlg.GetSelection()
1236                        parms = styleChoice[sel]
1237                        for r in range(len(atomData)):
1238                            atomData[r][c] = parms
1239                            drawAtoms.SetCellValue(r,c,parms)
1240                        FindBondsDraw()
1241                        G2plt.PlotStructure(self,data)
1242                    dlg.Destroy()
1243                elif drawAtoms.GetColLabelValue(c) == 'Label':
1244                    dlg = wx.SingleChoiceDialog(self,'Select','Atom labelling style',labelChoice)
1245                    if dlg.ShowModal() == wx.ID_OK:
1246                        sel = dlg.GetSelection()
1247                        parms = labelChoice[sel]
1248                        for r in range(len(atomData)):
1249                            atomData[r][c] = parms
1250                            drawAtoms.SetCellValue(r,c,parms)
1251                    dlg.Destroy()                   
1252                elif drawAtoms.GetColLabelValue(c) == 'Color':
1253                    dlg = wx.ColourDialog(self)
1254                    if dlg.ShowModal() == wx.ID_OK:
1255                        color = dlg.GetColourData().GetColour()
1256                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1257                        attr.SetReadOnly(True)
1258                        attr.SetBackgroundColour(color)
1259                        for r in range(len(atomData)):
1260                            atomData[r][c] = color
1261                            drawingData['Atoms'][r][c] = color
1262                            drawAtoms.SetAttr(r,c,attr)
1263                        UpdateDrawAtoms()
1264                    dlg.Destroy()
1265                elif drawAtoms.GetColLabelValue(c) == 'Residue':
1266                    SetChoice('Residue',c,3)
1267                elif drawAtoms.GetColLabelValue(c) == '1-letter':
1268                    SetChoice('1-letter',c,1)
1269                elif drawAtoms.GetColLabelValue(c) == 'Chain':
1270                    SetChoice('Chain',c)
1271                elif drawAtoms.GetColLabelValue(c) == 'Name':
1272                    SetChoice('Name',c)
1273                elif drawAtoms.GetColLabelValue(c) == 'Sym Op':
1274                    SetChoice('Name',c)
1275                elif drawAtoms.GetColLabelValue(c) == 'Type':
1276                    SetChoice('Type',c)
1277                elif drawAtoms.GetColLabelValue(c) in ['x','y','z','I/A']:
1278                    drawAtoms.ClearSelection()
1279            else:
1280                if drawAtoms.GetColLabelValue(c) in ['Style','Label']:
1281                    atomData[r][c] = drawAtoms.GetCellValue(r,c)
1282                    FindBondsDraw()
1283                elif drawAtoms.GetColLabelValue(c) == 'Color':
1284                    color = atomData[r][c]
1285                    colors = wx.ColourData()
1286                    colors.SetChooseFull(True)
1287                    colors.SetCustomColour(0,color)
1288                    colors.SetColour(color)
1289                    dlg = wx.ColourDialog(self,colors)
1290                    dlg.GetColourData().SetCustomColour(0,color)
1291                    if dlg.ShowModal() == wx.ID_OK:
1292                        color = dlg.GetColourData().GetColour()
1293                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1294                        attr.SetReadOnly(True)
1295                        attr.SetBackgroundColour(color)
1296                        atomData[r][c] = color
1297                        drawingData['Atoms'][r][c] = color
1298                        drawAtoms.SetAttr(i,cs+2,attr)
1299                    dlg.Destroy()
1300                    event.StopPropagation()
1301                    UpdateDrawAtoms()
1302            G2plt.PlotStructure(self,data)
1303                   
1304        def RowSelect(event):
1305            r,c =  event.GetRow(),event.GetCol()
1306            if r < 0 and c < 0:
1307                if drawAtoms.IsSelection():
1308                    drawAtoms.ClearSelection()
1309            elif c < 0:                   #only row clicks
1310                if event.ControlDown():                   
1311                    if r in drawAtoms.GetSelectedRows():
1312                        drawAtoms.DeselectRow(r)
1313                    else:
1314                        drawAtoms.SelectRow(r,True)
1315                elif event.ShiftDown():
1316                    for row in range(r+1):
1317                        drawAtoms.SelectRow(row,True)
1318                else:
1319                    drawAtoms.ClearSelection()
1320                    drawAtoms.SelectRow(r,True)               
1321            drawingData['selectedAtoms'] = []
1322            drawingData['selectedAtoms'] = drawAtoms.GetSelectedRows()
1323            G2plt.PlotStructure(self,data)                   
1324               
1325        table = []
1326        rowLabels = []
1327        for i,atom in enumerate(drawingData['Atoms']):
1328            table.append(atom[:colLabels.index('I/A')+1])
1329            rowLabels.append(str(i))
1330
1331        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1332        drawAtoms.SetTable(atomTable, True)
1333        drawAtoms.SetMargins(0,0)
1334        drawAtoms.AutoSizeColumns(True)
1335        drawAtoms.SetColSize(colLabels.index('Style'),80)
1336        drawAtoms.SetColSize(colLabels.index('Color'),50)
1337        drawAtoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
1338        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1339        drawAtoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, RefreshAtomGrid)
1340        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
1341        for i,atom in enumerate(drawingData['Atoms']):
1342            attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1343            attr.SetReadOnly(True)
1344            attr.SetBackgroundColour(atom[cs+2])
1345            drawAtoms.SetAttr(i,cs+2,attr)
1346            drawAtoms.SetCellValue(i,cs+2,'')
1347        indx = drawingData['selectedAtoms']
1348        if indx:
1349            for r in range(len(atomData)):
1350                if r in indx:
1351                    drawAtoms.SelectRow(r)
1352        for c in range(len(colLabels)):
1353           attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1354           attr.SetReadOnly(True)
1355           attr.SetBackgroundColour(VERY_LIGHT_GREY)
1356           if colLabels[c] not in ['Style','Label','Color']:
1357                drawAtoms.SetColAttr(c,attr)
1358        self.dataFrame.setSizePosLeft([600,300])
1359       
1360        FindBondsDraw()
1361        drawAtoms.ClearSelection()
1362        G2plt.PlotStructure(self,data)
1363
1364    def DrawAtomStyle(event):
1365        indx = drawAtoms.GetSelectedRows()
1366        if indx:
1367            generalData = data['General']
1368            atomData = data['Drawing']['Atoms']
1369            cx,ct,cs = data['Drawing']['atomPtrs']
1370            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1371            if generalData['Type'] == 'macromolecular':
1372                styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids',
1373                'backbone','ribbons','schematic']
1374            dlg = wx.SingleChoiceDialog(self,'Select','Atom drawing style',styleChoice)
1375            if dlg.ShowModal() == wx.ID_OK:
1376                sel = dlg.GetSelection()
1377                parms = styleChoice[sel]
1378                for r in indx:
1379                    atomData[r][cs] = parms
1380                    drawAtoms.SetCellValue(r,cs,parms)
1381            dlg.Destroy()
1382            FindBondsDraw()
1383            drawAtoms.ClearSelection()
1384            G2plt.PlotStructure(self,data)
1385
1386    def DrawAtomLabel(event):
1387        indx = drawAtoms.GetSelectedRows()
1388        if indx:
1389            generalData = data['General']
1390            atomData = data['Drawing']['Atoms']
1391            cx,ct,cs = data['Drawing']['atomPtrs']
1392            styleChoice = [' ','type','name','number']
1393            if generalData['Type'] == 'macromolecular':
1394                styleChoice = [' ','type','name','number','residue','1-letter','chain']
1395            dlg = wx.SingleChoiceDialog(self,'Select','Atom label style',styleChoice)
1396            if dlg.ShowModal() == wx.ID_OK:
1397                sel = dlg.GetSelection()
1398                parms = styleChoice[sel]
1399                for r in indx:
1400                    atomData[r][cs+1] = parms
1401                    drawAtoms.SetCellValue(r,cs+1,parms)
1402            dlg.Destroy()
1403            drawAtoms.ClearSelection()
1404            G2plt.PlotStructure(self,data)
1405           
1406    def DrawAtomColor(event):
1407
1408        indx = drawAtoms.GetSelectedRows()
1409        if indx:
1410            if len(indx) > 1:
1411                self.dataFrame.SetStatusText('Select Custom Color, change color, Add to Custom Colors, then OK')
1412            else:
1413                self.dataFrame.SetStatusText('Change color, Add to Custom Colors, then OK')
1414            generalData = data['General']
1415            atomData = data['Drawing']['Atoms']
1416            cx,ct,cs = data['Drawing']['atomPtrs']
1417            atmColors = []
1418            atmTypes = []
1419            for r in indx:
1420                if atomData[r][cs+2] not in atmColors:
1421                    atmColors.append(atomData[r][cs+2])
1422                    atmTypes.append(atomData[r][ct])
1423                    if len(atmColors) > 16:
1424                        break
1425            colors = wx.ColourData()
1426            colors.SetChooseFull(True)
1427            for i,color in enumerate(atmColors):
1428                colors.SetCustomColour(i,color)
1429            dlg = wx.ColourDialog(self,colors)
1430            if dlg.ShowModal() == wx.ID_OK:
1431                for i in range(len(atmColors)):                   
1432                    atmColors[i] = dlg.GetColourData().GetCustomColour(i)
1433                colorDict = dict(zip(atmTypes,atmColors))
1434                for r in indx:
1435                    color = colorDict[atomData[r][ct]]
1436                    atomData[r][cs+2] = color
1437                    attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1438                    attr.SetBackgroundColour(color)
1439                    drawAtoms.SetAttr(r,cs+2,attr)
1440                    data['Drawing']['Atoms'][r][cs+2] = color
1441            drawAtoms.ClearSelection()
1442            dlg.Destroy()
1443            self.dataFrame.SetStatusText('')
1444           
1445    def ResetAtomColors(event):
1446        generalData = data['General']
1447        atomData = data['Drawing']['Atoms']
1448        cx,ct,cs = data['Drawing']['atomPtrs']
1449        for atom in atomData:           
1450            atNum = generalData['AtomTypes'].index(atom[ct])
1451            atom[cs+2] = list(generalData['Color'][atNum])
1452        UpdateDrawAtoms()
1453        drawAtoms.ClearSelection()
1454        G2plt.PlotStructure(self,data)       
1455       
1456    def SetViewPoint(event):
1457        indx = drawAtoms.GetSelectedRows()
1458        if indx:
1459            atomData = data['Drawing']['Atoms']
1460            cx = data['Drawing']['atomPtrs'][0]
1461            data['Drawing']['viewPoint'] = [atomData[indx[0]][cx:cx+3],[indx[0],0]]
1462            drawAtoms.ClearSelection()                                  #do I really want to do this?
1463            G2plt.PlotStructure(self,data)
1464           
1465    def noDuplicate(xyz,atomData):                  #be careful where this is used - it's slow
1466        cx = data['Drawing']['atomPtrs'][0]
1467        if True in [np.allclose(np.array(xyz),np.array(atom[cx:cx+3]),atol=0.0002) for atom in atomData]:
1468            return False
1469        else:
1470            return True
1471               
1472    def AddSymEquiv(event):
1473        indx = drawAtoms.GetSelectedRows()
1474        indx.sort()
1475        if indx:
1476            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1477            cx = colLabels.index('x')
1478            cuia = colLabels.index('I/A')
1479            cuij = cuia+2
1480            atomData = data['Drawing']['Atoms']
1481            generalData = data['General']
1482            SGData = generalData['SGData']
1483            dlg = SymOpDialog(self,SGData,False)
1484            try:
1485                if dlg.ShowModal() == wx.ID_OK:
1486                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1487                    Cell = np.array(Cell)
1488                    cent = SGData['SGCen'][Cent]
1489                    M,T = SGData['SGOps'][Opr]
1490                    for ind in indx:
1491                        XYZ = np.array(atomData[ind][cx:cx+3])
1492                        XYZ = np.inner(M,XYZ)+T
1493                        if Inv:
1494                            XYZ = -XYZ
1495                        XYZ = XYZ+cent+Cell
1496                        if noDuplicate(XYZ,atomData):
1497                            atom = copy.copy(atomData[ind])
1498                            atom[cx:cx+3] = XYZ
1499                            atomOp = atom[cx+3]
1500                            newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1501                                str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))                           
1502                            atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1503                            if atom[cuia] == 'A':
1504                                Uij = atom[cuij:cuij+6]
1505                                U = G2spc.Uij2U(Uij)
1506                                U = np.inner(np.inner(M,U),M)
1507                                Uij = G2spc.U2Uij(U)
1508                                atom[cuij:cuij+6] = Uij
1509                            atomData.append(atom)
1510            finally:
1511                dlg.Destroy()
1512            UpdateDrawAtoms()
1513            drawAtoms.ClearSelection()
1514            G2plt.PlotStructure(self,data)
1515           
1516    def TransformSymEquiv(event):
1517        indx = drawAtoms.GetSelectedRows()
1518        indx.sort()
1519        if indx:
1520            atomData = data['Drawing']['Atoms']
1521            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1522            cx = colLabels.index('x')
1523            cuia = colLabels.index('I/A')
1524            cuij = cuia+2
1525            atomData = data['Drawing']['Atoms']
1526            generalData = data['General']
1527            SGData = generalData['SGData']
1528            dlg = SymOpDialog(self,SGData,False)
1529            try:
1530                if dlg.ShowModal() == wx.ID_OK:
1531                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1532                    Cell = np.array(Cell)
1533                    cent = SGData['SGCen'][Cent]
1534                    M,T = SGData['SGOps'][Opr]
1535                    for ind in indx:
1536                        XYZ = np.array(atomData[ind][cx:cx+3])
1537                        XYZ = np.inner(M,XYZ)+T
1538                        if Inv:
1539                            XYZ = -XYZ
1540                        XYZ = XYZ+cent+Cell
1541                        atom = atomData[ind]
1542                        atom[cx:cx+3] = XYZ
1543                        atomOp = atom[cx+3]
1544                        newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1545                            str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))
1546                        atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1547                        if atom[cuia] == 'A':
1548                            Uij = atom[cuij:cuij+6]
1549                            U = G2spc.Uij2U(Uij)
1550                            U = np.inner(np.inner(M,U),M)
1551                            Uij = G2spc.U2Uij(U)
1552                            atom[cuij:cuij+6] = Uij
1553                    data['Drawing']['Atoms'] = atomData
1554            finally:
1555                dlg.Destroy()
1556            UpdateDrawAtoms()
1557            drawAtoms.ClearSelection()
1558            G2plt.PlotStructure(self,data)
1559           
1560    def FillCoordSphere(event):
1561        generalData = data['General']
1562        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1563        radii = generalData['BondRadii']
1564        atomTypes = generalData['AtomTypes']
1565        try:
1566            indH = atomTypes.index('H')
1567            radii[indH] = 0.5
1568        except:
1569            pass           
1570        indx = drawAtoms.GetSelectedRows()
1571        if indx:
1572            indx.sort()
1573            atomData = data['Drawing']['Atoms']
1574            numAtoms = len(atomData)
1575            cx,ct,cs = data['Drawing']['atomPtrs']
1576            generalData = data['General']
1577            SGData = generalData['SGData']
1578            cellArray = G2lat.CellBlock(1)
1579            for ind in indx:
1580                atomA = atomData[ind]
1581                xyzA = np.array(atomA[cx:cx+3])
1582                indA = atomTypes.index(atomA[ct])
1583                for atomB in atomData[:numAtoms]:
1584                    indB = atomTypes.index(atomB[ct])
1585                    sumR = radii[indA]+radii[indB]
1586                    xyzB = np.array(atomB[cx:cx+3])
1587                    for xyz in cellArray+xyzB:
1588                        dist = np.sqrt(np.sum(np.inner(Amat,xyz-xyzA)**2))
1589                        if 0 < dist <= data['Drawing']['radiusFactor']*sumR:
1590                            if noDuplicate(xyz,atomData):
1591                                oprB = atomB[cx+3]
1592                                C = xyz-xyzB
1593                                newOp = '1+'+str(int(round(C[0])))+','+str(int(round(C[1])))+','+str(int(round(C[2])))
1594                                newAtom = atomB[:]
1595                                newAtom[cx:cx+3] = xyz
1596                                newAtom[cx+3] = G2spc.StringOpsProd(oprB,newOp,SGData)
1597                                atomData.append(newAtom)
1598            data['Drawing']['Atoms'] = atomData
1599            UpdateDrawAtoms()
1600            drawAtoms.ClearSelection()
1601            G2plt.PlotStructure(self,data)
1602           
1603    def FillUnitCell(event):
1604        indx = drawAtoms.GetSelectedRows()
1605        indx.sort()
1606        if indx:
1607            atomData = data['Drawing']['Atoms']
1608            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1609            cx = colLabels.index('x')
1610            cuia = colLabels.index('I/A')
1611            cuij = cuia+2
1612            generalData = data['General']
1613            SGData = generalData['SGData']
1614            for ind in indx:
1615                atom = atomData[ind]
1616                XYZ = np.array(atom[cx:cx+3])
1617                if atom[cuia] == 'A':
1618                    Uij = atom[cuij:cuij+6]
1619                    result = G2spc.GenAtom(XYZ,SGData,False,Uij)
1620                    for item in result:
1621                        atom = copy.copy(atomData[ind])
1622                        atom[cx:cx+3] = item[0]
1623                        atom[cx+3] = str(item[2])+'+' \
1624                            +str(item[3][0])+','+str(item[3][1])+','+str(item[3][2])
1625                        atom[cuij:cuij+6] = item[1]
1626                        Opp = G2spc.Opposite(item[0])
1627                        for xyz in Opp:
1628                            if noDuplicate(xyz,atomData):
1629                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
1630                                cell = '1'+'+'+ \
1631                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
1632                                atom[cx:cx+3] = xyz
1633                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
1634                                atomData.append(atom[:])
1635                else:
1636                    result = G2spc.GenAtom(XYZ,SGData,False)
1637                    for item in result:
1638                        atom = copy.copy(atomData[ind])
1639                        atom[cx:cx+3] = item[0]
1640                        atom[cx+3] = str(item[1])+'+' \
1641                            +str(item[2][0])+','+str(item[2][1])+','+str(item[2][2])
1642                        Opp = G2spc.Opposite(item[0])
1643                        for xyz in Opp:
1644                            if noDuplicate(xyz,atomData):
1645                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
1646                                cell = '1'+'+'+ \
1647                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
1648                                atom[cx:cx+3] = xyz
1649                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
1650                                atomData.append(atom[:])               
1651                data['Drawing']['Atoms'] = atomData
1652            UpdateDrawAtoms()
1653            drawAtoms.ClearSelection()
1654            G2plt.PlotStructure(self,data)
1655           
1656    def FindBondsToo():                         #works but slow for large structures - keep as reference
1657        cx,ct,cs = data['Drawing']['atomPtrs']
1658        atomData = data['Drawing']['Atoms']
1659        generalData = data['General']
1660        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1661        radii = generalData['BondRadii']
1662        atomTypes = generalData['AtomTypes']
1663        try:
1664            indH = atomTypes.index('H')
1665            radii[indH] = 0.5
1666        except:
1667            pass           
1668        for atom in atomData:
1669            atom[-1] = []
1670        Atoms = []
1671        for i,atom in enumerate(atomData):
1672            Atoms.append([i,np.array(atom[cx:cx+3]),atom[cs],radii[atomTypes.index(atom[ct])]])
1673        for atomA in Atoms:
1674            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
1675                for atomB in Atoms:                   
1676                    Dx = atomB[1]-atomA[1]
1677                    DX = np.inner(Amat,Dx)
1678                    dist = np.sqrt(np.sum(DX**2))
1679                    sumR = atomA[3]+atomB[3]
1680                    if 0.5 < dist <= 0.85*sumR:
1681                        i = atomA[0]
1682                        if atomA[2] == 'polyhedra':
1683                            atomData[i][-1].append(DX)
1684                        elif atomB[1] != 'polyhedra':
1685                            j = atomB[0]
1686                            atomData[i][-1].append(Dx*atomA[3]/sumR)
1687                            atomData[j][-1].append(-Dx*atomB[3]/sumR)
1688                   
1689    def FindBondsDraw():                    #uses numpy & masks - very fast even for proteins!
1690        import numpy.ma as ma
1691        cx,ct,cs = data['Drawing']['atomPtrs']
1692        hydro = data['Drawing']['showHydrogen']
1693        atomData = data['Drawing']['Atoms']
1694        generalData = data['General']
1695        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1696        radii = generalData['BondRadii']
1697        atomTypes = generalData['AtomTypes']
1698        try:
1699            indH = atomTypes.index('H')
1700            radii[indH] = 0.5
1701        except:
1702            pass           
1703        for atom in atomData:
1704            atom[-2] = []               #clear out old bonds/polyhedra
1705            atom[-1] = []
1706        Indx = range(len(atomData))
1707        Atoms = []
1708        Styles = []
1709        Radii = []
1710        for atom in atomData:
1711            Atoms.append(np.array(atom[cx:cx+3]))
1712            Styles.append(atom[cs])
1713            try:
1714                if not hydro and atom[ct] == 'H':
1715                    Radii.append(0.0)
1716                else:
1717                    Radii.append(radii[atomTypes.index(atom[ct])])
1718            except ValueError:          #changed atom type!
1719                Radii.append(0.20)
1720        Atoms = np.array(Atoms)
1721        Radii = np.array(Radii)
1722        IASR = zip(Indx,Atoms,Styles,Radii)
1723        for atomA in IASR:
1724            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
1725                Dx = Atoms-atomA[1]
1726                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
1727                sumR = atomA[3]+Radii
1728                IndB = ma.nonzero(ma.masked_greater(dist-data['Drawing']['radiusFactor']*sumR,0.))                 #get indices of bonded atoms
1729                i = atomA[0]
1730                for j in IndB[0]:
1731                    if Styles[i] == 'polyhedra':
1732                        atomData[i][-2].append(np.inner(Amat,Dx[j]))
1733                    elif Styles[j] != 'polyhedra' and j > i:
1734                        atomData[i][-2].append(Dx[j]*Radii[i]/sumR[j])
1735                        atomData[j][-2].append(-Dx[j]*Radii[j]/sumR[j])
1736                if Styles[i] == 'polyhedra':
1737                    Bonds = atomData[i][-2]
1738                    Faces = []
1739                    if len(Bonds) > 2:
1740                        FaceGen = G2lat.uniqueCombinations(Bonds,3)     #N.B. this is a generator
1741                        for face in FaceGen:
1742                            vol = nl.det(face)
1743                            if abs(vol) > 1. or len(Bonds) == 3:
1744                                if vol < 0.:
1745                                    face = [face[0],face[2],face[1]]
1746                                face = np.array(face)
1747                                if not np.array([np.array(nl.det(face-bond))+0.0001 < 0 for bond in Bonds]).any():
1748                                    norm = np.cross(face[1]-face[0],face[2]-face[0])
1749                                    norm /= np.sqrt(np.sum(norm**2))
1750                                    Faces.append([face,norm])
1751                        atomData[i][-1] = Faces
1752                       
1753    def DrawAtomsDelete(event):   
1754        indx = drawAtoms.GetSelectedRows()
1755        indx.sort()
1756        if indx:
1757            atomData = data['Drawing']['Atoms']
1758            indx.reverse()
1759            for ind in indx:
1760                del atomData[ind]
1761            UpdateDrawAtoms()
1762            drawAtoms.ClearSelection()
1763            G2plt.PlotStructure(self,data)
1764        event.StopPropagation()
1765       
1766    def OnReloadDrawAtoms(event):
1767        data['Drawing']['Atoms'] = []
1768        UpdateDrawAtoms()
1769        drawAtoms.ClearSelection()
1770        G2plt.PlotStructure(self,data)
1771        event.StopPropagation()
1772       
1773    def FindAtomIndexByIDs(atomData,IDs):
1774        indx = []
1775        for i,atom in enumerate(atomData):
1776            if atom[-2] in IDs:
1777                indx.append(i)
1778        return indx
1779       
1780    def DrawAtomsDeleteByIDs(IDs):
1781        atomData = data['Drawing']['Atoms']
1782        indx = FindAtomIndexByIDs(atomData,IDs)
1783        indx.reverse()
1784        for ind in indx:
1785            del atomData[ind]
1786           
1787    def ChangeDrawAtomsByIDs(colName,IDs,value):
1788        atomData = data['Drawing']['Atoms']
1789        cx,ct,cs = data['Drawing']['atomPtrs']
1790        if colName == 'Name':
1791            col = ct-1
1792        elif colName == 'Type':
1793            col = ct
1794        elif colName == 'I/A':
1795            col = cs
1796        indx = FindAtomIndexByIDs(atomData,IDs)
1797        for ind in indx:
1798            atomData[ind][col] = value
1799               
1800    def UpdateDrawOptions():
1801        import copy
1802        import wx.lib.colourselect as wcs
1803        generalData = data['General']
1804        SetupDrawingData()
1805        drawingData = data['Drawing']
1806        if generalData['Type'] == 'nuclear':
1807            pickChoice = ['Atoms','Bonds','Torsions','Planes']
1808        elif generalData['Type'] == 'macromolecular':
1809            pickChoice = ['Atoms','Residues','Chains','Bonds','Torsions','Planes','phi/psi']
1810
1811        def OnZclip(event):
1812            drawingData['Zclip'] = Zclip.GetValue()
1813            ZclipTxt.SetLabel('Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1814            G2plt.PlotStructure(self,data)
1815           
1816        def OnCameraPos(event):
1817            drawingData['cameraPos'] = cameraPos.GetValue()
1818            cameraPosTxt.SetLabel('Camera Distance: '+'%.2f'%(drawingData['cameraPos']))
1819            ZclipTxt.SetLabel('Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1820            G2plt.PlotStructure(self,data)
1821
1822        def OnBackColor(event):
1823            drawingData['backColor'] = event.GetValue()
1824            G2plt.PlotStructure(self,data)
1825
1826        def OnBallScale(event):
1827            drawingData['ballScale'] = ballScale.GetValue()/100.
1828            ballScaleTxt.SetLabel('Ball scale: '+'%.2f'%(drawingData['ballScale']))
1829            G2plt.PlotStructure(self,data)
1830
1831        def OnVdWScale(event):
1832            drawingData['vdwScale'] = vdwScale.GetValue()/100.
1833            vdwScaleTxt.SetLabel('van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
1834            G2plt.PlotStructure(self,data)
1835
1836        def OnEllipseProb(event):
1837            drawingData['ellipseProb'] = ellipseProb.GetValue()
1838            ellipseProbTxt.SetLabel('Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
1839            G2plt.PlotStructure(self,data)
1840
1841        def OnBondRadius(event):
1842            drawingData['bondRadius'] = bondRadius.GetValue()/100.
1843            bondRadiusTxt.SetLabel('Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
1844            G2plt.PlotStructure(self,data)
1845
1846        def OnShowABC(event):
1847            drawingData['showABC'] = showABC.GetValue()
1848            G2plt.PlotStructure(self,data)
1849
1850        def OnShowUnitCell(event):
1851            drawingData['unitCellBox'] = unitCellBox.GetValue()
1852            G2plt.PlotStructure(self,data)
1853
1854        def OnShowHyd(event):
1855            drawingData['showHydrogen'] = showHydrogen.GetValue()
1856            FindBondsDraw()
1857            G2plt.PlotStructure(self,data)
1858
1859        def OnSizeHatoms(event):
1860            try:
1861                value = max(0.1,min(1.2,float(sizeH.GetValue())))
1862            except ValueError:
1863                value = 0.5
1864            drawingData['sizeH'] = value
1865            sizeH.SetValue("%.2f"%(value))
1866            G2plt.PlotStructure(self,data)
1867           
1868        def OnRadFactor(event):
1869            try:
1870                value = max(0.1,min(1.2,float(radFactor.GetValue())))
1871            except ValueError:
1872                value = 0.85
1873            drawingData['radiusFactor'] = value
1874            radFactor.SetValue("%.2f"%(value))
1875            FindBondsDraw()
1876            G2plt.PlotStructure(self,data)
1877
1878        dataDisplay = wx.Panel(drawOptions)
1879        mainSizer = wx.BoxSizer(wx.VERTICAL)
1880        mainSizer.Add((5,5),0)
1881        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Drawing controls:'),0,wx.ALIGN_CENTER_VERTICAL)
1882        mainSizer.Add((5,5),0)
1883       
1884        slopSizer = wx.BoxSizer(wx.HORIZONTAL)
1885        slideSizer = wx.FlexGridSizer(6,2)
1886        slideSizer.AddGrowableCol(1,1)
1887
1888        cameraPosTxt = wx.StaticText(dataDisplay,-1,
1889            'Camera Distance: '+'%.2f'%(drawingData['cameraPos']),name='cameraPos')
1890        slideSizer.Add(cameraPosTxt,0,wx.ALIGN_CENTER_VERTICAL)
1891        cameraPos = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['cameraPos'],name='cameraSlider')
1892        cameraPos.SetRange(10,500)
1893        cameraPos.Bind(wx.EVT_SLIDER, OnCameraPos)
1894        slideSizer.Add(cameraPos,1,wx.EXPAND|wx.RIGHT)
1895       
1896        ZclipTxt = wx.StaticText(dataDisplay,-1,'Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1897        slideSizer.Add(ZclipTxt,0,wx.ALIGN_CENTER_VERTICAL)
1898        Zclip = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['Zclip'])
1899        Zclip.SetRange(1,99)
1900        Zclip.Bind(wx.EVT_SLIDER, OnZclip)
1901        slideSizer.Add(Zclip,1,wx.EXPAND|wx.RIGHT)
1902       
1903        vdwScaleTxt = wx.StaticText(dataDisplay,-1,'van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
1904        slideSizer.Add(vdwScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
1905        vdwScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['vdwScale']))
1906        vdwScale.Bind(wx.EVT_SLIDER, OnVdWScale)
1907        slideSizer.Add(vdwScale,1,wx.EXPAND|wx.RIGHT)
1908
1909        ellipseProbTxt = wx.StaticText(dataDisplay,-1,'Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
1910        slideSizer.Add(ellipseProbTxt,0,wx.ALIGN_CENTER_VERTICAL)
1911        ellipseProb = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['ellipseProb'])
1912        ellipseProb.SetRange(1,99)
1913        ellipseProb.Bind(wx.EVT_SLIDER, OnEllipseProb)
1914        slideSizer.Add(ellipseProb,1,wx.EXPAND|wx.RIGHT)
1915
1916        ballScaleTxt = wx.StaticText(dataDisplay,-1,'Ball scale: '+'%.2f'%(drawingData['ballScale']))
1917        slideSizer.Add(ballScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
1918        ballScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['ballScale']))
1919        ballScale.Bind(wx.EVT_SLIDER, OnBallScale)
1920        slideSizer.Add(ballScale,1,wx.EXPAND|wx.RIGHT)
1921
1922        bondRadiusTxt = wx.StaticText(dataDisplay,-1,'Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
1923        slideSizer.Add(bondRadiusTxt,0,wx.ALIGN_CENTER_VERTICAL)
1924        bondRadius = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['bondRadius']))
1925        bondRadius.SetRange(1,25)
1926        bondRadius.Bind(wx.EVT_SLIDER, OnBondRadius)
1927        slideSizer.Add(bondRadius,1,wx.EXPAND|wx.RIGHT)
1928       
1929        slopSizer.Add(slideSizer,1,wx.EXPAND|wx.RIGHT)
1930        slopSizer.Add((10,5),0)
1931        slopSizer.SetMinSize(wx.Size(300,10))
1932        mainSizer.Add(slopSizer,0)
1933        mainSizer.Add((5,5),0)
1934
1935        flexSizer = wx.FlexGridSizer(5,2,5,0)
1936        flexSizer.Add(wx.StaticText(dataDisplay,-1,'View Point:  '),0,wx.ALIGN_CENTER_VERTICAL)
1937        VP = drawingData['viewPoint'][0]
1938        viewPoint = wx.TextCtrl(dataDisplay,value='%.3f, %.3f, %.3f'%(VP[0],VP[1],VP[2]),
1939            style=wx.TE_READONLY,size=wx.Size(120,20),name='viewPoint')
1940        viewPoint.SetBackgroundColour(VERY_LIGHT_GREY)
1941        flexSizer.Add(viewPoint,0,wx.ALIGN_CENTER_VERTICAL)
1942       
1943        showABC = wx.CheckBox(dataDisplay,-1,label='Show test point?')
1944        showABC.Bind(wx.EVT_CHECKBOX, OnShowABC)
1945        showABC.SetValue(drawingData['showABC'])
1946        flexSizer.Add(showABC,0,wx.ALIGN_CENTER_VERTICAL)
1947
1948        unitCellBox = wx.CheckBox(dataDisplay,-1,label='Show unit cell?')
1949        unitCellBox.Bind(wx.EVT_CHECKBOX, OnShowUnitCell)
1950        unitCellBox.SetValue(drawingData['unitCellBox'])
1951        flexSizer.Add(unitCellBox,0,wx.ALIGN_CENTER_VERTICAL)
1952
1953        showHydrogen = wx.CheckBox(dataDisplay,-1,label='Show hydrogens?')
1954        showHydrogen.Bind(wx.EVT_CHECKBOX, OnShowHyd)
1955        showHydrogen.SetValue(drawingData['showHydrogen'])
1956        flexSizer.Add(showHydrogen,0,wx.ALIGN_CENTER_VERTICAL)
1957
1958        lineSizer = wx.BoxSizer(wx.HORIZONTAL)
1959        lineSizer.Add(wx.StaticText(dataDisplay,-1,'Background color:'),0,wx.ALIGN_CENTER_VERTICAL)
1960        backColor = wcs.ColourSelect(dataDisplay, -1,colour=drawingData['backColor'],size=wx.Size(25,25))
1961        backColor.Bind(wcs.EVT_COLOURSELECT, OnBackColor)
1962        lineSizer.Add(backColor,0,wx.ALIGN_CENTER_VERTICAL)
1963        flexSizer.Add(lineSizer,0,)
1964
1965        flexSizer.Add(wx.StaticText(dataDisplay,-1,'Hydrogen radius, A:  '),0,wx.ALIGN_CENTER_VERTICAL)
1966        sizeH = wx.TextCtrl(dataDisplay,-1,value='%.2f'%(drawingData['sizeH']),style=wx.TE_PROCESS_ENTER)
1967        sizeH.Bind(wx.EVT_TEXT_ENTER,OnSizeHatoms)
1968        sizeH.Bind(wx.EVT_KILL_FOCUS,OnSizeHatoms)
1969        flexSizer.Add(sizeH,0,wx.ALIGN_CENTER_VERTICAL)
1970
1971        flexSizer.Add(wx.StaticText(dataDisplay,-1,'Bond search factor:  '),0,wx.ALIGN_CENTER_VERTICAL)
1972        radFactor = wx.TextCtrl(dataDisplay,value='%.2f'%(drawingData['radiusFactor']),style=wx.TE_PROCESS_ENTER)
1973        radFactor.Bind(wx.EVT_TEXT_ENTER,OnRadFactor)
1974        radFactor.Bind(wx.EVT_KILL_FOCUS,OnRadFactor)
1975        flexSizer.Add(radFactor,0,wx.ALIGN_CENTER_VERTICAL)
1976        mainSizer.Add(flexSizer,0,)
1977
1978        dataDisplay.SetSizer(mainSizer)
1979        Size = mainSizer.Fit(self.dataFrame)
1980        Size[1] += 26                           #compensate for status bar
1981        dataDisplay.SetSize(Size)
1982        self.dataFrame.setSizePosLeft(Size)
1983       
1984    def UpdateTexture():
1985        generalData = data['General']       
1986        SGData = generalData['SGData']
1987        try:
1988            textureData = generalData['SH Texture']
1989        except KeyError:            #fix old files!
1990            textureData = generalData['SH Texture'] = {'Order':0,'Model':'cylindrical',
1991                'Sample omega':[False,0.0],'Sample chi':[False,0.0],'Sample phi':[False,0.0],
1992                'SH Coeff':[False,{}],'SHShow':False,'PFhkl':[0,0,1],
1993                'PFxyz':[0,0,1.],'PlotType':'Pole figure'}
1994        if 'SHShow' not in textureData:     #another fix
1995            textureData.update({'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
1996        try:                        #another fix!
1997            x = textureData['PlotType']
1998        except KeyError:
1999            textureData.update({'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
2000        shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
2001        SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
2002        if generalData['Type'] == 'Pawley' and G2gd.GetPatternTreeItemId(self,self.root,'Sequental results'):
2003            self.dataFrame.RefineTexture.Enable(True)
2004        shAngles = ['omega','chi','phi']
2005       
2006        def SetSHCoef():
2007            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],SamSym[textureData['Model']],textureData['Order'])
2008            newSHCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
2009            SHCoeff = textureData['SH Coeff'][1]
2010            for cofName in SHCoeff:
2011                if cofName in  cofNames:
2012                    newSHCoef[cofName] = SHCoeff[cofName]
2013            return newSHCoef
2014       
2015        def OnShOrder(event):
2016            Obj = event.GetEventObject()
2017            textureData['Order'] = int(Obj.GetValue())
2018            textureData['SH Coeff'][1] = SetSHCoef()
2019            wx.CallAfter(UpdateTexture)
2020            G2plt.PlotTexture(self,data,newPlot=False)
2021                       
2022        def OnShModel(event):
2023            Obj = event.GetEventObject()
2024            textureData['Model'] = Obj.GetValue()
2025            textureData['SH Coeff'][1] = SetSHCoef()
2026            wx.CallAfter(UpdateTexture)
2027            G2plt.PlotTexture(self,data,newPlot=False)
2028           
2029        def OnSHRefine(event):
2030            Obj = event.GetEventObject()
2031            textureData['SH Coeff'][0] = Obj.GetValue()
2032           
2033        def OnSHShow(event):
2034            Obj = event.GetEventObject()
2035            textureData['SHShow'] = Obj.GetValue()
2036            wx.CallAfter(UpdateTexture)
2037           
2038        def OnProjSel(event):
2039            Obj = event.GetEventObject()
2040            self.Projection = Obj.GetValue()
2041            G2plt.PlotTexture(self,data,newPlot=False)
2042           
2043        def OnColorSel(event):
2044            Obj = event.GetEventObject()
2045            self.ContourColor = Obj.GetValue()
2046            G2plt.PlotTexture(self,data,newPlot=False)
2047           
2048        def OnAngRef(event):
2049            Obj = event.GetEventObject()
2050            textureData[angIndx[Obj.GetId()]][0] = Obj.GetValue()
2051           
2052        def OnAngValue(event):
2053            Obj = event.GetEventObject()
2054            try:
2055                value =  float(Obj.GetValue())
2056            except ValueError:
2057                value = textureData[valIndx[Obj.GetId()]][1]
2058            Obj.SetValue('%8.2f'%(value))
2059            textureData[valIndx[Obj.GetId()]][1] = value
2060           
2061        def OnODFValue(event): 
2062            Obj = event.GetEventObject()
2063            try:
2064                value =  float(Obj.GetValue())
2065            except ValueError:
2066                value = textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]]
2067            Obj.SetValue('%8.3f'%(value))
2068            textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] = value
2069            G2plt.PlotTexture(self,data,newPlot=False)
2070           
2071        def OnPfType(event):
2072            Obj = event.GetEventObject()
2073            textureData['PlotType'] = Obj.GetValue()
2074            wx.CallAfter(UpdateTexture)
2075            G2plt.PlotTexture(self,data)
2076           
2077        def OnPFValue(event):
2078            Obj = event.GetEventObject()
2079            Saxis = Obj.GetValue().split()
2080            if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:               
2081                try:
2082                    hkl = [int(Saxis[i]) for i in range(3)]
2083                except (ValueError,IndexError):
2084                    hkl = textureData['PFhkl']
2085                if not np.any(np.array(hkl)):       #can't be all zeros!
2086                    hkl = textureData['PFhkl']
2087                Obj.SetValue('%d %d %d'%(hkl[0],hkl[1],hkl[2]))
2088                textureData['PFhkl'] = hkl
2089            else:
2090                try:
2091                    xyz = [float(Saxis[i]) for i in range(3)]
2092                except (ValueError,IndexError):
2093                    xyz = textureData['PFxyz']
2094                if not np.any(np.array(xyz)):       #can't be all zeros!
2095                    xyz = textureData['PFxyz']
2096                Obj.SetValue('%3.1f %3.1f %3.1f'%(xyz[0],xyz[1],xyz[2]))
2097                textureData['PFxyz'] = xyz
2098            G2plt.PlotTexture(self,data)
2099
2100        if Texture.GetSizer():
2101            Texture.GetSizer().Clear(True)
2102        mainSizer = wx.BoxSizer(wx.VERTICAL)
2103        titleSizer = wx.BoxSizer(wx.HORIZONTAL)
2104        titleSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2105        titleSizer.Add(wx.StaticText(Texture,-1,
2106            ' Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))),
2107            0,wx.ALIGN_CENTER_VERTICAL)
2108        mainSizer.Add(titleSizer,0)
2109        mainSizer.Add((0,5),0)
2110        shSizer = wx.FlexGridSizer(1,6,5,5)
2111        shSizer.Add(wx.StaticText(Texture,-1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL)
2112        shModel = wx.ComboBox(Texture,-1,value=textureData['Model'],choices=shModels,
2113            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2114        shModel.Bind(wx.EVT_COMBOBOX,OnShModel)
2115        shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL)
2116        shSizer.Add(wx.StaticText(Texture,-1,'  Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2117        shOrder = wx.ComboBox(Texture,-1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)],
2118            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2119        shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder)
2120        shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL)
2121        shRef = wx.CheckBox(Texture,-1,label=' Refine texture?')
2122        shRef.SetValue(textureData['SH Coeff'][0])
2123        shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine)
2124        shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL)
2125        shShow = wx.CheckBox(Texture,-1,label=' Show coeff.?')
2126        shShow.SetValue(textureData['SHShow'])
2127        shShow.Bind(wx.EVT_CHECKBOX, OnSHShow)
2128        shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL)
2129        mainSizer.Add(shSizer,0,0)
2130        mainSizer.Add((0,5),0)
2131        PTSizer = wx.FlexGridSizer(2,4,5,5)
2132        PTSizer.Add(wx.StaticText(Texture,-1,' Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL)
2133        choices = ['Axial pole distribution','Pole figure','Inverse pole figure']           
2134        pfType = wx.ComboBox(Texture,-1,value=str(textureData['PlotType']),choices=choices,
2135            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2136        pfType.Bind(wx.EVT_COMBOBOX,OnPfType)
2137        PTSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL)
2138        if 'Axial' not in textureData['PlotType']:
2139            PTSizer.Add(wx.StaticText(Texture,-1,' Projection type: '),0,wx.ALIGN_CENTER_VERTICAL)
2140            projSel = wx.ComboBox(Texture,-1,value=self.Projection,choices=['equal area','stereographic','3D display'],
2141                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2142            projSel.Bind(wx.EVT_COMBOBOX,OnProjSel)
2143            PTSizer.Add(projSel,0,wx.ALIGN_CENTER_VERTICAL)
2144        if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
2145            PTSizer.Add(wx.StaticText(Texture,-1,' Pole figure HKL: '),0,wx.ALIGN_CENTER_VERTICAL)
2146            PH = textureData['PFhkl']
2147            pfVal = wx.TextCtrl(Texture,-1,'%d %d %d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER)
2148        else:
2149            PTSizer.Add(wx.StaticText(Texture,-1,' Inverse pole figure XYZ: '),0,wx.ALIGN_CENTER_VERTICAL)
2150            PX = textureData['PFxyz']
2151            pfVal = wx.TextCtrl(Texture,-1,'%3.1f %3.1f %3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER)
2152        pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue)
2153        pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue)
2154        PTSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL)
2155        if 'Axial' not in textureData['PlotType']:
2156            PTSizer.Add(wx.StaticText(Texture,-1,' Color scheme'),0,wx.ALIGN_CENTER_VERTICAL)
2157            choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
2158            choice.sort()
2159            colorSel = wx.ComboBox(Texture,-1,value=self.ContourColor,choices=choice,
2160                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2161            colorSel.Bind(wx.EVT_COMBOBOX,OnColorSel)
2162            PTSizer.Add(colorSel,0,wx.ALIGN_CENTER_VERTICAL)       
2163        mainSizer.Add(PTSizer,0,wx.ALIGN_CENTER_VERTICAL)
2164        mainSizer.Add((0,5),0)
2165        if textureData['SHShow']:
2166            mainSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2167            mainSizer.Add((0,5),0)
2168            ODFSizer = wx.FlexGridSizer(2,8,2,2)
2169            ODFIndx = {}
2170            ODFkeys = textureData['SH Coeff'][1].keys()
2171            ODFkeys.sort()
2172            for item in ODFkeys:
2173                ODFSizer.Add(wx.StaticText(Texture,-1,item),0,wx.ALIGN_CENTER_VERTICAL)
2174                ODFval = wx.TextCtrl(Texture,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER)
2175                ODFIndx[ODFval.GetId()] = item
2176                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2177                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2178                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2179            mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2180            mainSizer.Add((0,5),0)
2181        mainSizer.Add((0,5),0)
2182        mainSizer.Add(wx.StaticText(Texture,-1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL)
2183        mainSizer.Add((0,5),0)
2184        angSizer = wx.BoxSizer(wx.HORIZONTAL)
2185        angIndx = {}
2186        valIndx = {}
2187        for item in ['Sample omega','Sample chi','Sample phi']:
2188            angRef = wx.CheckBox(Texture,-1,label=item+': ')
2189            angRef.SetValue(textureData[item][0])
2190            angIndx[angRef.GetId()] = item
2191            angRef.Bind(wx.EVT_CHECKBOX, OnAngRef)
2192            angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL)
2193            angVal = wx.TextCtrl(Texture,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER)
2194            valIndx[angVal.GetId()] = item
2195            angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue)
2196            angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue)
2197            angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL)
2198            angSizer.Add((5,0),0)
2199        mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL)
2200        Texture.SetSizer(mainSizer,True)
2201        mainSizer.Fit(self.dataFrame)
2202        Size = mainSizer.GetMinSize()
2203        Size[0] += 40
2204        Size[1] = max(Size[1],250) + 20
2205        Texture.SetSize(Size)
2206        Texture.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2207        Size[1] = min(Size[1],450)
2208        self.dataFrame.setSizePosLeft(Size)
2209       
2210    def UpdateDData():
2211        UseList = data['Histograms']
2212        if UseList:
2213            self.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,True)
2214            self.Refine.Enable(True)
2215        else:
2216            self.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,False)
2217            self.Refine.Enable(False)           
2218        generalData = data['General']       
2219        SGData = generalData['SGData']
2220        keyList = UseList.keys()
2221        keyList.sort()
2222        Indx = {}
2223       
2224        def OnPlotSel(event):
2225            Obj = event.GetEventObject()
2226            generalData['Data plot type'] = Obj.GetStringSelection()
2227            wx.CallAfter(UpdateDData)
2228            G2plt.PlotSizeStrainPO(self,data)
2229           
2230        def OnPOhkl(event):
2231            Obj = event.GetEventObject()
2232            Saxis = Obj.GetValue().split()
2233            try:
2234                hkl = [int(Saxis[i]) for i in range(3)]
2235            except (ValueError,IndexError):
2236                hkl = generalData['POhkl']
2237            if not np.any(np.array(hkl)):
2238                hkl = generalData['POhkl']
2239            generalData['POhkl'] = hkl
2240            h,k,l = hkl
2241            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2242            G2plt.PlotSizeStrainPO(self,data)
2243       
2244        def OnShowData(event):
2245            Obj = event.GetEventObject()
2246            hist = Indx[Obj.GetId()]
2247            UseList[hist]['Show'] = Obj.GetValue()
2248            wx.CallAfter(UpdateDData)
2249            G2plt.PlotSizeStrainPO(self,data)
2250           
2251        def OnCopyData(event):
2252            #how about HKLF data? This is only for PWDR data
2253            Obj = event.GetEventObject()
2254            hist = Indx[Obj.GetId()]
2255            sourceDict = UseList[hist]
2256            copyNames = ['Scale','Pref.Ori.','Size','Mustrain','HStrain','Extinction']
2257            copyDict = {}
2258            for name in copyNames: 
2259                copyDict[name] = copy.deepcopy(sourceDict[name])        #force copy
2260            keyList = ['All',]+UseList.keys()
2261            if UseList:
2262                copyList = []
2263                dlg = wx.MultiChoiceDialog(self, 
2264                    'Copy parameters to which histograms?', 'Copy parameters', 
2265                    keyList, wx.CHOICEDLG_STYLE)
2266                try:
2267                    if dlg.ShowModal() == wx.ID_OK:
2268                        result = dlg.GetSelections()
2269                        for i in result: 
2270                            copyList.append(keyList[i])
2271                        if 'All' in copyList: 
2272                            copyList = keyList[1:]
2273                        for item in copyList:
2274                            UseList[item].update(copy.deepcopy(copyDict))
2275                        wx.CallAfter(UpdateDData)
2276                finally:
2277                    dlg.Destroy()
2278           
2279        def OnScaleRef(event):
2280            Obj = event.GetEventObject()
2281            UseList[Indx[Obj.GetId()]]['Scale'][1] = Obj.GetValue()
2282           
2283        def OnScaleVal(event):
2284            Obj = event.GetEventObject()
2285            try:
2286                scale = float(Obj.GetValue())
2287                if scale > 0:
2288                    UseList[Indx[Obj.GetId()]]['Scale'][0] = scale
2289            except ValueError:
2290                pass
2291            Obj.SetValue("%.4f"%(UseList[Indx[Obj.GetId()]]['Scale'][0]))          #reset in case of error
2292           
2293        def OnSizeType(event):
2294            Obj = event.GetEventObject()
2295            hist = Indx[Obj.GetId()]
2296            UseList[hist]['Size'][0] = Obj.GetValue()
2297            G2plt.PlotSizeStrainPO(self,data)
2298            wx.CallAfter(UpdateDData)
2299           
2300        def OnSizeRef(event):
2301            Obj = event.GetEventObject()
2302            hist,pid = Indx[Obj.GetId()]
2303            if UseList[hist]['Size'][0] == 'ellipsoidal':
2304                UseList[hist]['Size'][5][pid] = Obj.GetValue()               
2305            else:
2306                UseList[hist]['Size'][2][pid] = Obj.GetValue()
2307           
2308        def OnSizeVal(event):
2309            Obj = event.GetEventObject()
2310            hist,pid = Indx[Obj.GetId()]
2311            if UseList[hist]['Size'][0] == 'ellipsoidal':
2312                try:
2313                    size = float(Obj.GetValue())
2314                    if pid < 3 and size <= 0.001:            #10A lower limit!
2315                        raise ValueError
2316                    UseList[hist]['Size'][4][pid] = size                   
2317                except ValueError:
2318                    pass
2319                Obj.SetValue("%.3f"%(UseList[hist]['Size'][4][pid]))          #reset in case of error
2320            else:
2321                try:
2322                    size = float(Obj.GetValue())
2323                    if size <= 0.001:            #10A lower limit!
2324                        raise ValueError
2325                    UseList[hist]['Size'][1][pid] = size
2326                except ValueError:
2327                    pass
2328                Obj.SetValue("%.3f"%(UseList[hist]['Size'][1][pid]))          #reset in case of error
2329            G2plt.PlotSizeStrainPO(self,data)
2330           
2331        def OnSizeAxis(event):           
2332            Obj = event.GetEventObject()
2333            hist = Indx[Obj.GetId()]
2334            Saxis = Obj.GetValue().split()
2335            try:
2336                hkl = [int(Saxis[i]) for i in range(3)]
2337            except (ValueError,IndexError):
2338                hkl = UseList[hist]['Size'][3]
2339            if not np.any(np.array(hkl)):
2340                hkl = UseList[hist]['Size'][3]
2341            UseList[hist]['Size'][3] = hkl
2342            h,k,l = hkl
2343            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2344                       
2345        def OnStrainType(event):
2346            Obj = event.GetEventObject()
2347            hist = Indx[Obj.GetId()]
2348            UseList[hist]['Mustrain'][0] = Obj.GetValue()
2349            G2plt.PlotSizeStrainPO(self,data)
2350            wx.CallAfter(UpdateDData)
2351           
2352        def OnStrainRef(event):
2353            Obj = event.GetEventObject()
2354            hist,pid = Indx[Obj.GetId()]
2355            if UseList[hist]['Mustrain'][0] == 'generalized':
2356                UseList[hist]['Mustrain'][5][pid] = Obj.GetValue()
2357            else:
2358                UseList[hist]['Mustrain'][2][pid] = Obj.GetValue()
2359           
2360        def OnStrainVal(event):
2361            Snames = G2spc.MustrainNames(SGData)
2362            Obj = event.GetEventObject()
2363            hist,pid = Indx[Obj.GetId()]
2364            try:
2365                strain = float(Obj.GetValue())
2366                if UseList[hist]['Mustrain'][0] == 'generalized':
2367                    if '4' in Snames[pid] and strain < 0:
2368                        raise ValueError
2369                    UseList[hist]['Mustrain'][4][pid] = strain
2370                else:
2371                    if strain <= 0:
2372                        raise ValueError
2373                    UseList[hist]['Mustrain'][1][pid] = strain
2374            except ValueError:
2375                pass
2376            if UseList[hist]['Mustrain'][0] == 'generalized':
2377                Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][4][pid]))          #reset in case of error
2378            else:
2379                Obj.SetValue("%.1f"%(UseList[hist]['Mustrain'][1][pid]))          #reset in case of error
2380            G2plt.PlotSizeStrainPO(self,data)
2381           
2382        def OnStrainAxis(event):
2383            Obj = event.GetEventObject()
2384            hist = Indx[Obj.GetId()]
2385            Saxis = Obj.GetValue().split()
2386            try:
2387                hkl = [int(Saxis[i]) for i in range(3)]
2388            except (ValueError,IndexError):
2389                hkl = UseList[hist]['Mustrain'][3]
2390            if not np.any(np.array(hkl)):
2391                hkl = UseList[hist]['Mustrain'][3]
2392            UseList[hist]['Mustrain'][3] = hkl
2393            h,k,l = hkl
2394            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2395            G2plt.PlotSizeStrainPO(self,data)
2396           
2397        def OnHstrainRef(event):
2398            Obj = event.GetEventObject()
2399            hist,pid = Indx[Obj.GetId()]
2400            UseList[hist]['HStrain'][1][pid] = Obj.GetValue()
2401           
2402        def OnHstrainVal(event):
2403            Snames = G2spc.HStrainNames(SGData)
2404            Obj = event.GetEventObject()
2405            hist,pid = Indx[Obj.GetId()]
2406            try:
2407                strain = float(Obj.GetValue())
2408                UseList[hist]['HStrain'][0][pid] = strain
2409            except ValueError:
2410                pass
2411            Obj.SetValue("%.5f"%(UseList[hist]['HStrain'][0][pid]))          #reset in case of error
2412
2413        def OnPOType(event):
2414            Obj = event.GetEventObject()
2415            hist = Indx[Obj.GetId()]
2416            if 'March' in Obj.GetValue():
2417                UseList[hist]['Pref.Ori.'][0] = 'MD'
2418            else:
2419                UseList[hist]['Pref.Ori.'][0] = 'SH'
2420            wx.CallAfter(UpdateDData)           
2421
2422        def OnPORef(event):
2423            Obj = event.GetEventObject()
2424            hist = Indx[Obj.GetId()]
2425            UseList[hist]['Pref.Ori.'][2] = Obj.GetValue()
2426           
2427        def OnPOVal(event):
2428            Obj = event.GetEventObject()
2429            hist = Indx[Obj.GetId()]
2430            try:
2431                mdVal = float(Obj.GetValue())
2432                if mdVal > 0:
2433                    UseList[hist]['Pref.Ori.'][1] = mdVal
2434            except ValueError:
2435                pass
2436            Obj.SetValue("%.3f"%(UseList[hist]['Pref.Ori.'][1]))          #reset in case of error
2437           
2438        def OnPOAxis(event):
2439            Obj = event.GetEventObject()
2440            hist = Indx[Obj.GetId()]
2441            Saxis = Obj.GetValue().split()
2442            try:
2443                hkl = [int(Saxis[i]) for i in range(3)]
2444            except (ValueError,IndexError):
2445                hkl = UseList[hist]['Pref.Ori.'][3]
2446            if not np.any(np.array(hkl)):
2447                hkl = UseList[hist]['Pref.Ori.'][3]
2448            UseList[hist]['Pref.Ori.'][3] = hkl
2449            h,k,l = hkl
2450            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2451           
2452        def OnPOOrder(event):
2453            Obj = event.GetEventObject()
2454            hist = Indx[Obj.GetId()]
2455            Order = int(Obj.GetValue())
2456            UseList[hist]['Pref.Ori.'][4] = Order
2457            UseList[hist]['Pref.Ori.'][5] = SetPOCoef(Order,hist)
2458            wx.CallAfter(UpdateDData)
2459
2460        def SetPOCoef(Order,hist):
2461            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',Order,False)     #cylindrical & no M
2462            newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
2463            POCoeff = UseList[hist]['Pref.Ori.'][5]
2464            for cofName in POCoeff:
2465                if cofName in  cofNames:
2466                    newPOCoef[cofName] = POCoeff[cofName]
2467            return newPOCoef
2468       
2469        def OnExtRef(event):
2470            Obj = event.GetEventObject()
2471            UseList[Indx[Obj.GetId()]]['Extinction'][1] = Obj.GetValue()
2472           
2473        def OnExtVal(event):
2474            Obj = event.GetEventObject()
2475            try:
2476                ext = float(Obj.GetValue())
2477                if ext >= 0:
2478                    UseList[Indx[Obj.GetId()]]['Extinction'][0] = ext
2479            except ValueError:
2480                pass
2481            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][0]))          #reset in case of error
2482           
2483        def checkAxis(axis):
2484            if not np.any(np.array(axis)):
2485                return False
2486            return axis
2487           
2488        def PlotSizer():
2489            plotSizer = wx.BoxSizer(wx.VERTICAL)
2490            choice = ['Mustrain','Size','Preferred orientation']
2491            plotSel = wx.RadioBox(DData,-1,'Select plot type:',choices=choice,
2492                majorDimension=3,style=wx.RA_SPECIFY_COLS)
2493            plotSel.SetStringSelection(generalData['Data plot type'])
2494            plotSel.Bind(wx.EVT_RADIOBOX,OnPlotSel)   
2495            plotSizer.Add(plotSel)
2496            if generalData['Data plot type'] == 'Preferred orientation':
2497                POhklSizer = wx.BoxSizer(wx.HORIZONTAL)
2498                POhklSizer.Add(wx.StaticText(DData,-1,' Plot preferred orientation for H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2499                h,k,l = generalData['POhkl']
2500                poAxis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2501                poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOhkl)
2502                poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOhkl)
2503                POhklSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
2504                plotSizer.Add(POhklSizer)           
2505            return plotSizer
2506           
2507        def ScaleSizer():
2508            scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
2509            scaleRef = wx.CheckBox(DData,-1,label=' Phase fraction: ')
2510            scaleRef.SetValue(UseList[item]['Scale'][1])
2511            Indx[scaleRef.GetId()] = item
2512            scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
2513            scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
2514            scaleVal = wx.TextCtrl(DData,wx.ID_ANY,
2515                '%.4f'%(UseList[item]['Scale'][0]),style=wx.TE_PROCESS_ENTER)
2516            Indx[scaleVal.GetId()] = item
2517            scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
2518            scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
2519            scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
2520            return scaleSizer
2521           
2522        def TopSizer(name,choices,parm,OnType):
2523            topSizer = wx.BoxSizer(wx.HORIZONTAL)
2524            topSizer.Add(wx.StaticText(DData,-1,name),0,wx.ALIGN_CENTER_VERTICAL)
2525            sizeType = wx.ComboBox(DData,wx.ID_ANY,value=UseList[item][parm][0],choices=choices,
2526                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2527            sizeType.Bind(wx.EVT_COMBOBOX, OnType)
2528            Indx[sizeType.GetId()] = item
2529            topSizer.Add(sizeType)
2530            topSizer.Add((5,0),0)
2531            return topSizer
2532           
2533        def IsoSizer(name,parm,fmt,OnVal,OnRef):
2534            isoSizer = wx.BoxSizer(wx.HORIZONTAL)
2535            sizeRef = wx.CheckBox(DData,-1,label=name)
2536            sizeRef.thisown = False
2537            sizeRef.SetValue(UseList[item][parm][2][0])
2538            Indx[sizeRef.GetId()] = [item,0]
2539            sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
2540            isoSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2541            sizeVal = wx.TextCtrl(DData,wx.ID_ANY,
2542                fmt%(UseList[item][parm][1][0]),style=wx.TE_PROCESS_ENTER)
2543            Indx[sizeVal.GetId()] = [item,0]
2544            sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
2545            sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
2546            isoSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2547            return isoSizer
2548           
2549        def UniSizer(parm,OnAxis):
2550            uniSizer = wx.BoxSizer(wx.HORIZONTAL)
2551            uniSizer.Add(wx.StaticText(DData,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2552            h,k,l = UseList[item][parm][3]
2553            Axis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2554            Indx[Axis.GetId()] = item
2555            Axis.Bind(wx.EVT_TEXT_ENTER,OnAxis)
2556            Axis.Bind(wx.EVT_KILL_FOCUS,OnAxis)
2557            uniSizer.Add(Axis,0,wx.ALIGN_CENTER_VERTICAL)
2558            return uniSizer
2559           
2560        def UniDataSizer(parmName,parm,fmt,OnVal,OnRef):
2561            dataSizer = wx.BoxSizer(wx.HORIZONTAL)
2562            parms = zip([' Equatorial '+parmName,' Axial '+parmName],
2563                UseList[item][parm][1],UseList[item][parm][2],range(2))
2564            for Pa,val,ref,id in parms:
2565                sizeRef = wx.CheckBox(DData,-1,label=Pa)
2566                sizeRef.thisown = False
2567                sizeRef.SetValue(ref)
2568                Indx[sizeRef.GetId()] = [item,id]
2569                sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
2570                dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2571                sizeVal = wx.TextCtrl(DData,wx.ID_ANY,fmt%(val),style=wx.TE_PROCESS_ENTER)
2572                Indx[sizeVal.GetId()] = [item,id]
2573                sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
2574                sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
2575                dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2576                dataSizer.Add((5,0),0)
2577            return dataSizer
2578           
2579        def EllSizeDataSizer():
2580            parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[item]['Size'][4],
2581                UseList[item]['Size'][5],range(6))
2582            dataSizer = wx.FlexGridSizer(1,6,5,5)
2583            for Pa,val,ref,id in parms:
2584                sizeRef = wx.CheckBox(DData,-1,label=Pa)
2585                sizeRef.thisown = False
2586                sizeRef.SetValue(ref)
2587                Indx[sizeRef.GetId()] = [item,id]
2588                sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2589                dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2590                sizeVal = wx.TextCtrl(DData,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER)
2591                Indx[sizeVal.GetId()] = [item,id]
2592                sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2593                sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2594                dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2595            return dataSizer
2596           
2597        def GenStrainDataSizer():
2598            Snames = G2spc.MustrainNames(SGData)
2599            numb = len(Snames)
2600            if len(UseList[item]['Mustrain'][4]) < numb:
2601                UseList[item]['Mustrain'][4] = numb*[0.0,]
2602                UseList[item]['Mustrain'][5] = numb*[False,]
2603            parms = zip(Snames,UseList[item]['Mustrain'][4],UseList[item]['Mustrain'][5],range(numb))
2604            dataSizer = wx.FlexGridSizer(1,6,5,5)
2605            for Pa,val,ref,id in parms:
2606                strainRef = wx.CheckBox(DData,-1,label=Pa)
2607                strainRef.thisown = False
2608                strainRef.SetValue(ref)
2609                Indx[strainRef.GetId()] = [item,id]
2610                strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2611                dataSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2612                strainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
2613                Indx[strainVal.GetId()] = [item,id]
2614                strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2615                strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2616                dataSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2617            return dataSizer
2618           
2619        def HstrainSizer():
2620            hstrainSizer = wx.FlexGridSizer(1,6,5,5)
2621            Hsnames = G2spc.HStrainNames(SGData)
2622            parms = zip(Hsnames,UseList[item]['HStrain'][0],UseList[item]['HStrain'][1],range(len(Hsnames)))
2623            for Pa,val,ref,id in parms:
2624                hstrainRef = wx.CheckBox(DData,-1,label=Pa)
2625                hstrainRef.thisown = False
2626                hstrainRef.SetValue(ref)
2627                Indx[hstrainRef.GetId()] = [item,id]
2628                hstrainRef.Bind(wx.EVT_CHECKBOX, OnHstrainRef)
2629                hstrainSizer.Add(hstrainRef,0,wx.ALIGN_CENTER_VERTICAL)
2630                hstrainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
2631                Indx[hstrainVal.GetId()] = [item,id]
2632                hstrainVal.Bind(wx.EVT_TEXT_ENTER,OnHstrainVal)
2633                hstrainVal.Bind(wx.EVT_KILL_FOCUS,OnHstrainVal)
2634                hstrainSizer.Add(hstrainVal,0,wx.ALIGN_CENTER_VERTICAL)
2635            return hstrainSizer
2636           
2637        def PoTopSizer(POData):
2638            poSizer = wx.FlexGridSizer(1,6,5,5)
2639            choice = ['March-Dollase','Spherical harmonics']
2640            POtype = choice[['MD','SH'].index(POData[0])]
2641            poSizer.Add(wx.StaticText(DData,-1,' Preferred orientation model '),0,wx.ALIGN_CENTER_VERTICAL)
2642            POType = wx.ComboBox(DData,wx.ID_ANY,value=POtype,choices=choice,
2643                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2644            Indx[POType.GetId()] = item
2645            POType.Bind(wx.EVT_COMBOBOX, OnPOType)
2646            poSizer.Add(POType)
2647            if POData[0] == 'SH':
2648                poSizer.Add(wx.StaticText(DData,-1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2649                poOrder = wx.ComboBox(DData,wx.ID_ANY,value=str(POData[4]),choices=[str(2*i) for i in range(18)],
2650                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2651                Indx[poOrder.GetId()] = item
2652                poOrder.Bind(wx.EVT_COMBOBOX,OnPOOrder)
2653                poSizer.Add(poOrder,0,wx.ALIGN_CENTER_VERTICAL)
2654                poRef = wx.CheckBox(DData,-1,label=' Refine? ')
2655                poRef.SetValue(POData[2])
2656                Indx[poRef.GetId()] = item
2657                poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
2658                poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
2659            return poSizer
2660           
2661        def MDDataSizer(POData):
2662            poSizer = wx.BoxSizer(wx.HORIZONTAL)
2663            poRef = wx.CheckBox(DData,-1,label=' March-Dollase ratio: ')
2664            poRef.SetValue(POData[2])
2665            Indx[poRef.GetId()] = item
2666            poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
2667            poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
2668            poVal = wx.TextCtrl(DData,wx.ID_ANY,
2669                '%.3f'%(POData[1]),style=wx.TE_PROCESS_ENTER)
2670            Indx[poVal.GetId()] = item
2671            poVal.Bind(wx.EVT_TEXT_ENTER,OnPOVal)
2672            poVal.Bind(wx.EVT_KILL_FOCUS,OnPOVal)
2673            poSizer.Add(poVal,0,wx.ALIGN_CENTER_VERTICAL)
2674            poSizer.Add(wx.StaticText(DData,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2675            h,k,l =POData[3]
2676            poAxis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2677            Indx[poAxis.GetId()] = item
2678            poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOAxis)
2679            poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOAxis)
2680            poSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
2681            return poSizer
2682           
2683        def SHDataSizer(POData):
2684            textJ = G2lat.textureIndex(POData[5])
2685            mainSizer.Add(wx.StaticText(DData,-1,' Spherical harmonic coefficients: '+'Texture index: %.3f'%(textJ)),0,wx.ALIGN_CENTER_VERTICAL)
2686            mainSizer.Add((0,5),0)
2687            ODFSizer = wx.FlexGridSizer(2,8,2,2)
2688            ODFIndx = {}
2689            ODFkeys = POData[5].keys()
2690            ODFkeys.sort()
2691            for odf in ODFkeys:
2692                ODFSizer.Add(wx.StaticText(DData,-1,odf),0,wx.ALIGN_CENTER_VERTICAL)
2693                ODFval = wx.TextCtrl(DData,wx.ID_ANY,'%8.3f'%(POData[5][odf]),style=wx.TE_PROCESS_ENTER)
2694                ODFIndx[ODFval.GetId()] = odf
2695#                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2696#                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2697                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2698            return ODFSizer
2699           
2700        def ExtSizer():           
2701            extSizer = wx.BoxSizer(wx.HORIZONTAL)
2702            extRef = wx.CheckBox(DData,-1,label=' Extinction: ')
2703            extRef.SetValue(UseList[item]['Extinction'][1])
2704            Indx[extRef.GetId()] = item
2705            extRef.Bind(wx.EVT_CHECKBOX, OnExtRef)
2706            extSizer.Add(extRef,0,wx.ALIGN_CENTER_VERTICAL)
2707            extVal = wx.TextCtrl(DData,wx.ID_ANY,
2708                '%.2f'%(UseList[item]['Extinction'][0]),style=wx.TE_PROCESS_ENTER)
2709            Indx[extVal.GetId()] = item
2710            extVal.Bind(wx.EVT_TEXT_ENTER,OnExtVal)
2711            extVal.Bind(wx.EVT_KILL_FOCUS,OnExtVal)
2712            extSizer.Add(extVal,0,wx.ALIGN_CENTER_VERTICAL)
2713            return extSizer
2714           
2715        if DData.GetSizer():
2716            DData.GetSizer().Clear(True)
2717        mainSizer = wx.BoxSizer(wx.VERTICAL)
2718        mainSizer.Add(wx.StaticText(DData,-1,'Histogram data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2719        mainSizer.Add(PlotSizer())           
2720           
2721        for item in keyList:
2722            histData = UseList[item]
2723           
2724            showSizer = wx.BoxSizer(wx.HORIZONTAL)
2725            showData = wx.CheckBox(DData,-1,label=' Show '+item)
2726            showData.SetValue(UseList[item]['Show'])
2727            Indx[showData.GetId()] = item
2728            showData.Bind(wx.EVT_CHECKBOX, OnShowData)
2729            showSizer.Add(showData,0,wx.ALIGN_CENTER_VERTICAL)
2730            copyData = wx.Button(DData,-1,label=' Copy?')
2731            Indx[copyData.GetId()] = item
2732            copyData.Bind(wx.EVT_BUTTON,OnCopyData)
2733            showSizer.Add(copyData,wx.ALIGN_CENTER_VERTICAL)
2734            mainSizer.Add((5,5),0)
2735            mainSizer.Add(showSizer,0,wx.ALIGN_CENTER_VERTICAL)
2736            mainSizer.Add((0,5),0)
2737           
2738            if UseList[item]['Show']:
2739                mainSizer.Add(ScaleSizer())
2740                mainSizer.Add((0,5),0)
2741               
2742            if item[:4] == 'PWDR' and UseList[item]['Show']:
2743                if UseList[item]['Size'][0] == 'isotropic':
2744                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
2745                    isoSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
2746                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
2747                    isoSizer.Add(IsoSizer(u' Cryst. size(\xb5m): ','Size','%.3f',
2748                        OnSizeVal,OnSizeRef),0,wx.ALIGN_CENTER_VERTICAL)
2749                    mainSizer.Add(isoSizer)
2750                elif UseList[item]['Size'][0] == 'uniaxial':
2751                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
2752                    uniSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
2753                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
2754                    uniSizer.Add(UniSizer('Size',OnSizeAxis),0,wx.ALIGN_CENTER_VERTICAL)
2755                    mainSizer.Add(uniSizer)
2756                    mainSizer.Add(UniDataSizer(u'size(\xb5m): ','Size','%.3f',OnSizeVal,OnSizeRef))
2757                elif UseList[item]['Size'][0] == 'ellipsoidal':
2758                    ellSizer = wx.BoxSizer(wx.HORIZONTAL)
2759                    ellSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
2760                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
2761                    ellSizer.Add(wx.StaticText(DData,-1,u' Coefficients(\xb5m): '),0,wx.ALIGN_CENTER_VERTICAL)
2762                    mainSizer.Add(ellSizer)
2763                    mainSizer.Add(EllSizeDataSizer())
2764                mainSizer.Add((0,5),0)                   
2765               
2766                if UseList[item]['Mustrain'][0] == 'isotropic':
2767                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
2768                    isoSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
2769                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
2770                    isoSizer.Add(IsoSizer(' microstrain: ','Mustrain','%.1f',
2771                        OnStrainVal,OnStrainRef),0,wx.ALIGN_CENTER_VERTICAL)                   
2772                    mainSizer.Add(isoSizer)
2773                    mainSizer.Add((0,5),0)
2774                elif UseList[item]['Mustrain'][0] == 'uniaxial':
2775                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
2776                    uniSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
2777                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
2778                    uniSizer.Add(UniSizer('Mustrain',OnStrainAxis),0,wx.ALIGN_CENTER_VERTICAL)
2779                    mainSizer.Add(uniSizer)
2780                    mainSizer.Add(UniDataSizer('mustrain: ','Mustrain','%.1f',OnStrainVal,OnStrainRef))
2781                elif UseList[item]['Mustrain'][0] == 'generalized':
2782                    genSizer = wx.BoxSizer(wx.HORIZONTAL)
2783                    genSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
2784                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
2785                    genSizer.Add(wx.StaticText(DData,-1,' Coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2786                    mainSizer.Add(genSizer)
2787                    mainSizer.Add(GenStrainDataSizer())                       
2788                mainSizer.Add((0,5),0)
2789               
2790                mainSizer.Add(wx.StaticText(DData,-1,' Hydrostatic/elastic strain:'))
2791                mainSizer.Add(HstrainSizer())
2792                   
2793                #texture  'Pref. Ori.':['MD',1.0,False,[0,0,1],0,[]] last two for 'SH' are SHorder & coeff
2794                poSizer = wx.BoxSizer(wx.VERTICAL)
2795                POData = UseList[item]['Pref.Ori.']
2796                poSizer.Add(PoTopSizer(POData))
2797                if POData[0] == 'MD':
2798                    poSizer.Add(MDDataSizer(POData))
2799                else:           #'SH'
2800                    if POData[4]:       #SH order > 0
2801                        poSizer.Add(SHDataSizer(POData))
2802                       
2803                mainSizer.Add(poSizer)
2804                mainSizer.Add((0,5),0)               
2805                #Extinction  'Extinction':[0.0,False]
2806                mainSizer.Add(ExtSizer())
2807                mainSizer.Add((0,5),0)
2808            elif item[:4] == 'HKLF' and UseList[item]['Show']:
2809                pass
2810        mainSizer.Add((5,5),0)
2811
2812        DData.SetSizer(mainSizer,True)
2813        mainSizer.FitInside(self.dataFrame)
2814        Size = mainSizer.GetMinSize()
2815        Size[0] += 40
2816        Size[1] = max(Size[1],250) + 20
2817        DData.SetSize(Size)
2818        DData.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2819        Size[1] = min(Size[1],450)
2820        self.dataFrame.setSizePosLeft(Size)
2821       
2822    def OnHklfAdd(event):
2823        UseList = data['Histograms']
2824        keyList = UseList.keys()
2825        TextList = []
2826        if self.PatternTree.GetCount():
2827            item, cookie = self.PatternTree.GetFirstChild(self.root)
2828            while item:
2829                name = self.PatternTree.GetItemText(item)
2830                if name not in keyList and 'HKLF' in name:
2831                    TextList.append(name)
2832                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)                       
2833            dlg = wx.MultiChoiceDialog(self, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2834            try:
2835                if dlg.ShowModal() == wx.ID_OK:
2836                    result = dlg.GetSelections()
2837                    for i in result:
2838                        histoName = TextList[i]
2839                        UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
2840                            'Extinction':['Lorentzian','Secondary Type I',{'Eg':[0.0,False]},]}                       
2841                    data['Histograms'] = UseList
2842                    wx.CallAfter(UpdateDData)
2843            finally:
2844                dlg.Destroy()
2845       
2846    def OnPwdrAdd(event):
2847        generalData = data['General']
2848        SGData = generalData['SGData']
2849        UseList = data['Histograms']
2850        newList = []
2851        NShkl = len(G2spc.MustrainNames(SGData))
2852        NDij = len(G2spc.HStrainNames(SGData))
2853        keyList = UseList.keys()
2854        TextList = ['All PWDR']
2855        if self.PatternTree.GetCount():
2856            item, cookie = self.PatternTree.GetFirstChild(self.root)
2857            while item:
2858                name = self.PatternTree.GetItemText(item)
2859                if name not in keyList and 'PWDR' in name:
2860                    TextList.append(name)
2861                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
2862            dlg = wx.MultiChoiceDialog(self, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2863            try:
2864                if dlg.ShowModal() == wx.ID_OK:
2865                    result = dlg.GetSelections()
2866                    for i in result: newList.append(TextList[i])
2867                    if 'All PWDR' in newList:
2868                        newList = TextList[1:]
2869                    for histoName in newList:
2870                        pId = G2gd.GetPatternTreeItemId(self,self.root,histoName)
2871                        UseList[histoName] = {'Histogram':histoName,'Show':False,
2872                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{}],
2873                            'Size':['isotropic',[4.,4.,],[False,False],[0,0,1],[4.,4.,4.,0.,0.,0.],6*[False,]],
2874                            'Mustrain':['isotropic',[1000.0,1000.0],[False,False],[0,0,1],
2875                                NShkl*[0.01,],NShkl*[False,]],
2876                            'HStrain':[NDij*[0.0,],NDij*[False,]],                         
2877                            'Extinction':[0.0,False]}
2878                        refList = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,pId,'Reflection Lists'))
2879                        refList[generalData['Name']] = []                       
2880                    data['Histograms'] = UseList
2881                    wx.CallAfter(UpdateDData)
2882            finally:
2883                dlg.Destroy()
2884       
2885    def OnDataDelete(event):
2886        UseList = data['Histograms']
2887        keyList = ['All',]+UseList.keys()
2888        keyList.sort()
2889        DelList = []
2890        if UseList:
2891            DelList = []
2892            dlg = wx.MultiChoiceDialog(self, 
2893                'Which histogram to delete from this phase?', 'Delete histogram', 
2894                keyList, wx.CHOICEDLG_STYLE)
2895            try:
2896                if dlg.ShowModal() == wx.ID_OK:
2897                    result = dlg.GetSelections()
2898                    for i in result: 
2899                        DelList.append(keyList[i])
2900                    if 'All' in DelList:
2901                        DelList = keyList[1:]
2902                    for i in DelList:
2903                        del UseList[i]
2904                    wx.CallAfter(UpdateDData)
2905            finally:
2906                dlg.Destroy()
2907
2908    def FillPawleyReflectionsGrid():
2909                       
2910        def KeyEditPawleyGrid(event):
2911            colList = self.PawleyRefl.GetSelectedCols()
2912            PawleyPeaks = data['Pawley ref']
2913            if event.GetKeyCode() == wx.WXK_RETURN:
2914                event.Skip(True)
2915            elif event.GetKeyCode() == wx.WXK_CONTROL:
2916                event.Skip(True)
2917            elif event.GetKeyCode() == wx.WXK_SHIFT:
2918                event.Skip(True)
2919            elif colList:
2920                self.PawleyRefl.ClearSelection()
2921                key = event.GetKeyCode()
2922                for col in colList:
2923                    if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
2924                        if key == 89: #'Y'
2925                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True
2926                        elif key == 78:  #'N'
2927                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False
2928                        FillPawleyReflectionsGrid()
2929           
2930        if 'Pawley ref' in data:
2931            PawleyPeaks = data['Pawley ref']                       
2932            rowLabels = []
2933            for i in range(len(PawleyPeaks)): rowLabels.append(str(i))
2934            colLabels = ['h','k','l','mul','d','refine','Fsq(hkl)','sig(Fsq)']
2935            Types = 4*[wg.GRID_VALUE_LONG,]+[wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,]+ \
2936                2*[wg.GRID_VALUE_FLOAT+':10,2',]
2937            PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
2938            self.PawleyRefl.SetTable(PawleyTable, True)
2939            self.PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid)                 
2940            self.PawleyRefl.SetMargins(0,0)
2941            self.PawleyRefl.AutoSizeColumns(False)
2942            self.dataFrame.setSizePosLeft([500,300])
2943                   
2944    def OnPawleyLoad(event):
2945        generalData = data['General']
2946        dmin = generalData['Pawley dmin']
2947        cell = generalData['Cell'][1:7]
2948        A = G2lat.cell2A(cell)
2949        SGData = generalData['SGData']
2950        HKLd = np.array(G2lat.GenHLaue(dmin,SGData,A))
2951        PawleyPeaks = []
2952        wx.BeginBusyCursor()
2953        try:
2954            for h,k,l,d in HKLd:
2955                ext,mul = G2spc.GenHKLf([h,k,l],SGData)[:2]
2956                if not ext:
2957                    PawleyPeaks.append([h,k,l,mul,d,False,100.0,1.0])
2958        finally:
2959            wx.EndBusyCursor()
2960        data['Pawley ref'] = PawleyPeaks
2961        FillPawleyReflectionsGrid()
2962       
2963    def OnPawleyEstimate(event):
2964        try:
2965            Refs = data['Pawley ref']
2966            Histograms = data['Histograms']
2967        except KeyError:
2968            print '**** Error - no histograms defined for this phase ****'
2969            return
2970        HistoNames = Histograms.keys()
2971        PatternId = G2gd.GetPatternTreeItemId(self,self.root,HistoNames[0])
2972        xdata = self.PatternTree.GetItemPyData(PatternId)[1]
2973        Inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId,'Instrument Parameters'))
2974        Inst = dict(zip(Inst[3],Inst[1]))
2975        Sample = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId,'Sample Parameters'))
2976        if 'Lam' in Inst:
2977            wave = Inst['Lam']
2978        else:
2979            wave = Inst['Lam1']
2980       
2981        posCorr = Inst['Zero']
2982        const = 9.e-2/(np.pi*Sample['Gonio. radius'])                  #shifts in microns
2983       
2984        for ref in Refs:
2985            pos = 2.0*asind(wave/(2.0*ref[4]))
2986            if 'Bragg' in Sample['Type']:
2987                pos -= const*(4.*Sample['Shift'][0]*cosd(pos/2.0)+ \
2988                    Sample['Transparency'][0]*sind(pos)*100.0)            #trans(=1/mueff) in cm
2989            else:               #Debye-Scherrer - simple but maybe not right
2990                pos -= const*(Sample['DisplaceX'][0]*cosd(pos)+Sample['DisplaceY'][0]*sind(pos))
2991            indx = np.searchsorted(xdata[0],pos)
2992            try:
2993                ref[6] = xdata[1][indx]
2994            except IndexError:
2995                pass
2996        FillPawleyReflectionsGrid()
2997                           
2998    def OnPawleyDelete(event):
2999        dlg = wx.MessageDialog(self,'Do you really want to delete Pawley reflections?','Delete', 
3000            wx.YES_NO | wx.ICON_QUESTION)
3001        try:
3002            result = dlg.ShowModal()
3003        finally:
3004            dlg.Destroy()
3005        if result == wx.ID_YES: 
3006            data['Pawley ref'] = []
3007            FillPawleyReflectionsGrid()
3008   
3009    def OnTextureRefine(event):
3010        event.Skip()       
3011           
3012    def OnTextureClear(event):
3013        event.Skip()
3014
3015    def OnPageChanged(event):
3016        page = event.GetSelection()
3017        text = self.dataDisplay.GetPageText(page)
3018        if text == 'Atoms':
3019            self.dataFrame.SetMenuBar(self.dataFrame.AtomsMenu)
3020            self.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
3021            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestAdd, id=G2gd.wxID_ATOMSTESTADD)
3022            self.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
3023            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestInsert, id=G2gd.wxID_ATONTESTINSERT)
3024            self.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
3025            self.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
3026            self.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
3027            self.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
3028            self.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS)
3029            self.dataFrame.Bind(wx.EVT_MENU, OnDistAngle, id=G2gd.wxID_ATOMSDISAGL)
3030            FillAtomsGrid()
3031        elif text == 'General':
3032            UpdateGeneral()
3033        elif text == 'Data':
3034            self.dataFrame.SetMenuBar(self.dataFrame.DataMenu)
3035            self.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD)
3036            self.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD)
3037            self.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE)
3038            UpdateDData()
3039            G2plt.PlotSizeStrainPO(self,data,Start=True)
3040        elif text == 'Draw Options':
3041            self.dataFrame.SetMenuBar(self.dataFrame.DataDrawOptions)
3042            UpdateDrawOptions()
3043            G2plt.PlotStructure(self,data)
3044        elif text == 'Draw Atoms':
3045            self.dataFrame.SetMenuBar(self.dataFrame.DrawAtomsMenu)
3046            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE)
3047            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL)
3048            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR)
3049            self.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR)
3050            self.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT)
3051            self.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV)
3052            self.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM)
3053            self.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD)           
3054            self.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL)
3055            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE)
3056            UpdateDrawAtoms()
3057            G2plt.PlotStructure(self,data)
3058        elif text == 'Pawley reflections':
3059            self.dataFrame.SetMenuBar(self.dataFrame.PawleyMenu)
3060            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD)
3061            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyEstimate, id=G2gd.wxID_PAWLEYESTIMATE)
3062            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyDelete, id=G2gd.wxID_PAWLEYDELETE)           
3063            FillPawleyReflectionsGrid()
3064        elif text == 'Texture':
3065            self.dataFrame.SetMenuBar(self.dataFrame.TextureMenu)
3066            self.dataFrame.Bind(wx.EVT_MENU, OnTextureRefine, id=G2gd.wxID_REFINETEXTURE)
3067            self.dataFrame.Bind(wx.EVT_MENU, OnTextureClear, id=G2gd.wxID_CLEARTEXTURE)
3068            UpdateTexture()                       
3069            G2plt.PlotTexture(self,data,Start=True)
3070        else:
3071            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
3072        event.Skip()
3073       
3074    General = wx.Window(self.dataDisplay)
3075    self.dataDisplay.AddPage(General,'General')
3076    SetupGeneral()
3077    GeneralData = data['General']
3078    UpdateGeneral()
3079
3080    if GeneralData['Type'] == 'Pawley':
3081        DData = wx.ScrolledWindow(self.dataDisplay)
3082        self.dataDisplay.AddPage(DData,'Data')
3083        self.PawleyRefl = G2gd.GSGrid(self.dataDisplay)
3084        self.dataDisplay.AddPage(self.PawleyRefl,'Pawley reflections')
3085        Texture = wx.ScrolledWindow(self.dataDisplay)
3086        self.dataDisplay.AddPage(Texture,'Texture')
3087    else:
3088        DData = wx.ScrolledWindow(self.dataDisplay)
3089        self.dataDisplay.AddPage(DData,'Data')
3090        Texture = wx.ScrolledWindow(self.dataDisplay)
3091        self.dataDisplay.AddPage(Texture,'Texture')
3092        Atoms = G2gd.GSGrid(self.dataDisplay)
3093        self.dataDisplay.AddPage(Atoms,'Atoms')
3094        drawOptions = wx.Window(self.dataDisplay)
3095        self.dataDisplay.AddPage(drawOptions,'Draw Options')
3096        drawAtoms = G2gd.GSGrid(self.dataDisplay)
3097        self.dataDisplay.AddPage(drawAtoms,'Draw Atoms')
3098
3099    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
3100    self.dataDisplay.SetSelection(oldPage)
3101   
3102           
Note: See TracBrowser for help on using the repository browser.