source: trunk/GSASIIphsGUI.py @ 459

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

fix bug in GenAtom? - didn't eliminate special position duplicates
refactor DisAglDialog? to have a reset & save results to general
begin torsion & distance/angle calcs in drawing

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