source: trunk/GSASIIphsGUI.py @ 457

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

begin distance angle calcs
move gpxfile routines from GSASIIstruct.py to GSASIIIO.py
move getVCov & ValEsd? to GSASIImath.py
add some text to help/gsasII.html

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