source: trunk/GSASIIphsGUI.py @ 657

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

fixups of findOffset & mapsearch

  • Property svn:keywords set to Date Author Revision URL Id
File size: 192.4 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - phase data display routines
3########### SVN repository information ###################
4# $Date: 2012-06-26 20:44:56 +0000 (Tue, 26 Jun 2012) $
5# $Author: vondreele $
6# $Revision: 657 $
7# $URL: trunk/GSASIIphsGUI.py $
8# $Id: GSASIIphsGUI.py 657 2012-06-26 20:44:56Z vondreele $
9########### SVN repository information ###################
10import wx
11import wx.grid as wg
12import matplotlib as mpl
13import math
14import copy
15import time
16import sys
17import random as ran
18import cPickle
19import GSASIIpath
20import GSASIIlattice as G2lat
21import GSASIIspc as G2spc
22import GSASIIElem as G2elem
23import GSASIIElemGUI as G2elemGUI
24import GSASIIplot as G2plt
25import GSASIIgrid as G2gd
26import GSASIIIO as G2IO
27import GSASIIstruct as G2str
28import GSASIImath as G2mth
29import GSASIIpwd as G2pwd
30import numpy as np
31import numpy.linalg as nl
32import numpy.ma as ma
33
34VERY_LIGHT_GREY = wx.Colour(235,235,235)
35WHITE = wx.Colour(255,255,255)
36BLACK = wx.Colour(0,0,0)
37
38# trig functions in degrees
39sind = lambda x: math.sin(x*math.pi/180.)
40tand = lambda x: math.tan(x*math.pi/180.)
41cosd = lambda x: math.cos(x*math.pi/180.)
42asind = lambda x: 180.*math.asin(x)/math.pi
43
44class SymOpDialog(wx.Dialog):
45    def __init__(self,parent,SGData,New=True):
46        wx.Dialog.__init__(self,parent,-1,'Select symmetry operator',
47            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
48        panel = wx.Panel(self)
49        self.SGData = SGData
50        self.New = New
51        self.OpSelected = [0,0,0,[0,0,0],False]
52        mainSizer = wx.BoxSizer(wx.VERTICAL)
53        mainSizer.Add((5,5),0)
54        if SGData['SGInv']:
55            choice = ['No','Yes']
56            self.inv = wx.RadioBox(panel,-1,'Choose inversion?',choices=choice)
57            self.inv.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
58            mainSizer.Add(self.inv,0,wx.ALIGN_CENTER_VERTICAL)
59        mainSizer.Add((5,5),0)
60        if SGData['SGLatt'] != 'P':
61            LattOp = G2spc.Latt2text(SGData['SGLatt']).split(';')
62            self.latt = wx.RadioBox(panel,-1,'Choose cell centering?',choices=LattOp)
63            self.latt.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
64            mainSizer.Add(self.latt,0,wx.ALIGN_CENTER_VERTICAL)
65        mainSizer.Add((5,5),0)
66        if SGData['SGLaue'] in ['-1','2/m','mmm','4/m','4/mmm']:
67            Ncol = 2
68        else:
69            Ncol = 3
70        OpList = []
71        for M,T in SGData['SGOps']:
72            OpList.append(G2spc.MT2text(M,T))
73        self.oprs = wx.RadioBox(panel,-1,'Choose space group operator?',choices=OpList,
74            majorDimension=Ncol)
75        self.oprs.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
76        mainSizer.Add(self.oprs,0,wx.ALIGN_CENTER_VERTICAL)
77        mainSizer.Add((5,5),0)
78        mainSizer.Add(wx.StaticText(panel,-1,"   Choose unit cell?"),0,wx.ALIGN_CENTER_VERTICAL)
79        mainSizer.Add((5,5),0)
80        cellSizer = wx.BoxSizer(wx.HORIZONTAL)
81        cellSizer.Add((5,0),0)
82        cellName = ['X','Y','Z']
83        self.cell = []
84        for i in range(3):
85            self.cell.append(wx.SpinCtrl(panel,-1,cellName[i],size=wx.Size(50,20)))
86            self.cell[-1].SetRange(-3,3)
87            self.cell[-1].SetValue(0)
88            self.cell[-1].Bind(wx.EVT_SPINCTRL, self.OnOpSelect)
89            cellSizer.Add(self.cell[-1],0,wx.ALIGN_CENTER_VERTICAL)
90        mainSizer.Add(cellSizer,0,)
91        if self.New:
92            choice = ['No','Yes']
93            self.new = wx.RadioBox(panel,-1,'Generate new positions?',choices=choice)
94            self.new.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
95            mainSizer.Add(self.new,0,wx.ALIGN_CENTER_VERTICAL)
96        mainSizer.Add((5,5),0)
97
98        OkBtn = wx.Button(panel,-1,"Ok")
99        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
100        cancelBtn = wx.Button(panel,-1,"Cancel")
101        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
102        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
103        btnSizer.Add((20,20),1)
104        btnSizer.Add(OkBtn)
105        btnSizer.Add((20,20),1)
106        btnSizer.Add(cancelBtn)
107        btnSizer.Add((20,20),1)
108
109        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
110        panel.SetSizer(mainSizer)
111        panel.Fit()
112        self.Fit()
113
114    def OnOpSelect(self,event):
115        if self.SGData['SGInv']:
116            self.OpSelected[0] = self.inv.GetSelection()
117        if self.SGData['SGLatt'] != 'P':
118            self.OpSelected[1] = self.latt.GetSelection()
119        self.OpSelected[2] = self.oprs.GetSelection()
120        for i in range(3):
121            self.OpSelected[3][i] = float(self.cell[i].GetValue())
122        if self.New:
123            self.OpSelected[4] = self.new.GetSelection()
124
125    def GetSelection(self):
126        return self.OpSelected
127
128    def OnOk(self,event):
129        parent = self.GetParent()
130        parent.Raise()
131        self.EndModal(wx.ID_OK)
132        self.Destroy()
133
134    def OnCancel(self,event):
135        parent = self.GetParent()
136        parent.Raise()
137        self.EndModal(wx.ID_CANCEL)
138        self.Destroy()
139
140class DisAglDialog(wx.Dialog):
141   
142    def __default__(self,data,default):
143        if data:
144            self.data = data
145        else:
146            self.data = {}
147            self.data['Name'] = default['Name']
148            self.data['Factors'] = [0.85,0.85]
149            self.data['AtomTypes'] = default['AtomTypes']
150            self.data['BondRadii'] = default['BondRadii']
151            self.data['AngleRadii'] = default['AngleRadii']
152       
153    def __init__(self,parent,data,default):
154        wx.Dialog.__init__(self,parent,-1,'Distance Angle Controls', 
155            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
156        self.default = default
157        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
158        self.__default__(data,self.default)
159        self.Draw(self.data)
160               
161    def Draw(self,data):
162        self.panel.Destroy()
163        self.panel = wx.Panel(self)
164        mainSizer = wx.BoxSizer(wx.VERTICAL)
165        mainSizer.Add(wx.StaticText(self.panel,-1,'Controls for phase '+data['Name']),
166            0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
167        mainSizer.Add((10,10),1)
168       
169        radiiSizer = wx.FlexGridSizer(2,3,5,5)
170        radiiSizer.Add(wx.StaticText(self.panel,-1,' Type'),0,wx.ALIGN_CENTER_VERTICAL)
171        radiiSizer.Add(wx.StaticText(self.panel,-1,'Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
172        radiiSizer.Add(wx.StaticText(self.panel,-1,'Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
173        self.objList = {}
174        for id,item in enumerate(self.data['AtomTypes']):
175            radiiSizer.Add(wx.StaticText(self.panel,-1,' '+item),0,wx.ALIGN_CENTER_VERTICAL)
176            bRadii = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['BondRadii'][id]),style=wx.TE_PROCESS_ENTER)
177            self.objList[bRadii.GetId()] = ['BondRadii',id]
178            bRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
179            bRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
180            radiiSizer.Add(bRadii,0,wx.ALIGN_CENTER_VERTICAL)
181            aRadii = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['AngleRadii'][id]),style=wx.TE_PROCESS_ENTER)
182            self.objList[aRadii.GetId()] = ['AngleRadii',id]
183            aRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
184            aRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
185            radiiSizer.Add(aRadii,0,wx.ALIGN_CENTER_VERTICAL)
186        mainSizer.Add(radiiSizer,0,wx.EXPAND)
187        factorSizer = wx.FlexGridSizer(2,2,5,5)
188        Names = ['Bond','Angle']
189        for i,name in enumerate(Names):
190            factorSizer.Add(wx.StaticText(self.panel,-1,name+' search factor'),0,wx.ALIGN_CENTER_VERTICAL)
191            bondFact = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['Factors'][i]),style=wx.TE_PROCESS_ENTER)
192            self.objList[bondFact.GetId()] = ['Factors',i]
193            bondFact.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
194            bondFact.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
195            factorSizer.Add(bondFact)
196        mainSizer.Add(factorSizer,0,wx.EXPAND)
197       
198        OkBtn = wx.Button(self.panel,-1,"Ok")
199        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
200        ResetBtn = wx.Button(self.panel,-1,'Reset')
201        ResetBtn.Bind(wx.EVT_BUTTON, self.OnReset)
202        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
203        btnSizer.Add((20,20),1)
204        btnSizer.Add(OkBtn)
205        btnSizer.Add(ResetBtn)
206        btnSizer.Add((20,20),1)
207        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
208        self.panel.SetSizer(mainSizer)
209        self.panel.Fit()
210        self.Fit()
211   
212    def OnRadiiVal(self,event):
213        Obj = event.GetEventObject()
214        item = self.objList[Obj.GetId()]
215        try:
216            self.data[item[0]][item[1]] = float(Obj.GetValue())
217        except ValueError:
218            pass
219        Obj.SetValue("%.3f"%(self.data[item[0]][item[1]]))          #reset in case of error
220       
221    def GetData(self):
222        return self.data
223       
224    def OnOk(self,event):
225        parent = self.GetParent()
226        parent.Raise()
227        self.EndModal(wx.ID_OK)             
228        self.Destroy()
229       
230    def OnReset(self,event):
231        data = {}
232        self.__default__(data,self.default)
233        self.Draw(self.data)
234       
235class SingleFloatDialog(wx.Dialog):
236   
237    def __init__(self,parent,title,prompt,value,limits=[0.,1.]):
238        wx.Dialog.__init__(self,parent,-1,title, 
239            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
240        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
241        self.limits = limits
242        self.value = value
243        self.prompt = prompt
244        self.Draw()
245       
246    def Draw(self):
247       
248        def OnValItem(event):
249            try:
250                val = float(valItem.GetValue())
251                if val < self.limits[0] or val > self.limits[1]:
252                    raise ValueError
253            except ValueError:
254                val = self.value
255            self.value = val
256            valItem.SetValue('%.5g'%(self.value))
257           
258        self.panel.Destroy()
259        self.panel = wx.Panel(self)
260        mainSizer = wx.BoxSizer(wx.VERTICAL)
261        mainSizer.Add(wx.StaticText(self.panel,-1,self.prompt),0,wx.ALIGN_CENTER)
262        valItem = wx.TextCtrl(self.panel,-1,value='%.5g'%(self.value),style=wx.TE_PROCESS_ENTER)
263        mainSizer.Add(valItem,0,wx.ALIGN_CENTER)
264        valItem.Bind(wx.EVT_TEXT_ENTER,OnValItem)
265        valItem.Bind(wx.EVT_KILL_FOCUS,OnValItem)
266        OkBtn = wx.Button(self.panel,-1,"Ok")
267        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
268        CancelBtn = wx.Button(self.panel,-1,'Cancel')
269        CancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
270        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
271        btnSizer.Add((20,20),1)
272        btnSizer.Add(OkBtn)
273        btnSizer.Add(CancelBtn)
274        btnSizer.Add((20,20),1)
275        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
276        self.panel.SetSizer(mainSizer)
277        self.panel.Fit()
278        self.Fit()
279
280    def GetValue(self):
281        return self.value
282       
283    def OnOk(self,event):
284        parent = self.GetParent()
285        parent.Raise()
286        self.EndModal(wx.ID_OK)             
287        self.Destroy()
288       
289    def OnCancel(self,event):
290        parent = self.GetParent()
291        parent.Raise()
292        self.EndModal(wx.ID_CANCEL)             
293        self.Destroy()
294       
295def UpdatePhaseData(G2frame,Item,data,oldPage):
296
297    Atoms = []
298    if G2frame.dataDisplay:
299        G2frame.dataDisplay.Destroy()
300    PhaseName = G2frame.PatternTree.GetItemText(Item)
301    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
302    G2frame.dataFrame.SetLabel('Phase Data for '+PhaseName)
303    G2frame.dataFrame.CreateStatusBar()
304    G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
305
306    def SetupGeneral():
307        generalData = data['General']
308        atomData = data['Atoms']
309        generalData['AtomTypes'] = []
310        generalData['Isotopes'] = {}
311# various patches
312        if 'Isotope' not in generalData:
313            generalData['Isotope'] = {}
314        if 'Data plot type' not in generalData:
315            generalData['Data plot type'] = 'Mustrain'
316        if 'POhkl' not in generalData:
317            generalData['POhkl'] = [0,0,1]
318        if 'Map' not in generalData:
319            generalData['Map'] = {'MapType':'','RefList':'','Resolution':0.5,
320                'rho':[],'rhoMax':0.,'mapSize':10.0,'cutOff':50.,'Flip':False}
321        if 'Flip' not in generalData:
322            generalData['Flip'] = {'RefList':'','Resolution':0.5,'Norm element':'None',
323                'k-factor':0.1}
324        if 'doPawley' not in generalData:
325            generalData['doPawley'] = False
326        if 'Pawley dmin' not in generalData:
327            generalData['Pawley dmin'] = 1.0
328           
329#        if 'SH Texture' not in generalData:
330#            generalData['SH Texture'] = data['SH Texture']
331        generalData['NoAtoms'] = {}
332        generalData['BondRadii'] = []
333        generalData['AngleRadii'] = []
334        generalData['vdWRadii'] = []
335        generalData['AtomMass'] = []
336        generalData['Color'] = []
337        generalData['Mydir'] = G2frame.dirname
338        cx,ct,cs,cia = [3,1,7,9]
339        generalData['AtomPtrs'] = [cx,ct,cs,cia]
340        if generalData['Type'] =='macromolecular':
341            cx,ct,cs,cia = [6,4,10,12]
342            generalData['AtomPtrs'] = [cx,ct,cs,cia]
343        for atom in atomData:
344            atom[ct] = atom[ct].lower().capitalize()              #force to standard form
345            if generalData['AtomTypes'].count(atom[ct]):
346                generalData['NoAtoms'][atom[ct]] += atom[cs-1]*float(atom[cs+1])
347            elif atom[ct] != 'UNK':
348                Info = G2elem.GetAtomInfo(atom[ct])
349                generalData['AtomTypes'].append(atom[ct])
350                generalData['Z'] = Info['Z']
351                generalData['Isotopes'][atom[ct]] = Info['Isotopes']
352                generalData['BondRadii'].append(Info['Drad'])
353                generalData['AngleRadii'].append(Info['Arad'])
354                generalData['vdWRadii'].append(Info['Vdrad'])
355                if atom[ct] in generalData['Isotope']:
356                    generalData['AtomMass'].append(Info['Isotopes'][generalData['Isotope'][atom[ct]]][0])
357                else:
358                    generalData['Isotope'][atom[ct]] = 'Nat. Abund.'
359                    generalData['AtomMass'].append(Info['Mass'])
360                generalData['NoAtoms'][atom[ct]] = atom[cs-1]*float(atom[cs+1])
361                generalData['Color'].append(Info['Color'])
362        F000X = 0.
363        F000N = 0.
364        for i,elem in enumerate(generalData['AtomTypes']):
365            F000X += generalData['NoAtoms'][elem]*generalData['Z']
366            isotope = generalData['Isotope'][elem]
367            F000N += generalData['NoAtoms'][elem]*generalData['Isotopes'][elem][isotope][1]
368        generalData['F000X'] = F000X
369        generalData['F000N'] = F000N
370       
371
372################################################################################
373##### General phase routines
374################################################################################
375
376    def UpdateGeneral():
377       
378        ''' default dictionary structure for phase data: (taken from GSASII.py)
379        'General':{
380            'Name':PhaseName
381            'Type':'nuclear'
382            'SGData':SGData
383            'Cell':[False,10.,10.,10.,90.,90.,90,1000.]
384            'AtomPtrs':[]
385            'Histogram list':['',]
386            'Pawley dmin':1.0}
387        'Atoms':[]
388        'Drawing':{}
389        '''
390       
391        phaseTypes = ['nuclear','modulated','magnetic','macromolecular']
392        SetupGeneral()
393        generalData = data['General']
394        Map = generalData['Map']
395        Flip = generalData['Flip'] 
396        PWDR = any(['PWDR' in item for item in data['Histograms'].keys()])
397       
398        def NameSizer():
399                   
400            def OnPhaseName(event):
401                oldName = generalData['Name']
402                generalData['Name'] = NameTxt.GetValue()
403                G2frame.G2plotNB.Rename(oldName,generalData['Name'])
404                G2frame.dataFrame.SetLabel('Phase Data for '+generalData['Name'])
405                G2frame.PatternTree.SetItemText(Item,generalData['Name'])
406                #Hmm, need to change phase name key in Reflection Lists for each histogram
407                           
408            def OnPhaseType(event):
409                if not generalData['AtomTypes']:             #can change only if no atoms!
410                    generalData['Type'] = TypeTxt.GetValue()
411                    dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
412                    UpdateGeneral()         #must use this way!
413                else:
414                    TypeTxt.SetValue(generalData['Type'])               
415               
416            def OnSpaceGroup(event):
417                SpcGp = SGTxt.GetValue()
418                SGErr,SGData = G2spc.SpcGroup(SpcGp)
419                if SGErr:
420                    text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous']
421                    SGTxt.SetValue(generalData['SGData']['SpGrp'])
422                    msg = 'Space Group Error'
423                    Style = wx.ICON_EXCLAMATION
424                else:
425                    text = G2spc.SGPrint(SGData)
426                    generalData['SGData'] = SGData
427                    msg = 'Space Group Information'
428                    Style = wx.ICON_INFORMATION
429                Text = ''
430                for line in text:
431                    Text += line+'\n'
432                wx.MessageBox(Text,caption=msg,style=Style)
433                dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
434                UpdateGeneral()
435               
436            nameSizer = wx.BoxSizer(wx.HORIZONTAL)
437            nameSizer.Add(wx.StaticText(dataDisplay,-1,' Phase name: '),0,wx.ALIGN_CENTER_VERTICAL)
438            NameTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['Name'],style=wx.TE_PROCESS_ENTER)
439            NameTxt.Bind(wx.EVT_TEXT_ENTER,OnPhaseName)
440            NameTxt.Bind(wx.EVT_KILL_FOCUS,OnPhaseName)
441            nameSizer.Add(NameTxt,0,wx.ALIGN_CENTER_VERTICAL)
442            nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Phase type: '),0,wx.ALIGN_CENTER_VERTICAL)
443            if len(data['Atoms']):
444                choices = phaseTypes[:-1]
445            else:
446                choices = phaseTypes           
447            TypeTxt = wx.ComboBox(dataDisplay,-1,value=generalData['Type'],choices=choices,
448                style=wx.CB_READONLY|wx.CB_DROPDOWN)
449            TypeTxt.Bind(wx.EVT_COMBOBOX, OnPhaseType)
450            nameSizer.Add(TypeTxt,0,wx.ALIGN_CENTER_VERTICAL)
451            nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Space group: '),0,wx.ALIGN_CENTER_VERTICAL)
452            SGTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['SGData']['SpGrp'],style=wx.TE_PROCESS_ENTER)
453            SGTxt.Bind(wx.EVT_TEXT_ENTER,OnSpaceGroup)
454            nameSizer.Add(SGTxt,0,wx.ALIGN_CENTER_VERTICAL)
455            return nameSizer
456           
457        def CellSizer():
458           
459            cellGUIlist = [[['m3','m3m'],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
460            [['3R','3mR'],6,zip([" a = "," alpha = "," Vol = "],["%.5f","%.3f","%.3f"],[True,True,False],[0,2,0])],
461            [['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])],
462            [['mmm'],8,zip([" a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
463                [True,True,True,False],[0,1,2,0])],
464            [['2/m'+'a'],10,zip([" a = "," b = "," c = "," alpha = "," Vol = "],
465                ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
466            [['2/m'+'b'],10,zip([" a = "," b = "," c = "," beta = "," Vol = "],
467                ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
468            [['2/m'+'c'],10,zip([" a = "," b = "," c = "," gamma = "," Vol = "],
469                ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
470            [['-1'],8,zip([" a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
471                ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
472                [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
473               
474            def OnCellRef(event):
475                generalData['Cell'][0] = cellRef.GetValue()
476               
477            def OnCellChange(event):
478                SGData = generalData['SGData']
479                laue = SGData['SGLaue']
480                if laue == '2/m':
481                    laue += SGData['SGUniq']
482                cell = generalData['Cell']
483                Obj = event.GetEventObject()
484                ObjId = cellList.index(Obj.GetId())
485                try:
486                    value = max(1.0,float(Obj.GetValue()))
487                except ValueError:
488                    if ObjId < 3:               #bad cell edge - reset
489                        value = controls[6+ObjId]
490                    else:                       #bad angle
491                        value = 90.
492                if laue in ['m3','m3m']:
493                    cell[1] = cell[2] = cell[3] = value
494                    cell[4] = cell[5] = cell[6] = 90.0
495                    Obj.SetValue("%.5f"%(cell[1]))
496                elif laue in ['3R','3mR']:
497                    if ObjId == 0:
498                        cell[1] = cell[2] = cell[3] = value
499                        Obj.SetValue("%.5f"%(cell[1]))
500                    else:
501                        cell[4] = cell[5] = cell[6] = value
502                        Obj.SetValue("%.5f"%(cell[4]))
503                elif laue in ['3','3m1','31m','6/m','6/mmm','4/m','4/mmm']:                   
504                    cell[4] = cell[5] = 90.
505                    cell[6] = 120.
506                    if laue in ['4/m','4/mmm']:
507                        cell[6] = 90.
508                    if ObjId == 0:
509                        cell[1] = cell[2] = value
510                        Obj.SetValue("%.5f"%(cell[1]))
511                    else:
512                        cell[3] = value
513                        Obj.SetValue("%.5f"%(cell[3]))
514                elif laue in ['mmm']:
515                    cell[ObjId+1] = value
516                    cell[4] = cell[5] = cell[6] = 90.
517                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
518                elif laue in ['2/m'+'a']:
519                    cell[5] = cell[6] = 90.
520                    if ObjId != 3:
521                        cell[ObjId+1] = value
522                        Obj.SetValue("%.5f"%(cell[ObjId+1]))
523                    else:
524                        cell[4] = value
525                        Obj.SetValue("%.3f"%(cell[4]))
526                elif laue in ['2/m'+'b']:
527                    cell[4] = cell[6] = 90.
528                    if ObjId != 3:
529                        cell[ObjId+1] = value
530                        Obj.SetValue("%.5f"%(cell[ObjId+1]))
531                    else:
532                        cell[5] = value
533                        Obj.SetValue("%.3f"%(cell[5]))
534                elif laue in ['2/m'+'c']:
535                    cell[5] = cell[6] = 90.
536                    if ObjId != 3:
537                        cell[ObjId+1] = value
538                        Obj.SetValue("%.5f"%(cell[ObjId+1]))
539                    else:
540                        cell[6] = value
541                        Obj.SetValue("%.3f"%(cell[6]))
542                else:
543                    cell[ObjId+1] = value
544                    if ObjId < 3:
545                        Obj.SetValue("%.5f"%(cell[1+ObjId]))
546                    else:
547                        Obj.SetValue("%.3f"%(cell[1+ObjId]))                       
548                cell[7] = G2lat.calc_V(G2lat.cell2A(cell[1:7]))
549                volVal.SetValue("%.3f"%(cell[7]))
550                generalData['Cell'] = cell
551                dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
552                UpdateGeneral()
553           
554            cell = generalData['Cell']
555            laue = generalData['SGData']['SGLaue']
556            if laue == '2/m':
557                laue += generalData['SGData']['SGUniq']
558            for cellGUI in cellGUIlist:
559                if laue in cellGUI[0]:
560                    useGUI = cellGUI
561            cellSizer = wx.FlexGridSizer(2,useGUI[1]+1,5,5)
562            if PWDR:
563                cellRef = wx.CheckBox(dataDisplay,-1,label='Refine unit cell:')
564                cellSizer.Add(cellRef,0,wx.ALIGN_CENTER_VERTICAL)
565                cellRef.Bind(wx.EVT_CHECKBOX, OnCellRef)
566                cellRef.SetValue(cell[0])
567            cellList = []
568            for txt,fmt,ifEdit,Id in useGUI[2]:
569                cellSizer.Add(wx.StaticText(dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL)
570                if ifEdit:          #a,b,c,etc.
571                    cellVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[Id+1])),
572                        style=wx.TE_PROCESS_ENTER)
573                    cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
574                    cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
575                    cellSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL)
576                    cellList.append(cellVal.GetId())
577                else:               #volume
578                    volVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[7])),style=wx.TE_READONLY)
579                    volVal.SetBackgroundColour(VERY_LIGHT_GREY)
580                    cellSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL)
581            return cellSizer
582           
583        def ElemSizer():
584           
585            def OnIsotope(event):
586                Obj = event.GetEventObject()
587                item = Indx[Obj.GetId()]
588                isotope = Obj.GetValue()
589                generalData['Isotope'][item] = isotope
590                indx = generalData['AtomTypes'].index(item)
591                data['General']['AtomMass'][indx] = generalData['Isotopes'][item][isotope][0]
592                dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
593                UpdateGeneral()
594               
595            elemSizer = wx.FlexGridSizer(8,len(generalData['AtomTypes'])+1,1,1)
596            elemSizer.Add(wx.StaticText(dataDisplay,label=' Elements'),0,wx.ALIGN_CENTER_VERTICAL)
597            for elem in generalData['AtomTypes']:
598                typTxt = wx.TextCtrl(dataDisplay,value=elem,style=wx.TE_READONLY)
599                typTxt.SetBackgroundColour(VERY_LIGHT_GREY)
600                elemSizer.Add(typTxt,0,wx.ALIGN_CENTER_VERTICAL)
601            elemSizer.Add(wx.StaticText(dataDisplay,label=' Isotope'),0,wx.ALIGN_CENTER_VERTICAL)
602            for elem in generalData['AtomTypes']:
603                choices = generalData['Isotopes'][elem].keys()
604                isoSel = wx.ComboBox(dataDisplay,-1,value=generalData['Isotope'][elem],choices=choices,
605                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
606                isoSel.Bind(wx.EVT_COMBOBOX,OnIsotope)
607                Indx[isoSel.GetId()] = elem
608                elemSizer.Add(isoSel,1,wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
609            elemSizer.Add(wx.StaticText(dataDisplay,label=' No. per cell'),0,wx.ALIGN_CENTER_VERTICAL)
610            for elem in generalData['AtomTypes']:
611                numbTxt = wx.TextCtrl(dataDisplay,value='%.1f'%(generalData['NoAtoms'][elem]),
612                    style=wx.TE_READONLY)
613                numbTxt.SetBackgroundColour(VERY_LIGHT_GREY)
614                elemSizer.Add(numbTxt,0,wx.ALIGN_CENTER_VERTICAL)
615            elemSizer.Add(wx.StaticText(dataDisplay,label=' Atom weight'),0,wx.ALIGN_CENTER_VERTICAL)
616            for wt in generalData['AtomMass']:
617                wtTxt = wx.TextCtrl(dataDisplay,value='%.3f'%(wt),style=wx.TE_READONLY)
618                wtTxt.SetBackgroundColour(VERY_LIGHT_GREY)
619                elemSizer.Add(wtTxt,0,wx.ALIGN_CENTER_VERTICAL)
620            elemSizer.Add(wx.StaticText(dataDisplay,label=' Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
621            for rad in generalData['BondRadii']:
622                bondRadii = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
623                bondRadii.SetBackgroundColour(VERY_LIGHT_GREY)
624                elemSizer.Add(bondRadii,0,wx.ALIGN_CENTER_VERTICAL)
625            elemSizer.Add(wx.StaticText(dataDisplay,label=' Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
626            for rad in generalData['AngleRadii']:
627                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
628                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
629                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
630            elemSizer.Add(wx.StaticText(dataDisplay,label=' van der Waals radii'),0,wx.ALIGN_CENTER_VERTICAL)
631            for rad in generalData['vdWRadii']:
632                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
633                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
634                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
635            elemSizer.Add(wx.StaticText(dataDisplay,label=' Default color'),0,wx.ALIGN_CENTER_VERTICAL)
636            for R,G,B in generalData['Color']:
637                colorTxt = wx.TextCtrl(dataDisplay,value='',style=wx.TE_READONLY)
638                colorTxt.SetBackgroundColour(wx.Colour(R,G,B))
639                elemSizer.Add(colorTxt,0,wx.ALIGN_CENTER_VERTICAL)
640            return elemSizer
641           
642        def DenSizer():
643           
644            mass = 0.
645            for i,elem in enumerate(generalData['AtomTypes']):
646                mass += generalData['NoAtoms'][elem]*generalData['AtomMass'][i]
647            denSizer = wx.BoxSizer(wx.HORIZONTAL)
648            denSizer.Add(wx.StaticText(dataDisplay,-1,' Density: '),0,wx.ALIGN_CENTER_VERTICAL)
649            Volume = generalData['Cell'][7]
650            density = mass/(0.6022137*Volume)
651            denTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(density),style=wx.TE_READONLY)
652            denTxt.SetBackgroundColour(VERY_LIGHT_GREY)
653            denSizer.Add(denTxt,0,wx.ALIGN_CENTER_VERTICAL)       
654            if generalData['Type'] == 'macromolecular' and mass > 0.0:
655                denSizer.Add(wx.StaticText(dataDisplay,-1,' Matthews coeff.: '),
656                    0,wx.ALIGN_CENTER_VERTICAL)
657                mattTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(Volume/mass),style=wx.TE_READONLY)
658                mattTxt.SetBackgroundColour(VERY_LIGHT_GREY)
659                denSizer.Add(mattTxt,0,wx.ALIGN_CENTER_VERTICAL)
660            return denSizer
661           
662        def PawleySizer():
663           
664            def OnPawleyRef(event):
665                generalData['doPawley'] = pawlRef.GetValue()
666           
667            def OnPawleyVal(event):
668                try:
669                    dmin = float(pawlVal.GetValue())
670                    if 0.25 <= dmin <= 20.:
671                        generalData['Pawley dmin'] = dmin
672                except ValueError:
673                    pass
674                pawlVal.SetValue("%.3f"%(generalData['Pawley dmin']))          #reset in case of error               
675           
676            pawleySizer = wx.BoxSizer(wx.HORIZONTAL)
677            pawleySizer.Add(wx.StaticText(dataDisplay,label=' Pawley controls: '),0,wx.ALIGN_CENTER_VERTICAL)
678            pawlRef = wx.CheckBox(dataDisplay,-1,label=' Do Pawley refinement?')
679            pawlRef.SetValue(generalData['doPawley'])
680            pawlRef.Bind(wx.EVT_CHECKBOX,OnPawleyRef)
681            pawleySizer.Add(pawlRef,0,wx.ALIGN_CENTER_VERTICAL)
682            pawleySizer.Add(wx.StaticText(dataDisplay,label=' Pawley dmin: '),0,wx.ALIGN_CENTER_VERTICAL)
683            pawlVal = wx.TextCtrl(dataDisplay,value='%.3f'%(generalData['Pawley dmin']),style=wx.TE_PROCESS_ENTER)
684            pawlVal.Bind(wx.EVT_TEXT_ENTER,OnPawleyVal)       
685            pawlVal.Bind(wx.EVT_KILL_FOCUS,OnPawleyVal)
686            pawleySizer.Add(pawlVal,0,wx.ALIGN_CENTER_VERTICAL)
687            return pawleySizer
688           
689        def MapSizer():
690           
691            def OnMapType(event):
692                Map['MapType'] = mapType.GetValue()
693               
694            def OnRefList(event):
695                Map['RefList'] = refList.GetValue()
696               
697            def OnResVal(event):
698                try:
699                    res = float(mapRes.GetValue())
700                    if 0.25 <= res <= 20.:
701                        Map['Resolution'] = res
702                except ValueError:
703                    pass
704                mapRes.SetValue("%.2f"%(Map['Resolution']))          #reset in case of error
705           
706            def OnCutOff(event):
707                try:
708                    res = float(cutOff.GetValue())
709                    if 1.0 <= res <= 100.:
710                        Map['cutOff'] = res
711                except ValueError:
712                    pass
713                cutOff.SetValue("%.1f"%(Map['cutOff']))          #reset in case of error
714           
715            #patch
716            if 'cutOff' not in Map:
717                Map['cutOff'] = 100.0
718            mapTypes = ['Fobs','Fcalc','delt-F','2*Fo-Fc','Patterson']
719            refList = data['Histograms'].keys()
720            if not generalData['AtomTypes']:
721                 mapTypes = ['Patterson',]
722                 Map['MapType'] = 'Patterson'
723            mapSizer = wx.BoxSizer(wx.VERTICAL)
724            lineSizer = wx.BoxSizer(wx.HORIZONTAL)
725            lineSizer.Add(wx.StaticText(dataDisplay,label=' Fourier map controls: Map type: '),0,wx.ALIGN_CENTER_VERTICAL)
726            mapType = wx.ComboBox(dataDisplay,-1,value=Map['MapType'],choices=mapTypes,
727                style=wx.CB_READONLY|wx.CB_DROPDOWN)
728            mapType.Bind(wx.EVT_COMBOBOX,OnMapType)
729            lineSizer.Add(mapType,0,wx.ALIGN_CENTER_VERTICAL)
730            lineSizer.Add(wx.StaticText(dataDisplay,label=' Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL)
731            refList = wx.ComboBox(dataDisplay,-1,value=Map['RefList'],choices=refList,
732                style=wx.CB_READONLY|wx.CB_DROPDOWN)
733            refList.Bind(wx.EVT_COMBOBOX,OnRefList)
734            lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL)
735            mapSizer.Add(lineSizer,0,wx.ALIGN_CENTER_VERTICAL)
736            line2Sizer = wx.BoxSizer(wx.HORIZONTAL)
737            line2Sizer.Add(wx.StaticText(dataDisplay,label=' Resolution: '),0,wx.ALIGN_CENTER_VERTICAL)
738            mapRes =  wx.TextCtrl(dataDisplay,value='%.2f'%(Map['Resolution']),style=wx.TE_PROCESS_ENTER)
739            mapRes.Bind(wx.EVT_TEXT_ENTER,OnResVal)       
740            mapRes.Bind(wx.EVT_KILL_FOCUS,OnResVal)
741            line2Sizer.Add(mapRes,0,wx.ALIGN_CENTER_VERTICAL)
742            line2Sizer.Add(wx.StaticText(dataDisplay,label=' Peak cutoff %: '),0,wx.ALIGN_CENTER_VERTICAL)
743            cutOff =  wx.TextCtrl(dataDisplay,value='%.1f'%(Map['cutOff']),style=wx.TE_PROCESS_ENTER)
744            cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)       
745            cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
746            line2Sizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL)
747            mapSizer.Add(line2Sizer,0,wx.ALIGN_CENTER_VERTICAL)
748            return mapSizer
749               
750        def FlipSizer():
751           
752            def OnRefList(event):
753                Flip['RefList'] = refList.GetValue()
754               
755            def OnNormElem(event):
756                PE = G2elemGUI.PickElement(G2frame,ifNone=True)
757                if PE.ShowModal() == wx.ID_OK:
758                    Flip['Norm element'] = PE.Elem.strip()
759                    normElem.SetLabel(Flip['Norm element'])
760                PE.Destroy()               
761               
762            def OnResVal(event):
763                try:
764                    res = float(flipRes.GetValue())
765                    if 0.25 <= res <= 20.:
766                        Flip['Resolution'] = res
767                except ValueError:
768                    pass
769                flipRes.SetValue("%.2f"%(Flip['Resolution']))          #reset in case of error
770           
771            def OnkFactor(event):
772                try:
773                    res = float(kFactor.GetValue())
774                    if 0.1 <= res <= 1.2:
775                        Flip['k-factor'] = res
776                except ValueError:
777                    pass
778                kFactor.SetValue("%.3f"%(Flip['k-factor']))          #reset in case of error
779           
780            refList = data['Histograms'].keys()
781            flipSizer = wx.BoxSizer(wx.VERTICAL)
782            lineSizer = wx.BoxSizer(wx.HORIZONTAL)
783            lineSizer.Add(wx.StaticText(dataDisplay,label=' Charge flip controls: Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL)
784            refList = wx.ComboBox(dataDisplay,-1,value=Flip['RefList'],choices=refList,
785                style=wx.CB_READONLY|wx.CB_DROPDOWN)
786            refList.Bind(wx.EVT_COMBOBOX,OnRefList)
787            lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL)
788            flipSizer.Add(lineSizer,0,wx.ALIGN_CENTER_VERTICAL)
789            line2Sizer = wx.BoxSizer(wx.HORIZONTAL)
790            line2Sizer.Add(wx.StaticText(dataDisplay,label=' Normalizing element: '),0,wx.ALIGN_CENTER_VERTICAL)
791            normElem = wx.Button(dataDisplay,label=Flip['Norm element'],style=wx.TE_READONLY)
792            normElem.Bind(wx.EVT_BUTTON,OnNormElem)
793            line2Sizer.Add(normElem,0,wx.ALIGN_CENTER_VERTICAL)
794            line2Sizer.Add(wx.StaticText(dataDisplay,label=' Resolution: '),0,wx.ALIGN_CENTER_VERTICAL)
795            flipRes =  wx.TextCtrl(dataDisplay,value='%.2f'%(Flip['Resolution']),style=wx.TE_PROCESS_ENTER)
796            flipRes.Bind(wx.EVT_TEXT_ENTER,OnResVal)       
797            flipRes.Bind(wx.EVT_KILL_FOCUS,OnResVal)
798            line2Sizer.Add(flipRes,0,wx.ALIGN_CENTER_VERTICAL)
799            line2Sizer.Add(wx.StaticText(dataDisplay,label=' k-Factor (0.1-1.2): '),0,wx.ALIGN_CENTER_VERTICAL)
800            kFactor =  wx.TextCtrl(dataDisplay,value='%.3f'%(Flip['k-factor']),style=wx.TE_PROCESS_ENTER)
801            kFactor.Bind(wx.EVT_TEXT_ENTER,OnkFactor)       
802            kFactor.Bind(wx.EVT_KILL_FOCUS,OnkFactor)
803            line2Sizer.Add(kFactor,0,wx.ALIGN_CENTER_VERTICAL)
804            flipSizer.Add(line2Sizer,0,wx.ALIGN_CENTER_VERTICAL)
805            return flipSizer
806               
807        General.DestroyChildren()
808        dataDisplay = wx.Panel(General)
809        mainSizer = wx.BoxSizer(wx.VERTICAL)
810        mainSizer.Add((5,5),0)
811        mainSizer.Add(NameSizer(),0)
812        mainSizer.Add((5,5),0)       
813        mainSizer.Add(CellSizer(),0)
814        mainSizer.Add((5,5),0)
815       
816        Indx = {}
817        if len(generalData['AtomTypes']):
818            mainSizer.Add(DenSizer())
819            mainSizer.Add((5,5),0)           
820            mainSizer.Add(ElemSizer())
821           
822        mainSizer.Add((5,5),0)
823        mainSizer.Add(PawleySizer())
824
825        mainSizer.Add((5,5),0)
826        mainSizer.Add(MapSizer())
827
828        mainSizer.Add((5,5),0)
829        mainSizer.Add(FlipSizer())
830
831        dataDisplay.SetSizer(mainSizer)
832        Size = mainSizer.Fit(G2frame.dataFrame)
833        Size[1] += 26                           #compensate for status bar
834        dataDisplay.SetSize(Size)
835        G2frame.dataFrame.setSizePosLeft(Size)
836
837################################################################################
838#####  Atom routines
839################################################################################
840
841    def FillAtomsGrid():
842
843        G2frame.dataFrame.setSizePosLeft([700,300])
844        generalData = data['General']
845        atomData = data['Atoms']
846        Items = [G2gd.wxID_ATOMSEDITINSERT, G2gd.wxID_ATOMSEDITDELETE, G2gd.wxID_ATOMSREFINE, 
847            G2gd.wxID_ATOMSMODIFY, G2gd.wxID_ATOMSTRANSFORM, G2gd.wxID_ATONTESTINSERT]
848        if atomData:
849            for item in Items:   
850                G2frame.dataFrame.AtomsMenu.Enable(item,True)
851        else:
852            for item in Items:
853                G2frame.dataFrame.AtomsMenu.Enable(item,False)           
854           
855        AAchoice = ": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK"
856        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",]+ \
857            3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_FLOAT+':10,4', #x,y,z,frac
858            wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+":I,A",]
859        Types += 7*[wg.GRID_VALUE_FLOAT+':10,5',]
860        colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23']
861        if generalData['Type'] == 'magnetic':
862            colLabels += ['Mx','My','Mz']
863            Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU,"
864            Types += 3*[wg.GRID_VALUE_FLOAT+':10,4',]
865        elif generalData['Type'] == 'macromolecular':
866            colLabels = ['res no','residue','chain'] + colLabels
867            Types = [wg.GRID_VALUE_STRING,
868                wg.GRID_VALUE_CHOICE+AAchoice,
869                wg.GRID_VALUE_STRING] + Types
870        elif generalData['Type'] == 'modulated':
871            Types += []
872            colLabels += []
873
874        def RefreshAtomGrid(event):
875
876            r,c =  event.GetRow(),event.GetCol()
877            if r < 0 and c < 0:
878                for row in range(Atoms.GetNumberRows()):
879                    Atoms.SelectRow(row,True)                   
880            if r < 0:                          #double click on col label! Change all atoms!
881                sel = -1
882                noSkip = True
883                if Atoms.GetColLabelValue(c) == 'refine':
884                    Type = generalData['Type']
885                    if Type in ['nuclear','macromolecular']:
886                        choice = ['F - site fraction','X - coordinates','U - thermal parameters']
887                    elif Type in ['magnetic',]:
888                        choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
889                    dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice)
890                    if dlg.ShowModal() == wx.ID_OK:
891                        sel = dlg.GetSelections()
892                        parms = ''
893                        for x in sel:
894                            parms += choice[x][0]
895                    dlg.Destroy()
896                elif Atoms.GetColLabelValue(c) == 'I/A':
897                    choice = ['Isotropic','Anisotropic']
898                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal Motion',choice)
899                    if dlg.ShowModal() == wx.ID_OK:
900                        sel = dlg.GetSelection()
901                        parms = choice[sel][0]
902                    dlg.Destroy()
903                elif Atoms.GetColLabelValue(c) == 'Type':
904                    choice = generalData['AtomTypes']
905                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom types',choice)
906                    if dlg.ShowModal() == wx.ID_OK:
907                        sel = dlg.GetSelection()
908                        parms = choice[sel]
909                        noSkip = False
910                        Atoms.ClearSelection()
911                        for row in range(Atoms.GetNumberRows()):
912                            if parms == atomData[row][c]:
913                                Atoms.SelectRow(row,True)
914                    SetupGeneral()
915                elif Atoms.GetColLabelValue(c) == 'residue':
916                    choice = []
917                    for r in range(Atoms.GetNumberRows()):
918                        if str(atomData[r][c]) not in choice:
919                            choice.append(str(atomData[r][c]))
920                    choice.sort()
921                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue',choice)
922                    if dlg.ShowModal() == wx.ID_OK:
923                        sel = dlg.GetSelection()
924                        parms = choice[sel]
925                        noSkip = False
926                        Atoms.ClearSelection()
927                        for row in range(Atoms.GetNumberRows()):
928                            if parms == atomData[row][c]:
929                                Atoms.SelectRow(row,True)
930                elif Atoms.GetColLabelValue(c) == 'res no':
931                    choice = []
932                    for r in range(Atoms.GetNumberRows()):
933                        if str(atomData[r][c]) not in choice:
934                            choice.append(str(atomData[r][c]))
935                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue no.',choice)
936                    if dlg.ShowModal() == wx.ID_OK:
937                        sel = dlg.GetSelection()
938                        parms = choice[sel]
939                        noSkip = False
940                        Atoms.ClearSelection()
941                        for row in range(Atoms.GetNumberRows()):
942                            if int(parms) == atomData[row][c]:
943                                Atoms.SelectRow(row,True)
944                elif Atoms.GetColLabelValue(c) == 'chain':
945                    choice = []
946                    for r in range(Atoms.GetNumberRows()):
947                        if atomData[r][c] not in choice:
948                            choice.append(atomData[r][c])
949                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Chain',choice)
950                    if dlg.ShowModal() == wx.ID_OK:
951                        sel = dlg.GetSelection()
952                        parms = choice[sel]
953                        noSkip = False
954                        Atoms.ClearSelection()
955                        for row in range(Atoms.GetNumberRows()):
956                            if parms == atomData[row][c]:
957                                Atoms.SelectRow(row,True)
958                    dlg.Destroy()
959                elif Atoms.GetColLabelValue(c) == 'Uiso':       #this needs to ask for value
960                    pass                                        #& then change all 'I' atoms
961                if sel >= 0 and noSkip:
962                    ui = colLabels.index('U11')
963                    us = colLabels.index('Uiso')
964                    ss = colLabels.index('site sym')
965                    for r in range(Atoms.GetNumberRows()):
966                        ID = atomData[r][-1]
967                        if parms != atomData[r][c] and Atoms.GetColLabelValue(c) == 'I/A':
968                            if parms == 'A':                #'I' --> 'A'
969                                Uiso = float(Atoms.GetCellValue(r,us))
970                                sytsym = atomData[r][ss]
971                                CSI = G2spc.GetCSuinel(sytsym)
972                                atomData[r][ui:ui+6] = Uiso*np.array(CSI[3])
973                                atomData[r][us] = 0.0
974                                Atoms.SetCellStyle(r,us,VERY_LIGHT_GREY,True)
975                                for i in range(6):
976                                    ci = ui+i
977                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
978                                    if CSI[2][i]:
979                                        Atoms.SetCellStyle(r,ci,WHITE,False)
980                            else:                           #'A' --> 'I'
981                                Uij = atomData[r][ui:ui+6]
982                                Uiso = (Uij[0]+Uij[1]+Uij[2])/3.0
983                                atomData[r][us] = Uiso
984                                Atoms.SetCellStyle(r,us,WHITE,False)
985                                for i in range(6):
986                                    ci = ui+i
987                                    atomData[r][ci] = 0.0
988                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
989                        atomData[r][c] = parms
990                        if 'Atoms' in data['Drawing']:
991                            DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
992                    FillAtomsGrid()
993                   
994        def ChangeAtomCell(event):
995           
996            def chkUij(Uij,CSI): #needs to do something!!!
997                return Uij
998
999            r,c =  event.GetRow(),event.GetCol()
1000            if r >= 0 and c >= 0:
1001                ID = atomData[r][-1]
1002                if Atoms.GetColLabelValue(c) in ['x','y','z']:
1003                    ci = colLabels.index('x')
1004                    XYZ = atomData[r][ci:ci+3]
1005                    if None in XYZ:
1006                        XYZ = [0,0,0]
1007                    SScol = colLabels.index('site sym')
1008                    Mulcol = colLabels.index('mult')
1009                    E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
1010                    Sytsym,Mult = G2spc.SytSym(XYZ,SGData)
1011                    atomData[r][SScol] = Sytsym
1012                    atomData[r][Mulcol] = Mult
1013                    if atomData[r][colLabels.index('I/A')] == 'A':
1014                        ui = colLabels.index('U11')
1015                        CSI = G2spc.GetCSuinel(Sytsym)
1016                        atomData[r][ui:ui+6] = chkUij(atomData[r][ui:ui+6],Sytsym)
1017                        for i in range(6):
1018                            ci = i+ui
1019                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
1020                            if CSI[2][i]:
1021                                Atoms.SetCellStyle(r,ci,WHITE,False)
1022                    SetupGeneral()
1023                elif Atoms.GetColLabelValue(c) == 'I/A':            #note use of text color to make it vanish!
1024                    if atomData[r][c] == 'I':
1025                        Uij = atomData[r][c+2:c+8]
1026                        atomData[r][c+1] = (Uij[0]+Uij[1]+Uij[2])/3.0
1027                        Atoms.SetCellStyle(r,c+1,WHITE,False)
1028                        Atoms.SetCellTextColour(r,c+1,BLACK)
1029                        for i in range(6):
1030                            ci = i+colLabels.index('U11')
1031                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
1032                            Atoms.SetCellTextColour(r,ci,VERY_LIGHT_GREY)
1033                            atomData[r][ci] = 0.0
1034                    else:
1035                        value = atomData[r][c+1]
1036                        CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
1037                        atomData[r][c+1] =  0.0
1038                        Atoms.SetCellStyle(r,c+1,VERY_LIGHT_GREY,True)
1039                        Atoms.SetCellTextColour(r,c+1,VERY_LIGHT_GREY)
1040                        for i in range(6):
1041                            ci = i+colLabels.index('U11')
1042                            atomData[r][ci] = value*CSI[3][i]
1043                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
1044                            Atoms.SetCellTextColour(r,ci,BLACK)
1045                            if CSI[2][i]:
1046                                Atoms.SetCellStyle(r,ci,WHITE,False)
1047                elif Atoms.GetColLabelValue(c) in ['U11','U22','U33','U12','U13','U23']:
1048                    value = atomData[r][c]
1049                    CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
1050                    iUij = CSI[0][c-colLabels.index('U11')]
1051                    for i in range(6):
1052                        if iUij == CSI[0][i]:
1053                            atomData[r][i+colLabels.index('U11')] = value*CSI[1][i]
1054                if 'Atoms' in data['Drawing']:
1055                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
1056                    FindBondsDraw()
1057                   
1058        def AtomTypeSelect(event):
1059            r,c =  event.GetRow(),event.GetCol()
1060            if Atoms.GetColLabelValue(c) == 'Type':
1061                PE = G2elemGUI.PickElement(G2frame)
1062                if PE.ShowModal() == wx.ID_OK:
1063                    if PE.Elem not in 'None':                       
1064                        atomData[r][c] = PE.Elem.strip()
1065                        name = atomData[r][c]
1066                        if len(name) in [2,4]:
1067                            atomData[r][c-1] = name[:2]+'(%d)'%(r+1)
1068                        else:
1069                            atomData[r][c-1] = name[:1]+'(%d)'%(r+1)
1070                PE.Destroy()
1071                SetupGeneral()
1072                FillAtomsGrid()
1073                value = Atoms.GetCellValue(r,c)
1074                atomData[r][c] = value
1075                ID = atomData[r][-1]
1076                if 'Atoms' in data['Drawing']:
1077                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
1078                SetupGeneral()
1079            else:
1080                event.Skip()
1081
1082        def RowSelect(event):
1083            r,c =  event.GetRow(),event.GetCol()
1084            if r < 0 and c < 0:
1085                if Atoms.IsSelection():
1086                    Atoms.ClearSelection()
1087            elif c < 0:                   #only row clicks
1088                if event.ControlDown():                   
1089                    if r in Atoms.GetSelectedRows():
1090                        Atoms.DeselectRow(r)
1091                    else:
1092                        Atoms.SelectRow(r,True)
1093                elif event.ShiftDown():
1094                    for row in range(r+1):
1095                        Atoms.SelectRow(row,True)
1096                else:
1097                    Atoms.ClearSelection()
1098                    Atoms.SelectRow(r,True)               
1099               
1100        def ChangeSelection(event):
1101            r,c =  event.GetRow(),event.GetCol()
1102            if r < 0 and c < 0:
1103                Atoms.ClearSelection()
1104            if c < 0:
1105                if r in Atoms.GetSelectedRows():
1106                    Atoms.DeselectRow(r)
1107                else:
1108                    Atoms.SelectRow(r,True)
1109            if r < 0:
1110                if c in Atoms.GetSelectedCols():
1111                    Atoms.DeselectCol(c)
1112                else:
1113                    Atoms.SelectCol(c,True)
1114       
1115        SGData = data['General']['SGData']
1116        if SGData['SGPolax']:
1117            G2frame.dataFrame.SetStatusText('Warning: The location of the origin is arbitrary in '+SGData['SGPolax'])
1118        table = []
1119        rowLabels = []
1120        for i,atom in enumerate(atomData):
1121            table.append(atom)
1122            rowLabels.append(str(i))
1123        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1124        Atoms.SetTable(atomTable, True)
1125        Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeAtomCell)
1126        Atoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, AtomTypeSelect)
1127        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1128        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
1129        Atoms.Bind(wg.EVT_GRID_LABEL_RIGHT_CLICK, ChangeSelection)
1130        Atoms.SetMargins(0,0)
1131        Atoms.AutoSizeColumns(False)
1132        colType = colLabels.index('Type')
1133        colSS = colLabels.index('site sym')
1134        colIA = colLabels.index('I/A')
1135        colU11 = colLabels.index('U11')
1136        colUiso = colLabels.index('Uiso')
1137        for i in range(colU11-1,colU11+6):
1138            Atoms.SetColSize(i,50)           
1139        for row in range(Atoms.GetNumberRows()):
1140            Atoms.SetReadOnly(row,colType,True)
1141            Atoms.SetReadOnly(row,colSS,True)                         #site sym
1142            Atoms.SetReadOnly(row,colSS+1,True)                       #Mult
1143            if Atoms.GetCellValue(row,colIA) == 'A':
1144                CSI = G2spc.GetCSuinel(atomData[row][colLabels.index('site sym')])
1145                Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True)
1146                Atoms.SetCellTextColour(row,colUiso,VERY_LIGHT_GREY)
1147                for i in range(6):
1148                    ci = colU11+i
1149                    Atoms.SetCellTextColour(row,ci,BLACK)
1150                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
1151                    if CSI[2][i]:
1152                        Atoms.SetCellStyle(row,ci,WHITE,False)
1153            else:
1154                Atoms.SetCellStyle(row,colUiso,WHITE,False)
1155                Atoms.SetCellTextColour(row,colUiso,BLACK)
1156                for i in range(6):
1157                    ci = colU11+i
1158                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
1159                    Atoms.SetCellTextColour(row,ci,VERY_LIGHT_GREY)
1160
1161    def OnAtomAdd(event):
1162        AtomAdd(0,0,0)
1163        FillAtomsGrid()
1164        event.StopPropagation()
1165       
1166    def OnAtomTestAdd(event):
1167        try:
1168            drawData = data['Drawing']
1169            x,y,z = drawData['testPos'][0]
1170            AtomAdd(x,y,z)
1171        except:
1172            AtomAdd(0,0,0)
1173        FillAtomsGrid()
1174        event.StopPropagation()
1175               
1176    def AtomAdd(x,y,z,El='H'):
1177        atomData = data['Atoms']
1178        generalData = data['General']
1179        Ncol = Atoms.GetNumberCols()
1180        atId = ran.randint(0,sys.maxint)
1181        E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
1182        Sytsym,Mult = G2spc.SytSym([x,y,z],SGData)
1183        if generalData['Type'] == 'macromolecular':
1184            atomData.append([0,'UNK','','UNK',El,'',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
1185        elif generalData['Type'] == 'nuclear':
1186            atomData.append(['UNK',El,'',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
1187        elif generalData['Type'] == 'magnetic':
1188            atomData.append(['UNK',El,'',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId])
1189        SetupGeneral()
1190        if 'Atoms' in data['Drawing']:           
1191            DrawAtomAdd(data['Drawing'],atomData[-1])
1192            G2plt.PlotStructure(G2frame,data)
1193
1194    def OnAtomInsert(event):
1195        AtomInsert(0,0,0)
1196        FillAtomsGrid()
1197        event.StopPropagation()
1198       
1199    def OnAtomTestInsert(event):
1200        if 'Drawing' in data:
1201            drawData = data['Drawing']
1202            x,y,z = drawData['testPos'][0]
1203            AtomAdd(x,y,z)
1204            FillAtomsGrid()
1205        event.StopPropagation()
1206           
1207    def AtomInsert(x,y,z):
1208        indx = Atoms.GetSelectedRows()
1209        if indx:
1210            indx = indx[0]
1211            atomData = data['Atoms']
1212            generalData = data['General']
1213            Ncol = Atoms.GetNumberCols()
1214            E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
1215            Sytsym,Mult = G2spc.SytSym([0,0,0],SGData)
1216            atId = ran.randint(0,sys.maxint)
1217            if generalData['Type'] == 'macromolecular':
1218                atomData.insert(indx,[0,'UNK','','UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
1219            elif generalData['Type'] == 'nuclear':
1220                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
1221            elif generalData['Type'] == 'magnetic':
1222                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])
1223            SetupGeneral()
1224
1225    def AtomDelete(event):
1226        indx = Atoms.GetSelectedRows()
1227        IDs = []
1228        if indx:
1229            atomData = data['Atoms']
1230            indx.reverse()
1231            for ind in indx:
1232                atom = atomData[ind]
1233                IDs.append(atom[-1])
1234                del atomData[ind]
1235            if 'Atoms' in data['Drawing']:
1236                DrawAtomsDeleteByIDs(IDs)
1237                FillAtomsGrid()
1238                G2plt.PlotStructure(G2frame,data)
1239            SetupGeneral()
1240        event.StopPropagation()
1241
1242    def AtomRefine(event):
1243        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1244        c = colLabels.index('refine')
1245        indx = Atoms.GetSelectedRows()
1246        if indx:
1247            atomData = data['Atoms']
1248            generalData = data['General']
1249            Type = generalData['Type']
1250            if Type in ['nuclear','macromolecular']:
1251                choice = ['F - site fraction','X - coordinates','U - thermal parameters']
1252            elif Type == 'magnetic':
1253                choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
1254            dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice)
1255            if dlg.ShowModal() == wx.ID_OK:
1256                sel = dlg.GetSelections()
1257                parms = ''
1258                for x in sel:
1259                    parms += choice[x][0]
1260                for r in indx:
1261                    atomData[r][c] = parms
1262                Atoms.ForceRefresh()
1263            dlg.Destroy()
1264
1265    def AtomModify(event):                  #intent to implement global modifications (+,-,*,/, etc.)?
1266        indx = Atoms.GetSelectedRows()
1267        if indx:
1268            atomData = data['Atoms']
1269            generalData = data['General']
1270            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1271            choices = ['Type','x','y','z','frac','I/A','Uiso']
1272            dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom parameter',choices)
1273            if dlg.ShowModal() == wx.ID_OK:
1274                sel = dlg.GetSelection()
1275                parm = choices[sel]
1276                cid = colLabels.index(parm)
1277            dlg.Destroy()
1278            if parm in ['Type']:
1279                dlg = G2elemGUI.PickElement(G2frame)
1280                if dlg.ShowModal() == wx.ID_OK:
1281                    if dlg.Elem not in ['None']:
1282                        El = dlg.Elem.strip()
1283                        for r in indx:                       
1284                            atomData[r][cid] = El
1285                            if len(El) in [2,4]:
1286                                atomData[r][cid-1] = El[:2]+'(%d)'%(r+1)
1287                            else:
1288                                atomData[r][cid-1] = El[:1]+'(%d)'%(r+1)
1289                        SetupGeneral()
1290                        if 'Atoms' in data['Drawing']:
1291                            for r in indx:
1292                                ID = atomData[r][-1]
1293                                DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
1294                    FillAtomsGrid()
1295                dlg.Destroy()
1296            elif parm in ['I/A']:
1297                choices = ['Isotropic','Anisotropic']
1298                dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal parameter model',choices)
1299                if dlg.ShowModal() == wx.ID_OK:
1300                    sel = dlg.GetSelection()
1301                    parm = choices[sel][0]
1302                    for r in indx:                       
1303                        atomData[r][cid] = parm
1304                    FillAtomsGrid()
1305            elif parm in ['frac','Uiso']:
1306                limits = [0.,1.]
1307                val = 1.0
1308                if  parm in ['Uiso']:
1309                    limits = [0.,0.25]
1310                    val = 0.01
1311                dlg = SingleFloatDialog(G2frame,'New value','Enter new value for '+parm,val,limits)
1312                if dlg.ShowModal() == wx.ID_OK:
1313                    parm = dlg.GetValue()
1314                    for r in indx:                       
1315                        atomData[r][cid] = parm
1316                    SetupGeneral()
1317                    FillAtomsGrid()
1318            elif parm in ['x','y','z']:
1319                limits = [-1.,1.]
1320                val = 0.
1321                dlg = SingleFloatDialog(G2frame,'Atom shift','Enter shift for '+parm,val,limits)
1322                if dlg.ShowModal() == wx.ID_OK:
1323                    parm = dlg.GetValue()
1324                    for r in indx:                       
1325                        atomData[r][cid] += parm
1326                    SetupGeneral()
1327                    FillAtomsGrid()
1328
1329    def AtomTransform(event):
1330        indx = Atoms.GetSelectedRows()
1331        if indx:
1332            generalData = data['General']
1333            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1334            cx = colLabels.index('x')
1335            cuia = colLabels.index('I/A')
1336            cuij = colLabels.index('U11')
1337            css = colLabels.index('site sym')
1338            atomData = data['Atoms']
1339            generalData = data['General']
1340            SGData = generalData['SGData']
1341            dlg = SymOpDialog(G2frame,SGData,True)
1342            try:
1343                if dlg.ShowModal() == wx.ID_OK:
1344                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1345                    Cell = np.array(Cell)
1346                    cent = SGData['SGCen'][Cent]
1347                    M,T = SGData['SGOps'][Opr]
1348                    for ind in indx:
1349                        XYZ = np.array(atomData[ind][cx:cx+3])
1350                        XYZ = np.inner(M,XYZ)+T
1351                        if Inv:
1352                            XYZ = -XYZ
1353                        XYZ = XYZ+cent+Cell
1354                        if New:
1355                            atom = copy.copy(atomData[ind])
1356                        else:
1357                            atom = atomData[ind]
1358                        atom[cx:cx+3] = XYZ
1359                        atom[css:css+2] = G2spc.SytSym(XYZ,SGData)
1360                        if atom[cuia] == 'A':
1361                            Uij = atom[cuij:cuij+6]
1362                            U = G2spc.Uij2U(Uij)
1363                            U = np.inner(np.inner(M,U),M)
1364                            Uij = G2spc.U2Uij(U)
1365                            atom[cuij:cuij+6] = Uij
1366                        if New:
1367                            atomData.append(atom)
1368            finally:
1369                dlg.Destroy()
1370            Atoms.ClearSelection()
1371            if New:
1372                FillAtomsGrid()
1373            else:
1374                Atoms.ForceRefresh()
1375
1376    def OnDistAngle(event):
1377        indx = Atoms.GetSelectedRows()
1378        Oxyz = []
1379        xyz = []
1380        DisAglData = {}
1381        DisAglCtls = {}
1382        if indx:
1383            generalData = data['General']
1384            DisAglData['OrigIndx'] = indx
1385            if 'DisAglCtls' in generalData:
1386                DisAglCtls = generalData['DisAglCtls']
1387            dlg = DisAglDialog(G2frame,DisAglCtls,generalData)
1388            if dlg.ShowModal() == wx.ID_OK:
1389                DisAglCtls = dlg.GetData()
1390            dlg.Destroy()
1391            generalData['DisAglCtls'] = DisAglCtls
1392            atomData = data['Atoms']
1393            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1394            cx = colLabels.index('x')
1395            cn = colLabels.index('Name')
1396            for i,atom in enumerate(atomData):
1397                xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1398                if i in indx:
1399                    Oxyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1400            DisAglData['OrigAtoms'] = Oxyz
1401            DisAglData['TargAtoms'] = xyz
1402            generalData = data['General']
1403            DisAglData['SGData'] = generalData['SGData']
1404            DisAglData['Cell'] = generalData['Cell'][1:] #+ volume
1405            if 'pId' in data:
1406                DisAglData['pId'] = data['pId']
1407                DisAglData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance'))
1408            G2str.DistAngle(DisAglCtls,DisAglData)
1409           
1410################################################################################
1411#Structure drawing GUI stuff               
1412################################################################################
1413
1414    def SetupDrawingData():
1415        generalData = data['General']
1416        atomData = data['Atoms']
1417        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
1418            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
1419        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
1420            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
1421        defaultDrawing = {'Atoms':[],'viewPoint':[[0.5,0.5,0.5],[]],'showHydrogen':True,
1422            'backColor':[0,0,0],'depthFog':False,'Zclip':50.0,'cameraPos':50.,
1423            'radiusFactor':0.85,'contourLevel':1.,'bondRadius':0.1,'ballScale':0.33,
1424            'vdwScale':0.67,'ellipseProb':50,'sizeH':0.50,'unitCellBox':False,
1425            'showABC':True,'selectedAtoms':[],'Atoms':[],'Rotation':[0.0,0.0,0.0,[]],
1426            'bondList':{},'testPos':[[-.1,-.1,-.1],[0.0,0.0,0.0],[0,0]]}
1427        try:
1428            drawingData = data['Drawing']
1429        except KeyError:
1430            data['Drawing'] = {}
1431            drawingData = data['Drawing']
1432        if not drawingData:                 #fill with defaults if empty
1433            drawingData.update(defaultDrawing)
1434        if 'contourLevel' not in drawingData:
1435            drawingData['contourLevel'] = 1.
1436        cx,ct,cs = [0,0,0]
1437        if generalData['Type'] == 'nuclear':
1438            cx,ct,cs = [2,1,6]         #x, type & style
1439        elif generalData['Type'] == 'macromolecular':
1440            cx,ct,cs = [5,4,9]         #x, type & style
1441        elif generalData['Type'] == 'magnetic':
1442            cx,ct,cs = [2,1,6]         #x, type & style
1443#        elif generalData['Type'] == 'modulated':
1444#           ?????   for future
1445        if not drawingData.get('Atoms'):
1446            for atom in atomData:
1447                DrawAtomAdd(drawingData,atom)
1448            drawingData['atomPtrs'] = [cx,ct,cs]
1449            data['Drawing'] = drawingData
1450           
1451    def MakeDrawAtom(atom,oldatom=None):
1452        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
1453            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
1454        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
1455            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
1456        generalData = data['General']
1457        SGData = generalData['SGData']
1458        if generalData['Type'] == 'nuclear':
1459            if oldatom:
1460                opr = oldatom[5]
1461                if atom[9] == 'A':                   
1462                    X,U = G2spc.ApplyStringOps(opr,SGData,atom[3:6],atom[11:17])
1463                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:11]+list(U)+oldatom[17:]][0]
1464                else:
1465                    X = G2spc.ApplyStringOps(opr,SGData,atom[3:6])
1466                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:]+[oldatom[-1]]][0]
1467            else:
1468                atomInfo = [atom[:2]+atom[3:6]+['1',]+['vdW balls',]+
1469                    ['',]+[[255,255,255],]+atom[9:]+[[],[]]][0]
1470            ct,cs = [1,8]         #type & color
1471        elif generalData['Type'] == 'macromolecular':
1472            try:
1473                oneLetter = AA3letter.index(atom[1])
1474            except ValueError:
1475                oneLetter = -1
1476            atomInfo = [[atom[1].strip()+atom[0],]+
1477                [AA1letter[oneLetter]+atom[0],]+atom[2:5]+
1478                atom[6:9]+['1',]+['sticks',]+['',]+[[255,255,255],]+atom[12:]+[[],[]]][0]
1479            ct,cs = [4,11]         #type & color
1480        elif generalData['Type'] == 'magnetic':
1481            if oldatom:
1482                atomInfo = [atom[:2]+oldatom[3:]][0]
1483            else:
1484                atomInfo = [atom[:2]+atom[3:6]+['vdW balls',]+['',]+atom[9:]+[[],[]]][0]
1485            ct,cs = [1,8]         #type & color
1486#        elif generalData['Type'] == 'modulated':
1487#           ?????   for future
1488        atNum = generalData['AtomTypes'].index(atom[ct])
1489        atomInfo[cs] = list(generalData['Color'][atNum])
1490        return atomInfo
1491           
1492    def DrawAtomAdd(drawingData,atom):
1493        drawingData['Atoms'].append(MakeDrawAtom(atom))
1494       
1495    def DrawAtomsReplaceByID(drawingData,atom,ID):
1496        IDs = [ID,]
1497        atomData = drawingData['Atoms']
1498        indx = FindAtomIndexByIDs(atomData,IDs)
1499        for ind in indx:
1500            atomData[ind] = MakeDrawAtom(atom,atomData[ind])
1501
1502################################################################################
1503##### Atom draw routines
1504################################################################################
1505           
1506    def UpdateDrawAtoms():
1507        generalData = data['General']
1508        SetupDrawingData()
1509        drawingData = data['Drawing']
1510        cx,ct,cs = drawingData['atomPtrs']
1511        atomData = drawingData['Atoms']
1512        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',]+ \
1513            [wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,polyhedra",
1514            wg.GRID_VALUE_CHOICE+": ,type,name,number",wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]
1515        styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1516        labelChoice = [' ','type','name','number']
1517        colLabels = ['Name','Type','x','y','z','Sym Op','Style','Label','Color','I/A']
1518        if generalData['Type'] == 'macromolecular':
1519            colLabels = ['Residue','1-letter','Chain'] + colLabels
1520            Types = 3*[wg.GRID_VALUE_STRING,]+Types
1521            Types[8] = wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,backbone,ribbons,schematic"
1522            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','backbone','ribbons','schematic']
1523            labelChoice = [' ','type','name','number','residue','1-letter','chain']
1524            Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1-letter,chain"
1525#        elif generalData['Type'] == 'modulated':
1526#            Types += []
1527#            colLabels += []
1528
1529        def RefreshAtomGrid(event):
1530
1531            def SetChoice(name,c,n=0):
1532                choice = []
1533                for r in range(len(atomData)):
1534                    if n:
1535                        srchStr = str(atomData[r][c][:n])
1536                    else:
1537                        srchStr = str(atomData[r][c])
1538                    if srchStr not in choice:
1539                        if n:
1540                            choice.append(str(atomData[r][c][:n]))
1541                        else:
1542                            choice.append(str(atomData[r][c]))
1543                choice.sort()
1544
1545                dlg = wx.MultiChoiceDialog(G2frame,'Select',name,choice)
1546                if dlg.ShowModal() == wx.ID_OK:
1547                    sel = dlg.GetSelections()
1548                    parms = []
1549                    for x in sel:
1550                        parms.append(choice[x])
1551                    noSkip = False
1552                    drawAtoms.ClearSelection()
1553                    drawingData['selectedAtoms'] = []
1554                    for row in range(len(atomData)):
1555                        test = atomData[row][c]
1556                        if n:
1557                            test = test[:n]
1558                        if  test in parms:
1559                            drawAtoms.SelectRow(row,True)
1560                            drawingData['selectedAtoms'].append(row)
1561                    G2plt.PlotStructure(G2frame,data)                   
1562                dlg.Destroy()
1563               
1564            r,c =  event.GetRow(),event.GetCol()
1565            if r < 0 and c < 0:
1566                for row in range(drawAtoms.GetNumberRows()):
1567                    drawingData['selectedAtoms'].append(row)
1568                    drawAtoms.SelectRow(row,True)                   
1569            elif r < 0:                          #dclick on col label
1570                sel = -1
1571                Parms = False
1572                noSkip = True
1573                if drawAtoms.GetColLabelValue(c) == 'Style':
1574                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice)
1575                    if dlg.ShowModal() == wx.ID_OK:
1576                        sel = dlg.GetSelection()
1577                        parms = styleChoice[sel]
1578                        for r in range(len(atomData)):
1579                            atomData[r][c] = parms
1580                            drawAtoms.SetCellValue(r,c,parms)
1581                        FindBondsDraw()
1582                        G2plt.PlotStructure(G2frame,data)
1583                    dlg.Destroy()
1584                elif drawAtoms.GetColLabelValue(c) == 'Label':
1585                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom labelling style',labelChoice)
1586                    if dlg.ShowModal() == wx.ID_OK:
1587                        sel = dlg.GetSelection()
1588                        parms = labelChoice[sel]
1589                        for r in range(len(atomData)):
1590                            atomData[r][c] = parms
1591                            drawAtoms.SetCellValue(r,c,parms)
1592                    dlg.Destroy()                   
1593                elif drawAtoms.GetColLabelValue(c) == 'Color':
1594                    dlg = wx.ColourDialog(G2frame)
1595                    if dlg.ShowModal() == wx.ID_OK:
1596                        color = dlg.GetColourData().GetColour()
1597                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1598                        attr.SetReadOnly(True)
1599                        attr.SetBackgroundColour(color)
1600                        for r in range(len(atomData)):
1601                            atomData[r][c] = color
1602                            drawingData['Atoms'][r][c] = color
1603                            drawAtoms.SetAttr(r,c,attr)
1604                        UpdateDrawAtoms()
1605                    dlg.Destroy()
1606                elif drawAtoms.GetColLabelValue(c) == 'Residue':
1607                    SetChoice('Residue',c,3)
1608                elif drawAtoms.GetColLabelValue(c) == '1-letter':
1609                    SetChoice('1-letter',c,1)
1610                elif drawAtoms.GetColLabelValue(c) == 'Chain':
1611                    SetChoice('Chain',c)
1612                elif drawAtoms.GetColLabelValue(c) == 'Name':
1613                    SetChoice('Name',c)
1614                elif drawAtoms.GetColLabelValue(c) == 'Sym Op':
1615                    SetChoice('Name',c)
1616                elif drawAtoms.GetColLabelValue(c) == 'Type':
1617                    SetChoice('Type',c)
1618                elif drawAtoms.GetColLabelValue(c) in ['x','y','z','I/A']:
1619                    drawAtoms.ClearSelection()
1620            else:
1621                if drawAtoms.GetColLabelValue(c) in ['Style','Label']:
1622                    atomData[r][c] = drawAtoms.GetCellValue(r,c)
1623                    FindBondsDraw()
1624                elif drawAtoms.GetColLabelValue(c) == 'Color':
1625                    color = atomData[r][c]
1626                    colors = wx.ColourData()
1627                    colors.SetChooseFull(True)
1628                    colors.SetCustomColour(0,color)
1629                    colors.SetColour(color)
1630                    dlg = wx.ColourDialog(G2frame,colors)
1631                    dlg.GetColourData().SetCustomColour(0,color)
1632                    if dlg.ShowModal() == wx.ID_OK:
1633                        color = dlg.GetColourData().GetColour()
1634                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1635                        attr.SetReadOnly(True)
1636                        attr.SetBackgroundColour(color)
1637                        atomData[r][c] = color
1638                        drawingData['Atoms'][r][c] = color
1639                        drawAtoms.SetAttr(i,cs+2,attr)
1640                    dlg.Destroy()
1641                    event.StopPropagation()
1642                    UpdateDrawAtoms()
1643            G2plt.PlotStructure(G2frame,data)
1644                   
1645        def RowSelect(event):
1646            r,c =  event.GetRow(),event.GetCol()
1647            if r < 0 and c < 0:
1648                if drawAtoms.IsSelection():
1649                    drawAtoms.ClearSelection()
1650            elif c < 0:                   #only row clicks
1651                if event.ControlDown():                   
1652                    if r in drawAtoms.GetSelectedRows():
1653                        drawAtoms.DeselectRow(r)
1654                    else:
1655                        drawAtoms.SelectRow(r,True)
1656                elif event.ShiftDown():
1657                    for row in range(r+1):
1658                        drawAtoms.SelectRow(row,True)
1659                else:
1660                    drawAtoms.ClearSelection()
1661                    drawAtoms.SelectRow(r,True)               
1662            drawingData['selectedAtoms'] = []
1663            drawingData['selectedAtoms'] = drawAtoms.GetSelectedRows()
1664            G2plt.PlotStructure(G2frame,data)                   
1665               
1666        table = []
1667        rowLabels = []
1668        for i,atom in enumerate(drawingData['Atoms']):
1669            table.append(atom[:colLabels.index('I/A')+1])
1670            rowLabels.append(str(i))
1671
1672        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1673        drawAtoms.SetTable(atomTable, True)
1674        drawAtoms.SetMargins(0,0)
1675        drawAtoms.AutoSizeColumns(True)
1676        drawAtoms.SetColSize(colLabels.index('Style'),80)
1677        drawAtoms.SetColSize(colLabels.index('Color'),50)
1678        drawAtoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
1679        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1680        drawAtoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, RefreshAtomGrid)
1681        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
1682        for i,atom in enumerate(drawingData['Atoms']):
1683            attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1684            attr.SetReadOnly(True)
1685            attr.SetBackgroundColour(atom[cs+2])
1686            drawAtoms.SetAttr(i,cs+2,attr)
1687            drawAtoms.SetCellValue(i,cs+2,'')
1688        indx = drawingData['selectedAtoms']
1689        if indx:
1690            for r in range(len(atomData)):
1691                if r in indx:
1692                    drawAtoms.SelectRow(r)
1693        for c in range(len(colLabels)):
1694           attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1695           attr.SetReadOnly(True)
1696           attr.SetBackgroundColour(VERY_LIGHT_GREY)
1697           if colLabels[c] not in ['Style','Label','Color']:
1698                drawAtoms.SetColAttr(c,attr)
1699        G2frame.dataFrame.setSizePosLeft([600,300])
1700       
1701        FindBondsDraw()
1702        drawAtoms.ClearSelection()
1703        G2plt.PlotStructure(G2frame,data)
1704
1705    def DrawAtomStyle(event):
1706        indx = drawAtoms.GetSelectedRows()
1707        if indx:
1708            generalData = data['General']
1709            atomData = data['Drawing']['Atoms']
1710            cx,ct,cs = data['Drawing']['atomPtrs']
1711            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1712            if generalData['Type'] == 'macromolecular':
1713                styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids',
1714                'backbone','ribbons','schematic']
1715            dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice)
1716            if dlg.ShowModal() == wx.ID_OK:
1717                sel = dlg.GetSelection()
1718                parms = styleChoice[sel]
1719                for r in indx:
1720                    atomData[r][cs] = parms
1721                    drawAtoms.SetCellValue(r,cs,parms)
1722            dlg.Destroy()
1723            FindBondsDraw()
1724            drawAtoms.ClearSelection()
1725            G2plt.PlotStructure(G2frame,data)
1726
1727    def DrawAtomLabel(event):
1728        indx = drawAtoms.GetSelectedRows()
1729        if indx:
1730            generalData = data['General']
1731            atomData = data['Drawing']['Atoms']
1732            cx,ct,cs = data['Drawing']['atomPtrs']
1733            styleChoice = [' ','type','name','number']
1734            if generalData['Type'] == 'macromolecular':
1735                styleChoice = [' ','type','name','number','residue','1-letter','chain']
1736            dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom label style',styleChoice)
1737            if dlg.ShowModal() == wx.ID_OK:
1738                sel = dlg.GetSelection()
1739                parms = styleChoice[sel]
1740                for r in indx:
1741                    atomData[r][cs+1] = parms
1742                    drawAtoms.SetCellValue(r,cs+1,parms)
1743            dlg.Destroy()
1744            drawAtoms.ClearSelection()
1745            G2plt.PlotStructure(G2frame,data)
1746           
1747    def DrawAtomColor(event):
1748
1749        indx = drawAtoms.GetSelectedRows()
1750        if indx:
1751            if len(indx) > 1:
1752                G2frame.dataFrame.SetStatusText('Select Custom Color, change color, Add to Custom Colors, then OK')
1753            else:
1754                G2frame.dataFrame.SetStatusText('Change color, Add to Custom Colors, then OK')
1755            generalData = data['General']
1756            atomData = data['Drawing']['Atoms']
1757            cx,ct,cs = data['Drawing']['atomPtrs']
1758            atmColors = []
1759            atmTypes = []
1760            for r in indx:
1761                if atomData[r][cs+2] not in atmColors:
1762                    atmColors.append(atomData[r][cs+2])
1763                    atmTypes.append(atomData[r][ct])
1764                    if len(atmColors) > 16:
1765                        break
1766            colors = wx.ColourData()
1767            colors.SetChooseFull(True)
1768            for i,color in enumerate(atmColors):
1769                colors.SetCustomColour(i,color)
1770            dlg = wx.ColourDialog(G2frame,colors)
1771            if dlg.ShowModal() == wx.ID_OK:
1772                for i in range(len(atmColors)):                   
1773                    atmColors[i] = dlg.GetColourData().GetCustomColour(i)
1774                colorDict = dict(zip(atmTypes,atmColors))
1775                for r in indx:
1776                    color = colorDict[atomData[r][ct]]
1777                    atomData[r][cs+2] = color
1778                    attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1779                    attr.SetBackgroundColour(color)
1780                    drawAtoms.SetAttr(r,cs+2,attr)
1781                    data['Drawing']['Atoms'][r][cs+2] = color
1782            drawAtoms.ClearSelection()
1783            dlg.Destroy()
1784            G2frame.dataFrame.SetStatusText('')
1785            G2plt.PlotStructure(G2frame,data)
1786           
1787    def ResetAtomColors(event):
1788        generalData = data['General']
1789        atomData = data['Drawing']['Atoms']
1790        cx,ct,cs = data['Drawing']['atomPtrs']
1791        for atom in atomData:           
1792            atNum = generalData['AtomTypes'].index(atom[ct])
1793            atom[cs+2] = list(generalData['Color'][atNum])
1794        UpdateDrawAtoms()
1795        drawAtoms.ClearSelection()
1796        G2plt.PlotStructure(G2frame,data)       
1797       
1798    def SetViewPoint(event):
1799        indx = drawAtoms.GetSelectedRows()
1800        if indx:
1801            atomData = data['Drawing']['Atoms']
1802            cx = data['Drawing']['atomPtrs'][0]
1803            data['Drawing']['viewPoint'] = [atomData[indx[0]][cx:cx+3],[indx[0],0]]
1804            drawAtoms.ClearSelection()                                  #do I really want to do this?
1805            G2plt.PlotStructure(G2frame,data)
1806           
1807    def noDuplicate(xyz,atomData):                  #be careful where this is used - it's slow
1808        cx = data['Drawing']['atomPtrs'][0]
1809        if True in [np.allclose(np.array(xyz),np.array(atom[cx:cx+3]),atol=0.0002) for atom in atomData]:
1810            return False
1811        else:
1812            return True
1813               
1814    def AddSymEquiv(event):
1815        indx = drawAtoms.GetSelectedRows()
1816        indx.sort()
1817        if indx:
1818            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1819            cx = colLabels.index('x')
1820            cuia = colLabels.index('I/A')
1821            cuij = cuia+2
1822            atomData = data['Drawing']['Atoms']
1823            generalData = data['General']
1824            SGData = generalData['SGData']
1825            dlg = SymOpDialog(G2frame,SGData,False)
1826            try:
1827                if dlg.ShowModal() == wx.ID_OK:
1828                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1829                    Cell = np.array(Cell)
1830                    cent = SGData['SGCen'][Cent]
1831                    M,T = SGData['SGOps'][Opr]
1832                    for ind in indx:
1833                        XYZ = np.array(atomData[ind][cx:cx+3])
1834                        XYZ = np.inner(M,XYZ)+T
1835                        if Inv:
1836                            XYZ = -XYZ
1837                        XYZ = XYZ+cent+Cell
1838                        if noDuplicate(XYZ,atomData):
1839                            atom = copy.copy(atomData[ind])
1840                            atom[cx:cx+3] = XYZ
1841                            atomOp = atom[cx+3]
1842                            newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1843                                str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))                           
1844                            atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1845                            if atom[cuia] == 'A':
1846                                Uij = atom[cuij:cuij+6]
1847                                U = G2spc.Uij2U(Uij)
1848                                U = np.inner(np.inner(M,U),M)
1849                                Uij = G2spc.U2Uij(U)
1850                                atom[cuij:cuij+6] = Uij
1851                            atomData.append(atom)
1852            finally:
1853                dlg.Destroy()
1854            UpdateDrawAtoms()
1855            drawAtoms.ClearSelection()
1856            G2plt.PlotStructure(G2frame,data)
1857           
1858    def TransformSymEquiv(event):
1859        indx = drawAtoms.GetSelectedRows()
1860        indx.sort()
1861        if indx:
1862            atomData = data['Drawing']['Atoms']
1863            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1864            cx = colLabels.index('x')
1865            cuia = colLabels.index('I/A')
1866            cuij = cuia+2
1867            atomData = data['Drawing']['Atoms']
1868            generalData = data['General']
1869            SGData = generalData['SGData']
1870            dlg = SymOpDialog(G2frame,SGData,False)
1871            try:
1872                if dlg.ShowModal() == wx.ID_OK:
1873                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1874                    Cell = np.array(Cell)
1875                    cent = SGData['SGCen'][Cent]
1876                    M,T = SGData['SGOps'][Opr]
1877                    for ind in indx:
1878                        XYZ = np.array(atomData[ind][cx:cx+3])
1879                        XYZ = np.inner(M,XYZ)+T
1880                        if Inv:
1881                            XYZ = -XYZ
1882                        XYZ = XYZ+cent+Cell
1883                        atom = atomData[ind]
1884                        atom[cx:cx+3] = XYZ
1885                        atomOp = atom[cx+3]
1886                        newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1887                            str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))
1888                        atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1889                        if atom[cuia] == 'A':
1890                            Uij = atom[cuij:cuij+6]
1891                            U = G2spc.Uij2U(Uij)
1892                            U = np.inner(np.inner(M,U),M)
1893                            Uij = G2spc.U2Uij(U)
1894                            atom[cuij:cuij+6] = Uij
1895                    data['Drawing']['Atoms'] = atomData
1896            finally:
1897                dlg.Destroy()
1898            UpdateDrawAtoms()
1899            drawAtoms.ClearSelection()
1900            G2plt.PlotStructure(G2frame,data)
1901           
1902    def FillCoordSphere(event):
1903        generalData = data['General']
1904        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1905        radii = generalData['BondRadii']
1906        atomTypes = generalData['AtomTypes']
1907        try:
1908            indH = atomTypes.index('H')
1909            radii[indH] = 0.5
1910        except:
1911            pass           
1912        indx = drawAtoms.GetSelectedRows()
1913        if indx:
1914            indx.sort()
1915            atomData = data['Drawing']['Atoms']
1916            numAtoms = len(atomData)
1917            cx,ct,cs = data['Drawing']['atomPtrs']
1918            generalData = data['General']
1919            SGData = generalData['SGData']
1920            cellArray = G2lat.CellBlock(1)
1921            for ind in indx:
1922                atomA = atomData[ind]
1923                xyzA = np.array(atomA[cx:cx+3])
1924                indA = atomTypes.index(atomA[ct])
1925                for atomB in atomData[:numAtoms]:
1926                    indB = atomTypes.index(atomB[ct])
1927                    sumR = radii[indA]+radii[indB]
1928                    xyzB = np.array(atomB[cx:cx+3])
1929                    for xyz in cellArray+xyzB:
1930                        dist = np.sqrt(np.sum(np.inner(Amat,xyz-xyzA)**2))
1931                        if 0 < dist <= data['Drawing']['radiusFactor']*sumR:
1932                            if noDuplicate(xyz,atomData):
1933                                oprB = atomB[cx+3]
1934                                C = xyz-xyzB
1935                                newOp = '1+'+str(int(round(C[0])))+','+str(int(round(C[1])))+','+str(int(round(C[2])))
1936                                newAtom = atomB[:]
1937                                newAtom[cx:cx+3] = xyz
1938                                newAtom[cx+3] = G2spc.StringOpsProd(oprB,newOp,SGData)
1939                                atomData.append(newAtom)
1940            data['Drawing']['Atoms'] = atomData
1941            UpdateDrawAtoms()
1942            drawAtoms.ClearSelection()
1943            G2plt.PlotStructure(G2frame,data)
1944           
1945    def FillUnitCell(event):
1946        indx = drawAtoms.GetSelectedRows()
1947        indx.sort()
1948        if indx:
1949            atomData = data['Drawing']['Atoms']
1950            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1951            cx = colLabels.index('x')
1952            cuia = colLabels.index('I/A')
1953            cuij = cuia+2
1954            generalData = data['General']
1955            SGData = generalData['SGData']
1956            for ind in indx:
1957                atom = atomData[ind]
1958                XYZ = np.array(atom[cx:cx+3])
1959                if atom[cuia] == 'A':
1960                    Uij = atom[cuij:cuij+6]
1961                    result = G2spc.GenAtom(XYZ,SGData,False,Uij,False)
1962                    for item in result:
1963                        atom = copy.copy(atomData[ind])
1964                        atom[cx:cx+3] = item[0]
1965                        atom[cx+3] = str(item[2])+'+' \
1966                            +str(item[3][0])+','+str(item[3][1])+','+str(item[3][2])
1967                        atom[cuij:cuij+6] = item[1]
1968                        Opp = G2spc.Opposite(item[0])
1969                        for xyz in Opp:
1970                            if noDuplicate(xyz,atomData):
1971                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
1972                                cell = '1'+'+'+ \
1973                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
1974                                atom[cx:cx+3] = xyz
1975                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
1976                                atomData.append(atom[:])
1977                else:
1978                    result = G2spc.GenAtom(XYZ,SGData,False,Move=False)
1979                    for item in result:
1980                        atom = copy.copy(atomData[ind])
1981                        atom[cx:cx+3] = item[0]
1982                        atom[cx+3] = str(item[1])+'+' \
1983                            +str(item[2][0])+','+str(item[2][1])+','+str(item[2][2])
1984                        Opp = G2spc.Opposite(item[0])
1985                        for xyz in Opp:
1986                            if noDuplicate(xyz,atomData):
1987                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
1988                                cell = '1'+'+'+ \
1989                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
1990                                atom[cx:cx+3] = xyz
1991                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
1992                                atomData.append(atom[:])               
1993                data['Drawing']['Atoms'] = atomData
1994            UpdateDrawAtoms()
1995            drawAtoms.ClearSelection()
1996            G2plt.PlotStructure(G2frame,data)
1997           
1998    def FindBondsToo():                         #works but slow for large structures - keep as reference
1999        cx,ct,cs = data['Drawing']['atomPtrs']
2000        atomData = data['Drawing']['Atoms']
2001        generalData = data['General']
2002        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
2003        radii = generalData['BondRadii']
2004        atomTypes = generalData['AtomTypes']
2005        try:
2006            indH = atomTypes.index('H')
2007            radii[indH] = 0.5
2008        except:
2009            pass           
2010        for atom in atomData:
2011            atom[-1] = []
2012        Atoms = []
2013        for i,atom in enumerate(atomData):
2014            Atoms.append([i,np.array(atom[cx:cx+3]),atom[cs],radii[atomTypes.index(atom[ct])]])
2015        for atomA in Atoms:
2016            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
2017                for atomB in Atoms:                   
2018                    Dx = atomB[1]-atomA[1]
2019                    DX = np.inner(Amat,Dx)
2020                    dist = np.sqrt(np.sum(DX**2))
2021                    sumR = atomA[3]+atomB[3]
2022                    if 0.5 < dist <= 0.85*sumR:
2023                        i = atomA[0]
2024                        if atomA[2] == 'polyhedra':
2025                            atomData[i][-1].append(DX)
2026                        elif atomB[1] != 'polyhedra':
2027                            j = atomB[0]
2028                            atomData[i][-1].append(Dx*atomA[3]/sumR)
2029                            atomData[j][-1].append(-Dx*atomB[3]/sumR)
2030                   
2031    def FindBondsDraw():                    #uses numpy & masks - very fast even for proteins!
2032        import numpy.ma as ma
2033        cx,ct,cs = data['Drawing']['atomPtrs']
2034        hydro = data['Drawing']['showHydrogen']
2035        atomData = data['Drawing']['Atoms']
2036        generalData = data['General']
2037        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
2038        radii = generalData['BondRadii']
2039        atomTypes = generalData['AtomTypes']
2040        try:
2041            indH = atomTypes.index('H')
2042            radii[indH] = 0.5
2043        except:
2044            pass           
2045        for atom in atomData:
2046            atom[-2] = []               #clear out old bonds/polyhedra
2047            atom[-1] = []
2048        Indx = range(len(atomData))
2049        Atoms = []
2050        Styles = []
2051        Radii = []
2052        for atom in atomData:
2053            Atoms.append(np.array(atom[cx:cx+3]))
2054            Styles.append(atom[cs])
2055            try:
2056                if not hydro and atom[ct] == 'H':
2057                    Radii.append(0.0)
2058                else:
2059                    Radii.append(radii[atomTypes.index(atom[ct])])
2060            except ValueError:          #changed atom type!
2061                Radii.append(0.20)
2062        Atoms = np.array(Atoms)
2063        Radii = np.array(Radii)
2064        IASR = zip(Indx,Atoms,Styles,Radii)
2065        for atomA in IASR:
2066            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
2067                Dx = Atoms-atomA[1]
2068                dist = ma.masked_less(np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)),0.5) #gets rid of G2frame & disorder "bonds" < 0.5A
2069                sumR = atomA[3]+Radii
2070                IndB = ma.nonzero(ma.masked_greater(dist-data['Drawing']['radiusFactor']*sumR,0.))                 #get indices of bonded atoms
2071                i = atomA[0]
2072                for j in IndB[0]:
2073                    if Styles[i] == 'polyhedra':
2074                        atomData[i][-2].append(np.inner(Amat,Dx[j]))
2075                    elif Styles[j] != 'polyhedra' and j > i:
2076                        atomData[i][-2].append(Dx[j]*Radii[i]/sumR[j])
2077                        atomData[j][-2].append(-Dx[j]*Radii[j]/sumR[j])
2078                if Styles[i] == 'polyhedra':
2079                    Bonds = atomData[i][-2]
2080                    Faces = []
2081                    if len(Bonds) > 2:
2082                        FaceGen = G2lat.uniqueCombinations(Bonds,3)     #N.B. this is a generator
2083                        for face in FaceGen:
2084                            vol = nl.det(face)
2085                            if abs(vol) > 1. or len(Bonds) == 3:
2086                                if vol < 0.:
2087                                    face = [face[0],face[2],face[1]]
2088                                face = np.array(face)
2089                                if not np.array([np.array(nl.det(face-bond))+0.0001 < 0 for bond in Bonds]).any():
2090                                    norm = np.cross(face[1]-face[0],face[2]-face[0])
2091                                    norm /= np.sqrt(np.sum(norm**2))
2092                                    Faces.append([face,norm])
2093                        atomData[i][-1] = Faces
2094                       
2095    def DrawAtomsDelete(event):   
2096        indx = drawAtoms.GetSelectedRows()
2097        indx.sort()
2098        if indx:
2099            atomData = data['Drawing']['Atoms']
2100            indx.reverse()
2101            for ind in indx:
2102                del atomData[ind]
2103            UpdateDrawAtoms()
2104            drawAtoms.ClearSelection()
2105            G2plt.PlotStructure(G2frame,data)
2106        event.StopPropagation()
2107       
2108    def OnReloadDrawAtoms(event):
2109        data['Drawing']['Atoms'] = []
2110        UpdateDrawAtoms()
2111        drawAtoms.ClearSelection()
2112        G2plt.PlotStructure(G2frame,data)
2113        event.StopPropagation()
2114       
2115    def FindAtomIndexByIDs(atomData,IDs,Draw=True):
2116        indx = []
2117        for i,atom in enumerate(atomData):
2118            if Draw and atom[-3] in IDs:
2119                indx.append(i)
2120            elif atom[-1] in IDs:
2121                indx.append(i)
2122        return indx
2123       
2124    def DrawAtomsDeleteByIDs(IDs):
2125        atomData = data['Drawing']['Atoms']
2126        indx = FindAtomIndexByIDs(atomData,IDs)
2127        indx.reverse()
2128        for ind in indx:
2129            del atomData[ind]
2130           
2131    def ChangeDrawAtomsByIDs(colName,IDs,value):
2132        atomData = data['Drawing']['Atoms']
2133        cx,ct,cs = data['Drawing']['atomPtrs']
2134        if colName == 'Name':
2135            col = ct-1
2136        elif colName == 'Type':
2137            col = ct
2138        elif colName == 'I/A':
2139            col = cs
2140        indx = FindAtomIndexByIDs(atomData,IDs)
2141        for ind in indx:
2142            atomData[ind][col] = value
2143               
2144    def OnDrawPlane(event):
2145        indx = drawAtoms.GetSelectedRows()
2146        if len(indx) < 4:
2147            print '**** ERROR - need 4+ atoms for plane calculation'
2148            return
2149        PlaneData = {}
2150        drawingData = data['Drawing']
2151        atomData = drawingData['Atoms']
2152        colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
2153        cx = colLabels.index('x')
2154        cn = colLabels.index('Name')
2155        xyz = []
2156        for i,atom in enumerate(atomData):
2157            if i in indx:
2158                xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
2159        generalData = data['General']
2160        PlaneData['Name'] = generalData['Name']
2161        PlaneData['Atoms'] = xyz
2162        PlaneData['Cell'] = generalData['Cell'][1:] #+ volume
2163        G2str.BestPlane(PlaneData)
2164   
2165    def OnDrawDAT(event):
2166        #distance, angle, torsion
2167        indx = drawAtoms.GetSelectedRows()
2168        if len(indx) not in [2,3,4]:
2169            print '**** ERROR - wrong number of atoms for distance, angle or torsion calculation'
2170            return
2171        DATData = {}
2172        ocx,oct,ocs,cia = data['General']['AtomPtrs']
2173        drawingData = data['Drawing']
2174        atomData = data['Atoms']
2175        atomDData = drawingData['Atoms']
2176        colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
2177        cx = colLabels.index('x')
2178        cn = colLabels.index('Name')
2179        cid = colLabels.index('I/A')+8
2180        xyz = []
2181        Oxyz = []
2182        DATData['Natoms'] = len(indx)
2183        for i in indx:
2184            atom = atomDData[i]
2185            xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+4]) #also gets Sym Op
2186            id = FindAtomIndexByIDs(atomData,[atom[cid],],False)[0]
2187            Oxyz.append([id,]+atomData[id][cx+1:cx+4])
2188        DATData['Datoms'] = xyz
2189        DATData['Oatoms'] = Oxyz
2190        generalData = data['General']
2191        DATData['Name'] = generalData['Name']
2192        DATData['SGData'] = generalData['SGData']
2193        DATData['Cell'] = generalData['Cell'][1:] #+ volume
2194        if 'pId' in data:
2195            DATData['pId'] = data['pId']
2196            DATData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance'))
2197        G2str.DisAglTor(DATData)
2198               
2199################################################################################
2200#### Draw Options page
2201################################################################################
2202
2203    def UpdateDrawOptions():
2204        import copy
2205        import wx.lib.colourselect as wcs
2206        generalData = data['General']
2207        SetupDrawingData()
2208        drawingData = data['Drawing']
2209        if generalData['Type'] == 'nuclear':
2210            pickChoice = ['Atoms','Bonds','Torsions','Planes']
2211        elif generalData['Type'] == 'macromolecular':
2212            pickChoice = ['Atoms','Residues','Chains','Bonds','Torsions','Planes','phi/psi']
2213
2214        def SlopSizer():
2215           
2216            def OnCameraPos(event):
2217                drawingData['cameraPos'] = cameraPos.GetValue()
2218                cameraPosTxt.SetLabel(' Camera Distance: '+'%.2f'%(drawingData['cameraPos']))
2219                ZclipTxt.SetLabel(' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
2220                G2plt.PlotStructure(G2frame,data)
2221
2222            def OnZclip(event):
2223                drawingData['Zclip'] = Zclip.GetValue()
2224                ZclipTxt.SetLabel(' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
2225                G2plt.PlotStructure(G2frame,data)
2226               
2227            def OnVdWScale(event):
2228                drawingData['vdwScale'] = vdwScale.GetValue()/100.
2229                vdwScaleTxt.SetLabel(' van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
2230                G2plt.PlotStructure(G2frame,data)
2231   
2232            def OnEllipseProb(event):
2233                drawingData['ellipseProb'] = ellipseProb.GetValue()
2234                ellipseProbTxt.SetLabel(' Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
2235                G2plt.PlotStructure(G2frame,data)
2236   
2237            def OnBallScale(event):
2238                drawingData['ballScale'] = ballScale.GetValue()/100.
2239                ballScaleTxt.SetLabel(' Ball scale: '+'%.2f'%(drawingData['ballScale']))
2240                G2plt.PlotStructure(G2frame,data)
2241
2242            def OnBondRadius(event):
2243                drawingData['bondRadius'] = bondRadius.GetValue()/100.
2244                bondRadiusTxt.SetLabel(' Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
2245                G2plt.PlotStructure(G2frame,data)
2246               
2247            def OnContourLevel(event):
2248                drawingData['contourLevel'] = contourLevel.GetValue()/100.
2249                contourLevelTxt.SetLabel(' Contour level: '+'%.2f'%(drawingData['contourLevel']*generalData['Map']['rhoMax']))
2250                G2plt.PlotStructure(G2frame,data)
2251
2252            def OnMapSize(event):
2253                drawingData['mapSize'] = mapSize.GetValue()/10.
2254                mapSizeTxt.SetLabel(' Map radius, A: '+'%.1f'%(drawingData['mapSize']))
2255                G2plt.PlotStructure(G2frame,data)
2256
2257           
2258            slopSizer = wx.BoxSizer(wx.HORIZONTAL)
2259            slideSizer = wx.FlexGridSizer(7,2)
2260            slideSizer.AddGrowableCol(1,1)
2261   
2262            cameraPosTxt = wx.StaticText(dataDisplay,-1,
2263                ' Camera Distance: '+'%.2f'%(drawingData['cameraPos']),name='cameraPos')
2264            slideSizer.Add(cameraPosTxt,0,wx.ALIGN_CENTER_VERTICAL)
2265            cameraPos = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['cameraPos'],name='cameraSlider')
2266            cameraPos.SetRange(10,500)
2267            cameraPos.Bind(wx.EVT_SLIDER, OnCameraPos)
2268            slideSizer.Add(cameraPos,1,wx.EXPAND|wx.RIGHT)
2269           
2270            ZclipTxt = wx.StaticText(dataDisplay,-1,' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
2271            slideSizer.Add(ZclipTxt,0,wx.ALIGN_CENTER_VERTICAL)
2272            Zclip = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['Zclip'])
2273            Zclip.SetRange(1,99)
2274            Zclip.Bind(wx.EVT_SLIDER, OnZclip)
2275            slideSizer.Add(Zclip,1,wx.EXPAND|wx.RIGHT)
2276           
2277            vdwScaleTxt = wx.StaticText(dataDisplay,-1,' van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
2278            slideSizer.Add(vdwScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
2279            vdwScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['vdwScale']))
2280            vdwScale.Bind(wx.EVT_SLIDER, OnVdWScale)
2281            slideSizer.Add(vdwScale,1,wx.EXPAND|wx.RIGHT)
2282   
2283            ellipseProbTxt = wx.StaticText(dataDisplay,-1,' Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
2284            slideSizer.Add(ellipseProbTxt,0,wx.ALIGN_CENTER_VERTICAL)
2285            ellipseProb = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['ellipseProb'])
2286            ellipseProb.SetRange(1,99)
2287            ellipseProb.Bind(wx.EVT_SLIDER, OnEllipseProb)
2288            slideSizer.Add(ellipseProb,1,wx.EXPAND|wx.RIGHT)
2289   
2290            ballScaleTxt = wx.StaticText(dataDisplay,-1,' Ball scale: '+'%.2f'%(drawingData['ballScale']))
2291            slideSizer.Add(ballScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
2292            ballScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['ballScale']))
2293            ballScale.Bind(wx.EVT_SLIDER, OnBallScale)
2294            slideSizer.Add(ballScale,1,wx.EXPAND|wx.RIGHT)
2295   
2296            bondRadiusTxt = wx.StaticText(dataDisplay,-1,' Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
2297            slideSizer.Add(bondRadiusTxt,0,wx.ALIGN_CENTER_VERTICAL)
2298            bondRadius = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['bondRadius']))
2299            bondRadius.SetRange(1,25)
2300            bondRadius.Bind(wx.EVT_SLIDER, OnBondRadius)
2301            slideSizer.Add(bondRadius,1,wx.EXPAND|wx.RIGHT)
2302           
2303            if generalData['Map']['rhoMax']:
2304                contourLevelTxt = wx.StaticText(dataDisplay,-1,' Contour level: '+'%.2f'%(drawingData['contourLevel']*generalData['Map']['rhoMax']))
2305                slideSizer.Add(contourLevelTxt,0,wx.ALIGN_CENTER_VERTICAL)
2306                contourLevel = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['contourLevel']))
2307                contourLevel.SetRange(1,100)
2308                contourLevel.Bind(wx.EVT_SLIDER, OnContourLevel)
2309                slideSizer.Add(contourLevel,1,wx.EXPAND|wx.RIGHT)
2310                mapSizeTxt = wx.StaticText(dataDisplay,-1,' Map radius, A: '+'%.1f'%(drawingData['mapSize']))
2311                slideSizer.Add(mapSizeTxt,0,wx.ALIGN_CENTER_VERTICAL)
2312                mapSize = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(10*drawingData['mapSize']))
2313                mapSize.SetRange(1,100)
2314                mapSize.Bind(wx.EVT_SLIDER, OnMapSize)
2315                slideSizer.Add(mapSize,1,wx.EXPAND|wx.RIGHT)
2316           
2317            slopSizer.Add(slideSizer,1,wx.EXPAND|wx.RIGHT)
2318            slopSizer.Add((10,5),0)
2319            slopSizer.SetMinSize(wx.Size(350,10))
2320            return slopSizer
2321           
2322        def ShowSizer():
2323           
2324            def OnBackColor(event):
2325                drawingData['backColor'] = event.GetValue()
2326                G2plt.PlotStructure(G2frame,data)
2327   
2328            def OnShowABC(event):
2329                drawingData['showABC'] = showABC.GetValue()
2330                G2plt.PlotStructure(G2frame,data)
2331   
2332            def OnShowUnitCell(event):
2333                drawingData['unitCellBox'] = unitCellBox.GetValue()
2334                G2plt.PlotStructure(G2frame,data)
2335   
2336            def OnShowHyd(event):
2337                drawingData['showHydrogen'] = showHydrogen.GetValue()
2338                FindBondsDraw()
2339                G2plt.PlotStructure(G2frame,data)
2340               
2341            showSizer = wx.FlexGridSizer(5,3,5,0)           
2342            lineSizer = wx.BoxSizer(wx.HORIZONTAL)
2343            lineSizer.Add(wx.StaticText(dataDisplay,-1,' Background color:'),0,wx.ALIGN_CENTER_VERTICAL)
2344            backColor = wcs.ColourSelect(dataDisplay, -1,colour=drawingData['backColor'],size=wx.Size(25,25))
2345            backColor.Bind(wcs.EVT_COLOURSELECT, OnBackColor)
2346            lineSizer.Add(backColor,0,wx.ALIGN_CENTER_VERTICAL)
2347            showSizer.Add(lineSizer,0,)
2348           
2349            showSizer.Add(wx.StaticText(dataDisplay,-1,' View Point:  '),0,wx.ALIGN_CENTER_VERTICAL)
2350            VP = drawingData['viewPoint'][0]
2351            viewPoint = wx.TextCtrl(dataDisplay,value='%.3f, %.3f, %.3f'%(VP[0],VP[1],VP[2]),
2352                style=wx.TE_READONLY,size=wx.Size(120,20),name='viewPoint')
2353            viewPoint.SetBackgroundColour(VERY_LIGHT_GREY)
2354            showSizer.Add(viewPoint,0,wx.ALIGN_CENTER_VERTICAL)
2355           
2356            showABC = wx.CheckBox(dataDisplay,-1,label=' Show test point?')
2357            showABC.Bind(wx.EVT_CHECKBOX, OnShowABC)
2358            showABC.SetValue(drawingData['showABC'])
2359            showSizer.Add(showABC,0,wx.ALIGN_CENTER_VERTICAL)
2360   
2361            unitCellBox = wx.CheckBox(dataDisplay,-1,label=' Show unit cell?')
2362            unitCellBox.Bind(wx.EVT_CHECKBOX, OnShowUnitCell)
2363            unitCellBox.SetValue(drawingData['unitCellBox'])
2364            showSizer.Add(unitCellBox,0,wx.ALIGN_CENTER_VERTICAL)
2365   
2366            showHydrogen = wx.CheckBox(dataDisplay,-1,label=' Show hydrogens?')
2367            showHydrogen.Bind(wx.EVT_CHECKBOX, OnShowHyd)
2368            showHydrogen.SetValue(drawingData['showHydrogen'])
2369            showSizer.Add(showHydrogen,0,wx.ALIGN_CENTER_VERTICAL)
2370            return showSizer
2371           
2372        def RadSizer():
2373           
2374            def OnSizeHatoms(event):
2375                try:
2376                    value = max(0.1,min(1.2,float(sizeH.GetValue())))
2377                except ValueError:
2378                    value = 0.5
2379                drawingData['sizeH'] = value
2380                sizeH.SetValue("%.2f"%(value))
2381                G2plt.PlotStructure(G2frame,data)
2382               
2383            def OnRadFactor(event):
2384                try:
2385                    value = max(0.1,min(1.2,float(radFactor.GetValue())))
2386                except ValueError:
2387                    value = 0.85
2388                drawingData['radiusFactor'] = value
2389                radFactor.SetValue("%.2f"%(value))
2390                FindBondsDraw()
2391                G2plt.PlotStructure(G2frame,data)
2392           
2393            radSizer = wx.BoxSizer(wx.HORIZONTAL)
2394            radSizer.Add(wx.StaticText(dataDisplay,-1,' Hydrogen radius, A:  '),0,wx.ALIGN_CENTER_VERTICAL)
2395            sizeH = wx.TextCtrl(dataDisplay,-1,value='%.2f'%(drawingData['sizeH']),size=wx.Size(60,20),style=wx.TE_PROCESS_ENTER)
2396            sizeH.Bind(wx.EVT_TEXT_ENTER,OnSizeHatoms)
2397            sizeH.Bind(wx.EVT_KILL_FOCUS,OnSizeHatoms)
2398            radSizer.Add(sizeH,0,wx.ALIGN_CENTER_VERTICAL)
2399   
2400            radSizer.Add(wx.StaticText(dataDisplay,-1,' Bond search factor:  '),0,wx.ALIGN_CENTER_VERTICAL)
2401            radFactor = wx.TextCtrl(dataDisplay,value='%.2f'%(drawingData['radiusFactor']),size=wx.Size(60,20),style=wx.TE_PROCESS_ENTER)
2402            radFactor.Bind(wx.EVT_TEXT_ENTER,OnRadFactor)
2403            radFactor.Bind(wx.EVT_KILL_FOCUS,OnRadFactor)
2404            radSizer.Add(radFactor,0,wx.ALIGN_CENTER_VERTICAL)
2405            return radSizer
2406
2407        drawOptions.DestroyChildren()
2408        dataDisplay = wx.Panel(drawOptions)
2409        mainSizer = wx.BoxSizer(wx.VERTICAL)
2410        mainSizer.Add((5,5),0)
2411        mainSizer.Add(wx.StaticText(dataDisplay,-1,' Drawing controls:'),0,wx.ALIGN_CENTER_VERTICAL)
2412        mainSizer.Add((5,5),0)       
2413        mainSizer.Add(SlopSizer(),0)
2414        mainSizer.Add((5,5),0)
2415        mainSizer.Add(ShowSizer(),0,)
2416        mainSizer.Add((5,5),0)
2417        mainSizer.Add(RadSizer(),0,)
2418
2419        dataDisplay.SetSizer(mainSizer)
2420        Size = mainSizer.Fit(G2frame.dataFrame)
2421        Size[1] += 26                           #compensate for status bar
2422        dataDisplay.SetSize(Size)
2423        G2frame.dataFrame.setSizePosLeft(Size)
2424
2425################################################################################
2426####  Texture routines
2427################################################################################
2428       
2429    def UpdateTexture():
2430        generalData = data['General']       
2431        SGData = generalData['SGData']
2432        try:
2433            textureData = generalData['SH Texture']
2434        except KeyError:            #fix old files!
2435            textureData = generalData['SH Texture'] = {'Order':0,'Model':'cylindrical',
2436                'Sample omega':[False,0.0],'Sample chi':[False,0.0],'Sample phi':[False,0.0],
2437                'SH Coeff':[False,{}],'SHShow':False,'PFhkl':[0,0,1],
2438                'PFxyz':[0,0,1.],'PlotType':'Pole figure'}
2439        if 'SHShow' not in textureData:     #another fix
2440            textureData.update({'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
2441        try:                        #another fix!
2442            x = textureData['PlotType']
2443        except KeyError:
2444            textureData.update({'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
2445        shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
2446        SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
2447        if generalData['doPawley'] and G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequental results'):
2448            G2frame.dataFrame.RefineTexture.Enable(True)
2449        shAngles = ['omega','chi','phi']
2450       
2451        def SetSHCoef():
2452            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],SamSym[textureData['Model']],textureData['Order'])
2453            newSHCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
2454            SHCoeff = textureData['SH Coeff'][1]
2455            for cofName in SHCoeff:
2456                if cofName in  cofNames:
2457                    newSHCoef[cofName] = SHCoeff[cofName]
2458            return newSHCoef
2459       
2460        def OnShOrder(event):
2461            Obj = event.GetEventObject()
2462            textureData['Order'] = int(Obj.GetValue())
2463            textureData['SH Coeff'][1] = SetSHCoef()
2464            wx.CallAfter(UpdateTexture)
2465            G2plt.PlotTexture(G2frame,data)
2466                       
2467        def OnShModel(event):
2468            Obj = event.GetEventObject()
2469            textureData['Model'] = Obj.GetValue()
2470            textureData['SH Coeff'][1] = SetSHCoef()
2471            wx.CallAfter(UpdateTexture)
2472            G2plt.PlotTexture(G2frame,data)
2473           
2474        def OnSHRefine(event):
2475            Obj = event.GetEventObject()
2476            textureData['SH Coeff'][0] = Obj.GetValue()
2477           
2478        def OnSHShow(event):
2479            Obj = event.GetEventObject()
2480            textureData['SHShow'] = Obj.GetValue()
2481            wx.CallAfter(UpdateTexture)
2482           
2483        def OnProjSel(event):
2484            Obj = event.GetEventObject()
2485            G2frame.Projection = Obj.GetValue()
2486            G2plt.PlotTexture(G2frame,data)
2487           
2488        def OnColorSel(event):
2489            Obj = event.GetEventObject()
2490            G2frame.ContourColor = Obj.GetValue()
2491            G2plt.PlotTexture(G2frame,data)
2492           
2493        def OnAngRef(event):
2494            Obj = event.GetEventObject()
2495            textureData[angIndx[Obj.GetId()]][0] = Obj.GetValue()
2496           
2497        def OnAngValue(event):
2498            Obj = event.GetEventObject()
2499            try:
2500                value =  float(Obj.GetValue())
2501            except ValueError:
2502                value = textureData[valIndx[Obj.GetId()]][1]
2503            Obj.SetValue('%8.2f'%(value))
2504            textureData[valIndx[Obj.GetId()]][1] = value
2505           
2506        def OnODFValue(event): 
2507            Obj = event.GetEventObject()
2508            try:
2509                value =  float(Obj.GetValue())
2510            except ValueError:
2511                value = textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]]
2512            Obj.SetValue('%8.3f'%(value))
2513            textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] = value
2514            G2plt.PlotTexture(G2frame,data)
2515           
2516        def OnPfType(event):
2517            Obj = event.GetEventObject()
2518            textureData['PlotType'] = Obj.GetValue()
2519            wx.CallAfter(UpdateTexture)
2520            G2plt.PlotTexture(G2frame,data)
2521           
2522        def OnPFValue(event):
2523            Obj = event.GetEventObject()
2524            Saxis = Obj.GetValue().split()
2525            if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:               
2526                try:
2527                    hkl = [int(Saxis[i]) for i in range(3)]
2528                except (ValueError,IndexError):
2529                    hkl = textureData['PFhkl']
2530                if not np.any(np.array(hkl)):       #can't be all zeros!
2531                    hkl = textureData['PFhkl']
2532                Obj.SetValue('%d %d %d'%(hkl[0],hkl[1],hkl[2]))
2533                textureData['PFhkl'] = hkl
2534            else:
2535                try:
2536                    xyz = [float(Saxis[i]) for i in range(3)]
2537                except (ValueError,IndexError):
2538                    xyz = textureData['PFxyz']
2539                if not np.any(np.array(xyz)):       #can't be all zeros!
2540                    xyz = textureData['PFxyz']
2541                Obj.SetValue('%3.1f %3.1f %3.1f'%(xyz[0],xyz[1],xyz[2]))
2542                textureData['PFxyz'] = xyz
2543            G2plt.PlotTexture(G2frame,data)
2544
2545        if Texture.GetSizer():
2546            Texture.GetSizer().Clear(True)
2547        mainSizer = wx.BoxSizer(wx.VERTICAL)
2548        titleSizer = wx.BoxSizer(wx.HORIZONTAL)
2549        titleSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2550        titleSizer.Add(wx.StaticText(Texture,-1,
2551            ' Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))),
2552            0,wx.ALIGN_CENTER_VERTICAL)
2553        mainSizer.Add(titleSizer,0)
2554        mainSizer.Add((0,5),0)
2555        shSizer = wx.FlexGridSizer(1,6,5,5)
2556        shSizer.Add(wx.StaticText(Texture,-1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL)
2557        shModel = wx.ComboBox(Texture,-1,value=textureData['Model'],choices=shModels,
2558            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2559        shModel.Bind(wx.EVT_COMBOBOX,OnShModel)
2560        shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL)
2561        shSizer.Add(wx.StaticText(Texture,-1,'  Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2562        shOrder = wx.ComboBox(Texture,-1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)],
2563            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2564        shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder)
2565        shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL)
2566        shRef = wx.CheckBox(Texture,-1,label=' Refine texture?')
2567        shRef.SetValue(textureData['SH Coeff'][0])
2568        shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine)
2569        shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL)
2570        shShow = wx.CheckBox(Texture,-1,label=' Show coeff.?')
2571        shShow.SetValue(textureData['SHShow'])
2572        shShow.Bind(wx.EVT_CHECKBOX, OnSHShow)
2573        shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL)
2574        mainSizer.Add(shSizer,0,0)
2575        mainSizer.Add((0,5),0)
2576        PTSizer = wx.FlexGridSizer(2,4,5,5)
2577        PTSizer.Add(wx.StaticText(Texture,-1,' Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL)
2578        choices = ['Axial pole distribution','Pole figure','Inverse pole figure']           
2579        pfType = wx.ComboBox(Texture,-1,value=str(textureData['PlotType']),choices=choices,
2580            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2581        pfType.Bind(wx.EVT_COMBOBOX,OnPfType)
2582        PTSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL)
2583        if 'Axial' not in textureData['PlotType']:
2584            PTSizer.Add(wx.StaticText(Texture,-1,' Projection type: '),0,wx.ALIGN_CENTER_VERTICAL)
2585            projSel = wx.ComboBox(Texture,-1,value=G2frame.Projection,choices=['equal area','stereographic','3D display'],
2586                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2587            projSel.Bind(wx.EVT_COMBOBOX,OnProjSel)
2588            PTSizer.Add(projSel,0,wx.ALIGN_CENTER_VERTICAL)
2589        if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
2590            PTSizer.Add(wx.StaticText(Texture,-1,' Pole figure HKL: '),0,wx.ALIGN_CENTER_VERTICAL)
2591            PH = textureData['PFhkl']
2592            pfVal = wx.TextCtrl(Texture,-1,'%d %d %d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER)
2593        else:
2594            PTSizer.Add(wx.StaticText(Texture,-1,' Inverse pole figure XYZ: '),0,wx.ALIGN_CENTER_VERTICAL)
2595            PX = textureData['PFxyz']
2596            pfVal = wx.TextCtrl(Texture,-1,'%3.1f %3.1f %3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER)
2597        pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue)
2598        pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue)
2599        PTSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL)
2600        if 'Axial' not in textureData['PlotType']:
2601            PTSizer.Add(wx.StaticText(Texture,-1,' Color scheme'),0,wx.ALIGN_CENTER_VERTICAL)
2602            choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
2603            choice.sort()
2604            colorSel = wx.ComboBox(Texture,-1,value=G2frame.ContourColor,choices=choice,
2605                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2606            colorSel.Bind(wx.EVT_COMBOBOX,OnColorSel)
2607            PTSizer.Add(colorSel,0,wx.ALIGN_CENTER_VERTICAL)       
2608        mainSizer.Add(PTSizer,0,wx.ALIGN_CENTER_VERTICAL)
2609        mainSizer.Add((0,5),0)
2610        if textureData['SHShow']:
2611            mainSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2612            mainSizer.Add((0,5),0)
2613            ODFSizer = wx.FlexGridSizer(2,8,2,2)
2614            ODFIndx = {}
2615            ODFkeys = textureData['SH Coeff'][1].keys()
2616            ODFkeys.sort()
2617            for item in ODFkeys:
2618                ODFSizer.Add(wx.StaticText(Texture,-1,item),0,wx.ALIGN_CENTER_VERTICAL)
2619                ODFval = wx.TextCtrl(Texture,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER)
2620                ODFIndx[ODFval.GetId()] = item
2621                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2622                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2623                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2624            mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2625            mainSizer.Add((0,5),0)
2626        mainSizer.Add((0,5),0)
2627        mainSizer.Add(wx.StaticText(Texture,-1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL)
2628        mainSizer.Add((0,5),0)
2629        angSizer = wx.BoxSizer(wx.HORIZONTAL)
2630        angIndx = {}
2631        valIndx = {}
2632        for item in ['Sample omega','Sample chi','Sample phi']:
2633            angRef = wx.CheckBox(Texture,-1,label=item+': ')
2634            angRef.SetValue(textureData[item][0])
2635            angIndx[angRef.GetId()] = item
2636            angRef.Bind(wx.EVT_CHECKBOX, OnAngRef)
2637            angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL)
2638            angVal = wx.TextCtrl(Texture,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER)
2639            valIndx[angVal.GetId()] = item
2640            angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue)
2641            angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue)
2642            angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL)
2643            angSizer.Add((5,0),0)
2644        mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL)
2645        Texture.SetSizer(mainSizer,True)
2646        mainSizer.Fit(G2frame.dataFrame)
2647        Size = mainSizer.GetMinSize()
2648        Size[0] += 40
2649        Size[1] = max(Size[1],250) + 20
2650        Texture.SetSize(Size)
2651        Texture.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2652        Size[1] = min(Size[1],450)
2653        G2frame.dataFrame.setSizePosLeft(Size)
2654
2655################################################################################
2656##### DData routines
2657################################################################################
2658       
2659    def UpdateDData():
2660        UseList = data['Histograms']
2661        if UseList:
2662            G2frame.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,True)
2663            G2frame.Refine.Enable(True)
2664        else:
2665            G2frame.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,False)
2666            G2frame.Refine.Enable(False)           
2667        generalData = data['General']       
2668        SGData = generalData['SGData']
2669        keyList = UseList.keys()
2670        keyList.sort()
2671        PWDR = any(['PWDR' in item for item in keyList])
2672        Indx = {}
2673       
2674        def PlotSizer():
2675
2676            def OnPlotSel(event):
2677                Obj = event.GetEventObject()
2678                generalData['Data plot type'] = Obj.GetStringSelection()
2679                wx.CallAfter(UpdateDData)
2680                G2plt.PlotSizeStrainPO(G2frame,data)
2681               
2682            def OnPOhkl(event):
2683                Obj = event.GetEventObject()
2684                Saxis = Obj.GetValue().split()
2685                try:
2686                    hkl = [int(Saxis[i]) for i in range(3)]
2687                except (ValueError,IndexError):
2688                    hkl = generalData['POhkl']
2689                if not np.any(np.array(hkl)):
2690                    hkl = generalData['POhkl']
2691                generalData['POhkl'] = hkl
2692                h,k,l = hkl
2693                Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2694                G2plt.PlotSizeStrainPO(G2frame,data)
2695           
2696            plotSizer = wx.BoxSizer(wx.VERTICAL)
2697            choice = ['None','Mustrain','Size','Preferred orientation']
2698            plotSel = wx.RadioBox(DData,-1,'Select plot type:',choices=choice,
2699                majorDimension=2,style=wx.RA_SPECIFY_COLS)
2700            plotSel.SetStringSelection(generalData['Data plot type'])
2701            plotSel.Bind(wx.EVT_RADIOBOX,OnPlotSel)   
2702            plotSizer.Add(plotSel)
2703            if generalData['Data plot type'] == 'Preferred orientation':
2704                POhklSizer = wx.BoxSizer(wx.HORIZONTAL)
2705                POhklSizer.Add(wx.StaticText(DData,-1,' Plot preferred orientation for H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2706                h,k,l = generalData['POhkl']
2707                poAxis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2708                poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOhkl)
2709                poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOhkl)
2710                POhklSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
2711                plotSizer.Add(POhklSizer)           
2712            return plotSizer
2713           
2714        def ScaleSizer():
2715           
2716            def OnScaleRef(event):
2717                Obj = event.GetEventObject()
2718                UseList[Indx[Obj.GetId()]]['Scale'][1] = Obj.GetValue()
2719               
2720            def OnScaleVal(event):
2721                Obj = event.GetEventObject()
2722                try:
2723                    scale = float(Obj.GetValue())
2724                    if scale > 0:
2725                        UseList[Indx[Obj.GetId()]]['Scale'][0] = scale
2726                except ValueError:
2727                    pass
2728                Obj.SetValue("%.4f"%(UseList[Indx[Obj.GetId()]]['Scale'][0]))          #reset in case of error
2729                           
2730            scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
2731            if 'PWDR' in item:
2732                scaleRef = wx.CheckBox(DData,-1,label=' Phase fraction: ')
2733            elif 'HKLF' in item:
2734                scaleRef = wx.CheckBox(DData,-1,label=' Scale factor: ')               
2735            scaleRef.SetValue(UseList[item]['Scale'][1])
2736            Indx[scaleRef.GetId()] = item
2737            scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
2738            scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
2739            scaleVal = wx.TextCtrl(DData,wx.ID_ANY,
2740                '%.4f'%(UseList[item]['Scale'][0]),style=wx.TE_PROCESS_ENTER)
2741            Indx[scaleVal.GetId()] = item
2742            scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
2743            scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
2744            scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
2745            return scaleSizer
2746           
2747        def OnShowData(event):
2748            Obj = event.GetEventObject()
2749            hist = Indx[Obj.GetId()]
2750            UseList[hist]['Show'] = Obj.GetValue()
2751            wx.CallAfter(UpdateDData)
2752            G2plt.PlotSizeStrainPO(G2frame,data)
2753           
2754        def OnCopyData(event):
2755            #how about HKLF data? This is only for PWDR data
2756            Obj = event.GetEventObject()
2757            hist = Indx[Obj.GetId()]
2758            sourceDict = UseList[hist]
2759            copyNames = ['Scale','Pref.Ori.','Size','Mustrain','HStrain','Extinction']
2760            copyDict = {}
2761            for name in copyNames: 
2762                copyDict[name] = copy.deepcopy(sourceDict[name])        #force copy
2763            keyList = ['All',]+UseList.keys()
2764            if UseList:
2765                copyList = []
2766                dlg = wx.MultiChoiceDialog(G2frame, 
2767                    'Copy parameters to which histograms?', 'Copy parameters', 
2768                    keyList, wx.CHOICEDLG_STYLE)
2769                try:
2770                    if dlg.ShowModal() == wx.ID_OK:
2771                        result = dlg.GetSelections()
2772                        for i in result: 
2773                            copyList.append(keyList[i])
2774                        if 'All' in copyList: 
2775                            copyList = keyList[1:]
2776                        for item in copyList:
2777                            UseList[item].update(copy.deepcopy(copyDict))
2778                        wx.CallAfter(UpdateDData)
2779                finally:
2780                    dlg.Destroy()
2781                   
2782        def OnCopyFlags(event):
2783            Obj = event.GetEventObject()
2784            hist = Indx[Obj.GetId()]
2785            sourceDict = UseList[hist]
2786            copyDict = {}
2787            copyNames = ['Scale','Pref.Ori.','Size','Mustrain','HStrain','Extinction']
2788            for name in copyNames:
2789                if name in ['Scale','Extinction','HStrain']:
2790                    copyDict[name] = sourceDict[name][1]
2791                elif name in ['Size','Mustrain']:
2792                    copyDict[name] = [sourceDict[name][0],sourceDict[name][2],sourceDict[name][4]]
2793                elif name == 'Pref.Ori.':
2794                    copyDict[name] = [sourceDict[name][0],sourceDict[name][2]]
2795                    if sourceDict[name][0] == 'SH':
2796                        SHterms = sourceDict[name][5]
2797                        SHflags = {}
2798                        for item in SHterms:
2799                            SHflags[item] = SHterms[item][1]
2800                        copyDict[name].append(SHflags)                       
2801            keyList = ['All',]+UseList.keys()
2802            if UseList:
2803                copyList = []
2804                dlg = wx.MultiChoiceDialog(G2frame, 
2805                    'Copy parameters to which histograms?', 'Copy parameters', 
2806                    keyList, wx.CHOICEDLG_STYLE)
2807                try:
2808                    if dlg.ShowModal() == wx.ID_OK:
2809                        result = dlg.GetSelections()
2810                        for i in result: 
2811                            copyList.append(keyList[i])
2812                        if 'All' in copyList: 
2813                            copyList = keyList[1:]
2814                        for item in copyList:
2815                            UseList[item]                           
2816                            for name in copyNames:
2817                                if name in ['Scale','Extinction','HStrain']:
2818                                    UseList[item][name][1] = copy.copy(copyDict[name])
2819                                elif name in ['Size','Mustrain']:
2820                                    UseList[item][name][0] = copy.copy(copyDict[name][0])
2821                                    UseList[item][name][2] = copy.copy(copyDict[name][1])
2822                                    UseList[item][name][4] = copy.copy(copyDict[name][2])
2823                                elif name == 'Pref.Ori.':
2824                                    UseList[item][name][0] = copy.copy(copyDict[name][0])
2825                                    UseList[item][name][2] = copy.copy(copyDict[name][1])
2826                                    if sourceDict[name][0] == 'SH':
2827                                        SHflags = copy.copy(copyDict[name][2])
2828                                        SHterms = copy.copy(sourceDict[name][5])
2829                                        for item in SHflags:
2830                                            SHterms[item][1] = copy.copy(SHflags[item])                                             
2831                        wx.CallAfter(UpdateDData)
2832                finally:
2833                    dlg.Destroy()
2834           
2835           
2836        def OnLGmixRef(event):
2837            Obj = event.GetEventObject()
2838            hist,name = Indx[Obj.GetId()]
2839            UseList[hist][name][2][2] = Obj.GetValue()
2840           
2841        def OnLGmixVal(event):
2842            Obj = event.GetEventObject()
2843            hist,name = Indx[Obj.GetId()]
2844            try:
2845                value = float(Obj.GetValue())
2846                if 0.1 <= value <= 1:
2847                    UseList[hist][name][1][2] = value
2848                else:
2849                    raise ValueError
2850            except ValueError:
2851                pass
2852            Obj.SetValue("%.4f"%(UseList[hist][name][1][2]))          #reset in case of error
2853
2854        def OnSizeType(event):
2855            Obj = event.GetEventObject()
2856            hist = Indx[Obj.GetId()]
2857            UseList[hist]['Size'][0] = Obj.GetValue()
2858            G2plt.PlotSizeStrainPO(G2frame,data)
2859            wx.CallAfter(UpdateDData)
2860           
2861        def OnSizeRef(event):
2862            Obj = event.GetEventObject()
2863            hist,pid = Indx[Obj.GetId()]
2864            if UseList[hist]['Size'][0] == 'ellipsoidal':
2865                UseList[hist]['Size'][5][pid] = Obj.GetValue()               
2866            else:
2867                UseList[hist]['Size'][2][pid] = Obj.GetValue()
2868           
2869        def OnSizeVal(event):
2870            Obj = event.GetEventObject()
2871            hist,pid = Indx[Obj.GetId()]
2872            if UseList[hist]['Size'][0] == 'ellipsoidal':
2873                try:
2874                    size = float(Obj.GetValue())
2875                    if pid < 3 and size <= 0.001:            #10A lower limit!
2876                        raise ValueError
2877                    UseList[hist]['Size'][4][pid] = size                   
2878                except ValueError:
2879                    pass
2880                Obj.SetValue("%.3f"%(UseList[hist]['Size'][4][pid]))          #reset in case of error
2881            else:
2882                try:
2883                    size = float(Obj.GetValue())
2884                    if size <= 0.001:            #10A lower limit!
2885                        raise ValueError
2886                    UseList[hist]['Size'][1][pid] = size
2887                except ValueError:
2888                    pass
2889                Obj.SetValue("%.3f"%(UseList[hist]['Size'][1][pid]))          #reset in case of error
2890            G2plt.PlotSizeStrainPO(G2frame,data)
2891           
2892        def OnSizeAxis(event):           
2893            Obj = event.GetEventObject()
2894            hist = Indx[Obj.GetId()]
2895            Saxis = Obj.GetValue().split()
2896            try:
2897                hkl = [int(Saxis[i]) for i in range(3)]
2898            except (ValueError,IndexError):
2899                hkl = UseList[hist]['Size'][3]
2900            if not np.any(np.array(hkl)):
2901                hkl = UseList[hist]['Size'][3]
2902            UseList[hist]['Size'][3] = hkl
2903            h,k,l = hkl
2904            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2905                       
2906        def OnStrainType(event):
2907            Obj = event.GetEventObject()
2908            hist = Indx[Obj.GetId()]
2909            UseList[hist]['Mustrain'][0] = Obj.GetValue()
2910            wx.CallAfter(UpdateDData)
2911            G2plt.PlotSizeStrainPO(G2frame,data)
2912           
2913        def OnStrainRef(event):
2914            Obj = event.GetEventObject()
2915            hist,pid = Indx[Obj.GetId()]
2916            if UseList[hist]['Mustrain'][0] == 'generalized':
2917                UseList[hist]['Mustrain'][5][pid] = Obj.GetValue()
2918            else:
2919                UseList[hist]['Mustrain'][2][pid] = Obj.GetValue()
2920           
2921        def OnStrainVal(event):
2922            Snames = G2spc.MustrainNames(SGData)
2923            Obj = event.GetEventObject()
2924            hist,pid = Indx[Obj.GetId()]
2925            try:
2926                strain = float(Obj.GetValue())
2927                if UseList[hist]['Mustrain'][0] == 'generalized':
2928                    if '4' in Snames[pid] and strain < 0:
2929                        raise ValueError
2930                    UseList[hist]['Mustrain'][4][pid] = strain
2931                else:
2932                    if strain <= 0:
2933                        raise ValueError
2934                    UseList[hist]['Mustrain'][1][pid] = strain
2935            except ValueError:
2936                pass
2937            if UseList[hist]['Mustrain'][0] == 'generalized':
2938                Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][4][pid]))          #reset in case of error
2939            else:
2940                Obj.SetValue("%.1f"%(UseList[hist]['Mustrain'][1][pid]))          #reset in case of error
2941            G2plt.PlotSizeStrainPO(G2frame,data)
2942           
2943        def OnStrainAxis(event):
2944            Obj = event.GetEventObject()
2945            hist = Indx[Obj.GetId()]
2946            Saxis = Obj.GetValue().split()
2947            try:
2948                hkl = [int(Saxis[i]) for i in range(3)]
2949            except (ValueError,IndexError):
2950                hkl = UseList[hist]['Mustrain'][3]
2951            if not np.any(np.array(hkl)):
2952                hkl = UseList[hist]['Mustrain'][3]
2953            UseList[hist]['Mustrain'][3] = hkl
2954            h,k,l = hkl
2955            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2956            G2plt.PlotSizeStrainPO(G2frame,data)
2957           
2958        def OnHstrainRef(event):
2959            Obj = event.GetEventObject()
2960            hist,pid = Indx[Obj.GetId()]
2961            UseList[hist]['HStrain'][1][pid] = Obj.GetValue()
2962           
2963        def OnHstrainVal(event):
2964            Snames = G2spc.HStrainNames(SGData)
2965            Obj = event.GetEventObject()
2966            hist,pid = Indx[Obj.GetId()]
2967            try:
2968                strain = float(Obj.GetValue())
2969                UseList[hist]['HStrain'][0][pid] = strain
2970            except ValueError:
2971                pass
2972            Obj.SetValue("%.5f"%(UseList[hist]['HStrain'][0][pid]))          #reset in case of error
2973
2974        def OnPOVal(event):
2975            Obj = event.GetEventObject()
2976            hist = Indx[Obj.GetId()]
2977            try:
2978                mdVal = float(Obj.GetValue())
2979                if mdVal > 0:
2980                    UseList[hist]['Pref.Ori.'][1] = mdVal
2981            except ValueError:
2982                pass
2983            Obj.SetValue("%.3f"%(UseList[hist]['Pref.Ori.'][1]))          #reset in case of error
2984           
2985        def OnPOAxis(event):
2986            Obj = event.GetEventObject()
2987            hist = Indx[Obj.GetId()]
2988            Saxis = Obj.GetValue().split()
2989            try:
2990                hkl = [int(Saxis[i]) for i in range(3)]
2991            except (ValueError,IndexError):
2992                hkl = UseList[hist]['Pref.Ori.'][3]
2993            if not np.any(np.array(hkl)):
2994                hkl = UseList[hist]['Pref.Ori.'][3]
2995            UseList[hist]['Pref.Ori.'][3] = hkl
2996            h,k,l = hkl
2997            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2998           
2999        def OnPOOrder(event):
3000            Obj = event.GetEventObject()
3001            hist = Indx[Obj.GetId()]
3002            Order = int(Obj.GetValue())
3003            UseList[hist]['Pref.Ori.'][4] = Order
3004            UseList[hist]['Pref.Ori.'][5] = SetPOCoef(Order,hist)
3005            wx.CallAfter(UpdateDData)
3006
3007        def OnPOType(event):
3008            Obj = event.GetEventObject()
3009            hist = Indx[Obj.GetId()]
3010            if 'March' in Obj.GetValue():
3011                UseList[hist]['Pref.Ori.'][0] = 'MD'
3012            else:
3013                UseList[hist]['Pref.Ori.'][0] = 'SH'
3014            wx.CallAfter(UpdateDData)           
3015   
3016        def OnPORef(event):
3017            Obj = event.GetEventObject()
3018            hist = Indx[Obj.GetId()]
3019            UseList[hist]['Pref.Ori.'][2] = Obj.GetValue()
3020               
3021        def SetPOCoef(Order,hist):
3022            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',Order,False)     #cylindrical & no M
3023            newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
3024            POCoeff = UseList[hist]['Pref.Ori.'][5]
3025            for cofName in POCoeff:
3026                if cofName in  cofNames:
3027                    newPOCoef[cofName] = POCoeff[cofName]
3028            return newPOCoef
3029       
3030        def OnExtRef(event):
3031            Obj = event.GetEventObject()
3032            UseList[Indx[Obj.GetId()]]['Extinction'][1] = Obj.GetValue()
3033           
3034        def OnExtVal(event):
3035            Obj = event.GetEventObject()
3036            try:
3037                ext = float(Obj.GetValue())
3038                if ext >= 0:
3039                    UseList[Indx[Obj.GetId()]]['Extinction'][0] = ext
3040            except ValueError:
3041                pass
3042            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][0]))
3043           
3044        def OnTbarVal(event):
3045            Obj = event.GetEventObject()
3046            try:
3047                tbar = float(Obj.GetValue())
3048                if tbar >= 0:
3049                    UseList[Indx[Obj.GetId()]]['Extinction'][2]['Tbar'] = tbar
3050            except ValueError:
3051                pass
3052            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][2]['Tbar']))
3053           
3054        def OnEval(event):
3055            Obj = event.GetEventObject()
3056            item = Indx[Obj.GetId()]
3057            try:
3058                val = float(Obj.GetValue())
3059                if val >= 0:
3060                    UseList[item[0]]['Extinction'][2][item[1]][0] = val
3061            except ValueError:
3062                pass
3063            Obj.SetValue("%9.3g"%(UseList[item[0]]['Extinction'][2][item[1]][0]))
3064           
3065        def OnEref(event):
3066            Obj = event.GetEventObject()
3067            item = Indx[Obj.GetId()]
3068            UseList[item[0]]['Extinction'][2][item[1]][1] = Obj.GetValue()
3069
3070        def OnSCExtType(event):
3071            Obj = event.GetEventObject()
3072            item = Indx[Obj.GetId()]
3073            UseList[item[0]]['Extinction'][item[1]] = Obj.GetValue()
3074            wx.CallAfter(UpdateDData)
3075               
3076        def checkAxis(axis):
3077            if not np.any(np.array(axis)):
3078                return False
3079            return axis
3080           
3081        def TopSizer(name,choices,parm,OnType):
3082            topSizer = wx.BoxSizer(wx.HORIZONTAL)
3083            topSizer.Add(wx.StaticText(DData,-1,name),0,wx.ALIGN_CENTER_VERTICAL)
3084            sizeType = wx.ComboBox(DData,wx.ID_ANY,value=UseList[item][parm][0],choices=choices,
3085                style=wx.CB_READONLY|wx.CB_DROPDOWN)
3086            sizeType.Bind(wx.EVT_COMBOBOX, OnType)
3087            Indx[sizeType.GetId()] = item
3088            topSizer.Add(sizeType)
3089            topSizer.Add((5,0),0)
3090            return topSizer
3091           
3092        def LGmixSizer(name,OnVal,OnRef):
3093            lgmixSizer = wx.BoxSizer(wx.HORIZONTAL)
3094            lgmixRef = wx.CheckBox(DData,-1,label='LGmix')
3095            lgmixRef.thisown = False
3096            lgmixRef.SetValue(UseList[item][name][2][2])
3097            Indx[lgmixRef.GetId()] = [item,name]
3098            lgmixRef.Bind(wx.EVT_CHECKBOX, OnRef)
3099            lgmixSizer.Add(lgmixRef,0,wx.ALIGN_CENTER_VERTICAL)
3100            lgmixVal = wx.TextCtrl(DData,wx.ID_ANY,
3101                '%.4f'%(UseList[item][name][1][2]),style=wx.TE_PROCESS_ENTER)
3102            Indx[lgmixVal.GetId()] = [item,name]
3103            lgmixVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
3104            lgmixVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
3105            lgmixSizer.Add(lgmixVal,0,wx.ALIGN_CENTER_VERTICAL)
3106            return lgmixSizer
3107                       
3108        def IsoSizer(name,parm,fmt,OnVal,OnRef):
3109            isoSizer = wx.BoxSizer(wx.HORIZONTAL)
3110            sizeRef = wx.CheckBox(DData,-1,label=name)
3111            sizeRef.thisown = False
3112            sizeRef.SetValue(UseList[item][parm][2][0])
3113            Indx[sizeRef.GetId()] = [item,0]
3114            sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
3115            isoSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
3116            sizeVal = wx.TextCtrl(DData,wx.ID_ANY,
3117                fmt%(UseList[item][parm][1][0]),style=wx.TE_PROCESS_ENTER)
3118            Indx[sizeVal.GetId()] = [item,0]
3119            sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
3120            sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
3121            isoSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
3122            return isoSizer
3123           
3124        def UniSizer(parm,OnAxis):
3125            uniSizer = wx.BoxSizer(wx.HORIZONTAL)
3126            uniSizer.Add(wx.StaticText(DData,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
3127            h,k,l = UseList[item][parm][3]
3128            Axis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
3129            Indx[Axis.GetId()] = item
3130            Axis.Bind(wx.EVT_TEXT_ENTER,OnAxis)
3131            Axis.Bind(wx.EVT_KILL_FOCUS,OnAxis)
3132            uniSizer.Add(Axis,0,wx.ALIGN_CENTER_VERTICAL)
3133            return uniSizer
3134           
3135        def UniDataSizer(parmName,parm,fmt,OnVal,OnRef):
3136            dataSizer = wx.BoxSizer(wx.HORIZONTAL)
3137            parms = zip([' Equatorial '+parmName,' Axial '+parmName],
3138                UseList[item][parm][1],UseList[item][parm][2],range(2))
3139            for Pa,val,ref,id in parms:
3140                sizeRef = wx.CheckBox(DData,-1,label=Pa)
3141                sizeRef.thisown = False
3142                sizeRef.SetValue(ref)
3143                Indx[sizeRef.GetId()] = [item,id]
3144                sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
3145                dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
3146                sizeVal = wx.TextCtrl(DData,wx.ID_ANY,fmt%(val),style=wx.TE_PROCESS_ENTER)
3147                Indx[sizeVal.GetId()] = [item,id]
3148                sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
3149                sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
3150                dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
3151                dataSizer.Add((5,0),0)
3152            return dataSizer
3153           
3154        def EllSizeDataSizer():
3155            parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[item]['Size'][4],
3156                UseList[item]['Size'][5],range(6))
3157            dataSizer = wx.FlexGridSizer(1,6,5,5)
3158            for Pa,val,ref,id in parms:
3159                sizeRef = wx.CheckBox(DData,-1,label=Pa)
3160                sizeRef.thisown = False
3161                sizeRef.SetValue(ref)
3162                Indx[sizeRef.GetId()] = [item,id]
3163                sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
3164                dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
3165                sizeVal = wx.TextCtrl(DData,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER)
3166                Indx[sizeVal.GetId()] = [item,id]
3167                sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
3168                sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
3169                dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
3170            return dataSizer
3171           
3172        def GenStrainDataSizer():
3173            Snames = G2spc.MustrainNames(SGData)
3174            numb = len(Snames)
3175            if len(UseList[item]['Mustrain'][4]) < numb:
3176                UseList[item]['Mustrain'][4] = numb*[0.0,]
3177                UseList[item]['Mustrain'][5] = numb*[False,]
3178            parms = zip(Snames,UseList[item]['Mustrain'][4],UseList[item]['Mustrain'][5],range(numb))
3179            dataSizer = wx.FlexGridSizer(1,6,5,5)
3180            for Pa,val,ref,id in parms:
3181                strainRef = wx.CheckBox(DData,-1,label=Pa)
3182                strainRef.thisown = False
3183                strainRef.SetValue(ref)
3184                Indx[strainRef.GetId()] = [item,id]
3185                strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
3186                dataSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
3187                strainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
3188                Indx[strainVal.GetId()] = [item,id]
3189                strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
3190                strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
3191                dataSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
3192            return dataSizer
3193           
3194        def HstrainSizer():
3195            hstrainSizer = wx.FlexGridSizer(1,6,5,5)
3196            Hsnames = G2spc.HStrainNames(SGData)
3197            parms = zip(Hsnames,UseList[item]['HStrain'][0],UseList[item]['HStrain'][1],range(len(Hsnames)))
3198            for Pa,val,ref,id in parms:
3199                hstrainRef = wx.CheckBox(DData,-1,label=Pa)
3200                hstrainRef.thisown = False
3201                hstrainRef.SetValue(ref)
3202                Indx[hstrainRef.GetId()] = [item,id]
3203                hstrainRef.Bind(wx.EVT_CHECKBOX, OnHstrainRef)
3204                hstrainSizer.Add(hstrainRef,0,wx.ALIGN_CENTER_VERTICAL)
3205                hstrainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
3206                Indx[hstrainVal.GetId()] = [item,id]
3207                hstrainVal.Bind(wx.EVT_TEXT_ENTER,OnHstrainVal)
3208                hstrainVal.Bind(wx.EVT_KILL_FOCUS,OnHstrainVal)
3209                hstrainSizer.Add(hstrainVal,0,wx.ALIGN_CENTER_VERTICAL)
3210            return hstrainSizer
3211           
3212        def PoTopSizer(POData):
3213            poSizer = wx.FlexGridSizer(1,6,5,5)
3214            choice = ['March-Dollase','Spherical harmonics']
3215            POtype = choice[['MD','SH'].index(POData[0])]
3216            poSizer.Add(wx.StaticText(DData,-1,' Preferred orientation model '),0,wx.ALIGN_CENTER_VERTICAL)
3217            POType = wx.ComboBox(DData,wx.ID_ANY,value=POtype,choices=choice,
3218                style=wx.CB_READONLY|wx.CB_DROPDOWN)
3219            Indx[POType.GetId()] = item
3220            POType.Bind(wx.EVT_COMBOBOX, OnPOType)
3221            poSizer.Add(POType)
3222            if POData[0] == 'SH':
3223                poSizer.Add(wx.StaticText(DData,-1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
3224                poOrder = wx.ComboBox(DData,wx.ID_ANY,value=str(POData[4]),choices=[str(2*i) for i in range(18)],
3225                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
3226                Indx[poOrder.GetId()] = item
3227                poOrder.Bind(wx.EVT_COMBOBOX,OnPOOrder)
3228                poSizer.Add(poOrder,0,wx.ALIGN_CENTER_VERTICAL)
3229                poRef = wx.CheckBox(DData,-1,label=' Refine? ')
3230                poRef.SetValue(POData[2])
3231                Indx[poRef.GetId()] = item
3232                poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
3233                poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
3234            return poSizer
3235           
3236        def MDDataSizer(POData):
3237            poSizer = wx.BoxSizer(wx.HORIZONTAL)
3238            poRef = wx.CheckBox(DData,-1,label=' March-Dollase ratio: ')
3239            poRef.SetValue(POData[2])
3240            Indx[poRef.GetId()] = item
3241            poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
3242            poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
3243            poVal = wx.TextCtrl(DData,wx.ID_ANY,
3244                '%.3f'%(POData[1]),style=wx.TE_PROCESS_ENTER)
3245            Indx[poVal.GetId()] = item
3246            poVal.Bind(wx.EVT_TEXT_ENTER,OnPOVal)
3247            poVal.Bind(wx.EVT_KILL_FOCUS,OnPOVal)
3248            poSizer.Add(poVal,0,wx.ALIGN_CENTER_VERTICAL)
3249            poSizer.Add(wx.StaticText(DData,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
3250            h,k,l =POData[3]
3251            poAxis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
3252            Indx[poAxis.GetId()] = item
3253            poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOAxis)
3254            poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOAxis)
3255            poSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
3256            return poSizer
3257           
3258        def SHDataSizer(POData):
3259            textJ = G2lat.textureIndex(POData[5])
3260            mainSizer.Add(wx.StaticText(DData,-1,' Spherical harmonic coefficients: '+'Texture index: %.3f'%(textJ)),0,wx.ALIGN_CENTER_VERTICAL)
3261            mainSizer.Add((0,5),0)
3262            ODFSizer = wx.FlexGridSizer(2,8,2,2)
3263            ODFIndx = {}
3264            ODFkeys = POData[5].keys()
3265            ODFkeys.sort()
3266            for odf in ODFkeys:
3267                ODFSizer.Add(wx.StaticText(DData,-1,odf),0,wx.ALIGN_CENTER_VERTICAL)
3268                ODFval = wx.TextCtrl(DData,wx.ID_ANY,'%8.3f'%(POData[5][odf]),style=wx.TE_PROCESS_ENTER)
3269                ODFIndx[ODFval.GetId()] = odf
3270#                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
3271#                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
3272                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
3273            return ODFSizer
3274           
3275        def ExtSizer():           
3276            extSizer = wx.BoxSizer(wx.HORIZONTAL)
3277            extRef = wx.CheckBox(DData,-1,label=' Extinction: ')
3278            extRef.SetValue(UseList[item]['Extinction'][1])
3279            Indx[extRef.GetId()] = item
3280            extRef.Bind(wx.EVT_CHECKBOX, OnExtRef)
3281            extSizer.Add(extRef,0,wx.ALIGN_CENTER_VERTICAL)
3282            extVal = wx.TextCtrl(DData,wx.ID_ANY,
3283                '%.2f'%(UseList[item]['Extinction'][0]),style=wx.TE_PROCESS_ENTER)
3284            Indx[extVal.GetId()] = item
3285            extVal.Bind(wx.EVT_TEXT_ENTER,OnExtVal)
3286            extVal.Bind(wx.EVT_KILL_FOCUS,OnExtVal)
3287            extSizer.Add(extVal,0,wx.ALIGN_CENTER_VERTICAL)
3288            return extSizer
3289       
3290        def SCExtSizer():
3291            extSizer = wx.BoxSizer(wx.VERTICAL)
3292            typeSizer = wx.BoxSizer(wx.HORIZONTAL)           
3293            typeSizer.Add(wx.StaticText(DData,-1,' Extinction type: '),0,wx.ALIGN_CENTER_VERTICAL)
3294            Choices = ['Primary','Secondary Type I','Secondary Type II','Secondary Type I & II']
3295            typeTxt = wx.ComboBox(DData,-1,choices=Choices,value=UseList[item]['Extinction'][1],
3296                style=wx.CB_READONLY|wx.CB_DROPDOWN)
3297            Indx[typeTxt.GetId()] = [item,1]
3298            typeTxt.Bind(wx.EVT_COMBOBOX,OnSCExtType)
3299            typeSizer.Add(typeTxt)
3300            typeSizer.Add(wx.StaticText(DData,-1,' Approx: '),0,wx.ALIGN_CENTER_VERTICAL)
3301            Choices=['Lorentzian','Gaussian']
3302            approxTxT = wx.ComboBox(DData,-1,choices=Choices,value=UseList[item]['Extinction'][0],
3303                style=wx.CB_READONLY|wx.CB_DROPDOWN)
3304            Indx[approxTxT.GetId()] = [item,0]
3305            approxTxT.Bind(wx.EVT_COMBOBOX,OnSCExtType)
3306            typeSizer.Add(approxTxT)
3307            extSizer.Add(typeSizer,0,wx.ALIGN_CENTER_VERTICAL)
3308            extSizer.Add((0,5),)
3309            valSizer =wx.BoxSizer(wx.HORIZONTAL)
3310            valSizer.Add(wx.StaticText(DData,-1,' Tbar(mm):'),0,wx.ALIGN_CENTER_VERTICAL)
3311            tbarVal = wx.TextCtrl(DData,wx.ID_ANY,
3312                '%.3f'%(UseList[item]['Extinction'][2]['Tbar']),style=wx.TE_PROCESS_ENTER)
3313            Indx[tbarVal.GetId()] = item
3314            tbarVal.Bind(wx.EVT_TEXT_ENTER,OnTbarVal)
3315            tbarVal.Bind(wx.EVT_KILL_FOCUS,OnTbarVal)
3316            valSizer.Add(tbarVal,0,wx.ALIGN_CENTER_VERTICAL)
3317            if 'Primary' in UseList[item]['Extinction'][1]:
3318                Ekey = ['Ep',]
3319            elif 'Secondary Type II' == UseList[item]['Extinction'][1]:
3320                Ekey = ['Es',]
3321            elif 'Secondary Type I' == UseList[item]['Extinction'][1]:
3322                Ekey = ['Eg',]
3323            else:
3324                Ekey = ['Eg','Es']
3325            for ekey in Ekey:
3326                Eref = wx.CheckBox(DData,-1,label=ekey+' : ')
3327                Eref.SetValue(UseList[item]['Extinction'][2][ekey][1])
3328                Indx[Eref.GetId()] = [item,ekey]
3329                Eref.Bind(wx.EVT_CHECKBOX, OnEref)
3330                valSizer.Add(Eref,0,wx.ALIGN_CENTER_VERTICAL)
3331                Eval = wx.TextCtrl(DData,wx.ID_ANY,
3332                    '%9.3g'%(UseList[item]['Extinction'][2][ekey][0]),style=wx.TE_PROCESS_ENTER)
3333                Indx[Eval.GetId()] = [item,ekey]
3334                Eval.Bind(wx.EVT_TEXT_ENTER,OnEval)
3335                Eval.Bind(wx.EVT_KILL_FOCUS,OnEval)
3336                valSizer.Add(Eval,0,wx.ALIGN_CENTER_VERTICAL)
3337
3338            extSizer.Add(valSizer,0,wx.ALIGN_CENTER_VERTICAL)
3339            return extSizer
3340           
3341        if DData.GetSizer():
3342            DData.GetSizer().Clear(True)
3343        mainSizer = wx.BoxSizer(wx.VERTICAL)
3344        mainSizer.Add(wx.StaticText(DData,-1,'Histogram data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
3345        if PWDR:
3346            mainSizer.Add(PlotSizer())           
3347           
3348        for item in keyList:
3349            histData = UseList[item]
3350            showSizer = wx.BoxSizer(wx.HORIZONTAL)
3351            showData = wx.CheckBox(DData,-1,label=' Show '+item)
3352            showData.SetValue(UseList[item]['Show'])
3353            Indx[showData.GetId()] = item
3354            showData.Bind(wx.EVT_CHECKBOX, OnShowData)
3355            showSizer.Add(showData,0,wx.ALIGN_CENTER_VERTICAL)
3356            copyData = wx.Button(DData,-1,label=' Copy?')
3357            Indx[copyData.GetId()] = item
3358            copyData.Bind(wx.EVT_BUTTON,OnCopyData)
3359            showSizer.Add(copyData,wx.ALIGN_CENTER_VERTICAL)
3360            copyFlags = wx.Button(DData,-1,label=' Copy flags?')
3361            Indx[copyFlags.GetId()] = item
3362            copyFlags.Bind(wx.EVT_BUTTON,OnCopyFlags)
3363            showSizer.Add(copyFlags,wx.ALIGN_CENTER_VERTICAL)
3364            mainSizer.Add((5,5),0)
3365            mainSizer.Add(showSizer,0,wx.ALIGN_CENTER_VERTICAL)
3366            mainSizer.Add((0,5),0)
3367           
3368            if UseList[item]['Show']:
3369                mainSizer.Add(ScaleSizer())
3370                mainSizer.Add((0,5),0)
3371               
3372            if item[:4] == 'PWDR' and UseList[item]['Show']:
3373                if UseList[item]['Size'][0] == 'isotropic':
3374                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
3375                    isoSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
3376                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
3377                    isoSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef))
3378                    mainSizer.Add(isoSizer)
3379                    mainSizer.Add(IsoSizer(u' Cryst. size(\xb5m): ','Size','%.3f',
3380                        OnSizeVal,OnSizeRef),0,wx.ALIGN_CENTER_VERTICAL)
3381                elif UseList[item]['Size'][0] == 'uniaxial':
3382                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
3383                    uniSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
3384                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
3385                    uniSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef))
3386                    uniSizer.Add(UniSizer('Size',OnSizeAxis),0,wx.ALIGN_CENTER_VERTICAL)
3387                    mainSizer.Add(uniSizer)
3388                    mainSizer.Add(UniDataSizer(u'size(\xb5m): ','Size','%.3f',OnSizeVal,OnSizeRef))
3389                elif UseList[item]['Size'][0] == 'ellipsoidal':
3390                    ellSizer = wx.BoxSizer(wx.HORIZONTAL)
3391                    ellSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
3392                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
3393                    ellSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef))
3394                    mainSizer.Add(ellSizer)
3395                    mainSizer.Add(EllSizeDataSizer())
3396                mainSizer.Add((0,5),0)                   
3397               
3398                if UseList[item]['Mustrain'][0] == 'isotropic':
3399                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
3400                    isoSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
3401                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
3402                    isoSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef))
3403                    mainSizer.Add(isoSizer)
3404                    mainSizer.Add(IsoSizer(' microstrain: ','Mustrain','%.1f',
3405                        OnStrainVal,OnStrainRef),0,wx.ALIGN_CENTER_VERTICAL)                   
3406                    mainSizer.Add((0,5),0)
3407                elif UseList[item]['Mustrain'][0] == 'uniaxial':
3408                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
3409                    uniSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
3410                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
3411                    uniSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef))
3412                    uniSizer.Add(UniSizer('Mustrain',OnStrainAxis),0,wx.ALIGN_CENTER_VERTICAL)
3413                    mainSizer.Add(uniSizer)
3414                    mainSizer.Add(UniDataSizer('mustrain: ','Mustrain','%.1f',OnStrainVal,OnStrainRef))
3415                elif UseList[item]['Mustrain'][0] == 'generalized':
3416                    genSizer = wx.BoxSizer(wx.HORIZONTAL)
3417                    genSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
3418                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
3419                    genSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef))
3420                    mainSizer.Add(genSizer)
3421                    mainSizer.Add(GenStrainDataSizer())                       
3422                mainSizer.Add((0,5),0)
3423               
3424                mainSizer.Add(wx.StaticText(DData,-1,' Hydrostatic/elastic strain:'))
3425                mainSizer.Add(HstrainSizer())
3426                   
3427                #texture  'Pref. Ori.':['MD',1.0,False,[0,0,1],0,[]] last two for 'SH' are SHorder & coeff
3428                poSizer = wx.BoxSizer(wx.VERTICAL)
3429                POData = UseList[item]['Pref.Ori.']
3430                poSizer.Add(PoTopSizer(POData))
3431                if POData[0] == 'MD':
3432                    poSizer.Add(MDDataSizer(POData))
3433                else:           #'SH'
3434                    if POData[4]:       #SH order > 0
3435                        poSizer.Add(SHDataSizer(POData))
3436                       
3437                mainSizer.Add(poSizer)
3438                mainSizer.Add((0,5),0)               
3439                #Extinction  'Extinction':[0.0,False]
3440                mainSizer.Add(ExtSizer())
3441                mainSizer.Add((0,5),0)
3442            elif item[:4] == 'HKLF' and UseList[item]['Show']:
3443                mainSizer.Add((0,5),0)               
3444                mainSizer.Add(SCExtSizer())
3445                mainSizer.Add((0,5),0)
3446                pass
3447        mainSizer.Add((5,5),0)
3448
3449        DData.SetSizer(mainSizer,True)
3450        mainSizer.FitInside(G2frame.dataFrame)
3451        Size = mainSizer.GetMinSize()
3452        Size[0] += 40
3453        Size[1] = max(Size[1],290) + 20
3454        DData.SetSize(Size)
3455        DData.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
3456        Size[1] = min(Size[1],450)
3457        G2frame.dataFrame.setSizePosLeft(Size)
3458       
3459    def OnHklfAdd(event):
3460        UseList = data['Histograms']
3461        keyList = UseList.keys()
3462        TextList = []
3463        if G2frame.PatternTree.GetCount():
3464            item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
3465            while item:
3466                name = G2frame.PatternTree.GetItemText(item)
3467                if name not in keyList and 'HKLF' in name:
3468                    TextList.append(name)
3469                item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)                       
3470            dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
3471            try:
3472                if dlg.ShowModal() == wx.ID_OK:
3473                    result = dlg.GetSelections()
3474                    for i in result:
3475                        histoName = TextList[i]
3476                        UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
3477                            'Extinction':['Lorentzian','Secondary Type I',
3478                            {'Tbar':0.0,'Eg':[0.0,False],'Es':[0.0,False],'Ep':[0.0,False]},]}                       
3479                    data['Histograms'] = UseList
3480                    wx.BeginBusyCursor()
3481                    UpdateHKLFdata(histoName)
3482                    wx.EndBusyCursor()
3483                    wx.CallAfter(UpdateDData)
3484            finally:
3485                dlg.Destroy()
3486               
3487    def UpdateHKLFdata(histoName):
3488        generalData = data['General']
3489        Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName)
3490        reflData = G2frame.PatternTree.GetItemPyData(Id)[1]
3491        SGData = generalData['SGData']
3492        Cell = generalData['Cell'][1:7]
3493        G,g = G2lat.cell2Gmat(Cell)
3494        for ref in reflData:
3495            H = ref[:3]
3496            ref[4] = np.sqrt(1./G2lat.calc_rDsq2(H,G))
3497            iabsnt,ref[3],ref[11],ref[12] = G2spc.GenHKLf(H,SGData)
3498        G2frame.PatternTree.SetItemPyData(Id,[histoName,reflData])
3499       
3500    def OnPwdrAdd(event):
3501        generalData = data['General']
3502        SGData = generalData['SGData']
3503        UseList = data['Histograms']
3504        newList = []
3505        NShkl = len(G2spc.MustrainNames(SGData))
3506        NDij = len(G2spc.HStrainNames(SGData))
3507        keyList = UseList.keys()
3508        TextList = ['All PWDR']
3509        if G2frame.PatternTree.GetCount():
3510            item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
3511            while item:
3512                name = G2frame.PatternTree.GetItemText(item)
3513                if name not in keyList and 'PWDR' in name:
3514                    TextList.append(name)
3515                item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
3516            dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
3517            try:
3518                if dlg.ShowModal() == wx.ID_OK:
3519                    result = dlg.GetSelections()
3520                    for i in result: newList.append(TextList[i])
3521                    if 'All PWDR' in newList:
3522                        newList = TextList[1:]
3523                    for histoName in newList:
3524                        pId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName)
3525                        UseList[histoName] = {'Histogram':histoName,'Show':False,
3526                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{}],
3527                            'Size':['isotropic',[4.,4.,1.0],[False,False,False],[0,0,1],
3528                                [4.,4.,4.,0.,0.,0.],6*[False,]],
3529                            'Mustrain':['isotropic',[1000.0,1000.0,1.0],[False,False,False],[0,0,1],
3530                                NShkl*[0.01,],NShkl*[False,]],
3531                            'HStrain':[NDij*[0.0,],NDij*[False,]],                         
3532                            'Extinction':[0.0,False]}
3533                        refList = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,pId,'Reflection Lists'))
3534                        refList[generalData['Name']] = []                       
3535                    data['Histograms'] = UseList
3536                    wx.CallAfter(UpdateDData)
3537            finally:
3538                dlg.Destroy()
3539       
3540    def OnDataDelete(event):
3541        UseList = data['Histograms']
3542        keyList = ['All',]+UseList.keys()
3543        keyList.sort()
3544        DelList = []
3545        if UseList:
3546            DelList = []
3547            dlg = wx.MultiChoiceDialog(G2frame, 
3548                'Which histogram to delete from this phase?', 'Delete histogram', 
3549                keyList, wx.CHOICEDLG_STYLE)
3550            try:
3551                if dlg.ShowModal() == wx.ID_OK:
3552                    result = dlg.GetSelections()
3553                    for i in result: 
3554                        DelList.append(keyList[i])
3555                    if 'All' in DelList:
3556                        DelList = keyList[1:]
3557                    for i in DelList:
3558                        del UseList[i]
3559                    wx.CallAfter(UpdateDData)
3560            finally:
3561                dlg.Destroy()
3562
3563################################################################################
3564##### Pawley routines
3565################################################################################
3566
3567    def FillPawleyReflectionsGrid():
3568                       
3569        def KeyEditPawleyGrid(event):
3570            colList = G2frame.PawleyRefl.GetSelectedCols()
3571            PawleyPeaks = data['Pawley ref']
3572            if event.GetKeyCode() == wx.WXK_RETURN:
3573                event.Skip(True)
3574            elif event.GetKeyCode() == wx.WXK_CONTROL:
3575                event.Skip(True)
3576            elif event.GetKeyCode() == wx.WXK_SHIFT:
3577                event.Skip(True)
3578            elif colList:
3579                G2frame.PawleyRefl.ClearSelection()
3580                key = event.GetKeyCode()
3581                for col in colList:
3582                    if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
3583                        if key == 89: #'Y'
3584                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True
3585                        elif key == 78:  #'N'
3586                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False
3587                        FillPawleyReflectionsGrid()
3588           
3589        if 'Pawley ref' in data:
3590            PawleyPeaks = data['Pawley ref']                       
3591            rowLabels = []
3592            for i in range(len(PawleyPeaks)): rowLabels.append(str(i))
3593            colLabels = ['h','k','l','mul','d','refine','Fsq(hkl)','sig(Fsq)']
3594            Types = 4*[wg.GRID_VALUE_LONG,]+[wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,]+ \
3595                2*[wg.GRID_VALUE_FLOAT+':10,2',]
3596            PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
3597            G2frame.PawleyRefl.SetTable(PawleyTable, True)
3598            G2frame.PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid)                 
3599            for r in range(G2frame.PawleyRefl.GetNumberRows()):
3600                for c in range(G2frame.PawleyRefl.GetNumberCols()):
3601                    if c in [5,6]:
3602                        G2frame.PawleyRefl.SetReadOnly(r,c,isReadOnly=False)
3603                    else:
3604                        G2frame.PawleyRefl.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
3605            G2frame.PawleyRefl.SetMargins(0,0)
3606            G2frame.PawleyRefl.AutoSizeColumns(False)
3607            G2frame.dataFrame.setSizePosLeft([500,300])
3608                   
3609    def OnPawleyLoad(event):
3610        generalData = data['General']
3611        dmin = generalData['Pawley dmin']
3612        cell = generalData['Cell'][1:7]
3613        A = G2lat.cell2A(cell)
3614        SGData = generalData['SGData']
3615        HKLd = np.array(G2lat.GenHLaue(dmin,SGData,A))
3616        PawleyPeaks = []
3617        wx.BeginBusyCursor()
3618        try:
3619            for h,k,l,d in HKLd:
3620                ext,mul = G2spc.GenHKLf([h,k,l],SGData)[:2]
3621                if not ext:
3622                    mul *= 2        #for powder multiplicity
3623                    PawleyPeaks.append([h,k,l,mul,d,False,100.0,1.0])
3624        finally:
3625            wx.EndBusyCursor()
3626        data['Pawley ref'] = PawleyPeaks
3627        FillPawleyReflectionsGrid()
3628       
3629    def OnPawleyEstimate(event):
3630        try:
3631            Refs = data['Pawley ref']
3632            Histograms = data['Histograms']
3633        except KeyError:
3634            print '**** Error - no histograms defined for this phase ****'
3635            return
3636        HistoNames = Histograms.keys()
3637        PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,HistoNames[0])
3638        xdata = G2frame.PatternTree.GetItemPyData(PatternId)[1]
3639        Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Instrument Parameters'))
3640        Inst = dict(zip(Inst[3],Inst[1]))
3641        Sample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Sample Parameters'))
3642        if 'Lam' in Inst:
3643            wave = Inst['Lam']
3644        else:
3645            wave = Inst['Lam1']
3646        posCorr = Inst['Zero']
3647        const = 9.e-2/(np.pi*Sample['Gonio. radius'])                  #shifts in microns
3648       
3649        for ref in Refs:
3650            pos = 2.0*asind(wave/(2.0*ref[4]))
3651            if 'Bragg' in Sample['Type']:
3652                pos -= const*(4.*Sample['Shift'][0]*cosd(pos/2.0)+ \
3653                    Sample['Transparency'][0]*sind(pos)*100.0)            #trans(=1/mueff) in cm
3654            else:               #Debye-Scherrer - simple but maybe not right
3655                pos -= const*(Sample['DisplaceX'][0]*cosd(pos)+Sample['DisplaceY'][0]*sind(pos))
3656            indx = np.searchsorted(xdata[0],pos)
3657            try:
3658                FWHM = max(0.001,G2pwd.getFWHM(pos,Inst))/2.
3659                dx = xdata[0][indx+1]-xdata[0][indx]
3660                ref[6] = FWHM*xdata[1][indx]/dx
3661                Lorenz = 1./(2.*sind(xdata[0][indx]/2.)**2*cosd(xdata[0][indx]/2.))           #Lorentz correction
3662                pola,dIdPola = G2pwd.Polarization(Inst['Polariz.'],xdata[0][indx],Inst['Azimuth'])
3663                ref[6] /= (Lorenz*pola*ref[3])
3664            except IndexError:
3665                pass
3666        FillPawleyReflectionsGrid()
3667                           
3668    def OnPawleyDelete(event):
3669        dlg = wx.MessageDialog(G2frame,'Do you really want to delete Pawley reflections?','Delete', 
3670            wx.YES_NO | wx.ICON_QUESTION)
3671        try:
3672            result = dlg.ShowModal()
3673        finally:
3674            dlg.Destroy()
3675        if result == wx.ID_YES: 
3676            data['Pawley ref'] = []
3677            FillPawleyReflectionsGrid()
3678
3679################################################################################
3680##### Fourier routines
3681################################################################################
3682
3683    def FillMapPeaksGrid():
3684                       
3685        def RowSelect(event):
3686            r,c =  event.GetRow(),event.GetCol()
3687            if r < 0 and c < 0:
3688                if MapPeaks.IsSelection():
3689                    MapPeaks.ClearSelection()
3690                else:
3691                    for row in range(MapPeaks.GetNumberRows()):
3692                        MapPeaks.SelectRow(row,True)
3693                   
3694            elif c < 0:                   #only row clicks
3695                if event.ControlDown():                   
3696                    if r in MapPeaks.GetSelectedRows():
3697                        MapPeaks.DeselectRow(r)
3698                    else:
3699                        MapPeaks.SelectRow(r,True)
3700                elif event.ShiftDown():
3701                    for row in range(r+1):
3702                        MapPeaks.SelectRow(row,True)
3703                else:
3704                    MapPeaks.ClearSelection()
3705                    MapPeaks.SelectRow(r,True)               
3706            G2plt.PlotStructure(G2frame,data)                   
3707           
3708        G2frame.dataFrame.setSizePosLeft([450,300])
3709        if 'Map Peaks' in data:
3710            mapPeaks = data['Map Peaks']                       
3711            rowLabels = []
3712            for i in range(len(mapPeaks)): rowLabels.append(str(i))
3713            colLabels = ['mag','x','y','z']
3714            Types = 4*[wg.GRID_VALUE_FLOAT+':10,4',]
3715            MapPeaksTable = G2gd.Table(mapPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
3716            MapPeaks.SetTable(MapPeaksTable, True)
3717            MapPeaks.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
3718            for r in range(MapPeaks.GetNumberRows()):
3719                for c in range(MapPeaks.GetNumberCols()):
3720                    MapPeaks.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
3721            MapPeaks.SetMargins(0,0)
3722            MapPeaks.AutoSizeColumns(False)
3723                   
3724    def OnPeaksMove(event):
3725        if 'Map Peaks' in data:
3726            mapPeaks = data['Map Peaks']                       
3727            Ind = MapPeaks.GetSelectedRows()
3728            for ind in Ind:
3729                x,y,z = mapPeaks[ind][1:]
3730                AtomAdd(x,y,z,'C')
3731   
3732    def OnPeaksClear(event):
3733        data['Map Peaks'] = []
3734        FillMapPeaksGrid()
3735        G2plt.PlotStructure(G2frame,data)
3736       
3737    def OnPeaksDelete(event):
3738        if 'Map Peaks' in data:
3739            mapPeaks = data['Map Peaks']
3740            Ind = MapPeaks.GetSelectedRows()
3741            Ind.sort()
3742            Ind.reverse()
3743            print Ind
3744            for ind in Ind:
3745                mapPeaks = np.delete(mapPeaks,ind,0)
3746            data['Map Peaks'] = mapPeaks
3747        FillMapPeaksGrid()
3748        G2plt.PlotStructure(G2frame,data)
3749               
3750    def OnPeaksUnique(event):
3751        generalData = data['General']
3752        cell = generalData['Cell'][1:7]
3753        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
3754        A = G2lat.cell2A(cell)
3755        SGData = generalData['SGData']
3756        if 'Map Peaks' in data:
3757            mapPeaks = data['Map Peaks']
3758            Ind = MapPeaks.GetSelectedRows()
3759            for ind in Ind:
3760                XYZ = np.array(mapPeaks[ind][1:])                       
3761                Equiv = G2spc.GenAtom(XYZ,SGData,Move=True)[1:]     #remove self
3762                for equiv in Equiv:                                 #special position fixer
3763                        Dx = XYZ-np.array(equiv[0])
3764                        dist = np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0))
3765                        if dist < 0.5:
3766                            print equiv[0],Dx,dist
3767                            mapPeaks[ind][1:] -= Dx/2.
3768        FillMapPeaksGrid()
3769        G2plt.PlotStructure(G2frame,data)
3770   
3771    def OnFourierMaps(event):
3772        generalData = data['General']
3773        mapData = generalData['Map']
3774        reflName = mapData['RefList']
3775        phaseName = generalData['Name']
3776        if 'PWDR' in reflName:
3777            PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName)
3778            reflSets = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))
3779            reflData = reflSets[phaseName]
3780        elif 'HKLF' in reflName:
3781            PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName)
3782            reflData = G2frame.PatternTree.GetItemPyData(PatternId)[1]
3783        mapData.update(G2mth.FourierMap(data,reflData))
3784        mapData['Flip'] = False
3785        mapSig = np.std(mapData['rho'])
3786        if not data['Drawing']:                 #if new drawing - no drawing data!
3787            SetupDrawingData()
3788        data['Drawing']['contourLevel'] = 1.
3789        data['Drawing']['mapSize'] = 10.
3790        print mapData['MapType']+' computed: rhomax = %.3f rhomin = %.3f sigma = %.3f'%(np.max(mapData['rho']),np.min(mapData['rho']),mapSig)
3791        UpdateDrawAtoms()
3792        G2plt.PlotStructure(G2frame,data)
3793       
3794    def printRho(SGLaue,rho,rhoMax):                         
3795# map printing for testing purposes
3796        dim = len(rho.shape)
3797        if dim == 2:
3798            ix,jy = rho.shape
3799            for j in range(jy):
3800                line = ''
3801                if SGLaue in ['3','3m1','31m','6/m','6/mmm']:
3802                    line += (jy-j)*'  '
3803                for i in range(ix):
3804                    r = int(100*rho[i,j]/rhoMax)
3805                    line += '%4d'%(r)
3806                print line+'\n'
3807        else:
3808            ix,jy,kz = rho.shape
3809            for k in range(kz):
3810                print 'k = ',k
3811                for j in range(jy):
3812                    line = ''
3813                    if SGLaue in ['3','3m1','31m','6/m','6/mmm']:
3814                        line += (jy-j)*'  '
3815                    for i in range(ix):
3816                        r = int(100*rho[i,j,k]/rhoMax)
3817                        line += '%4d'%(r)
3818                    print line+'\n'
3819## keep this               
3820   
3821    def OnSearchMaps(event):
3822       
3823        peaks = []
3824        mags = []
3825        print ' Begin fourier map search - can take some time'
3826        time0 = time.time()
3827
3828        pgbar = wx.ProgressDialog('Map search','No. Peaks found =',301.0, 
3829            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT)
3830        screenSize = wx.ClientDisplayRect()
3831        Size = pgbar.GetSize()
3832        Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x
3833        pgbar.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
3834        pgbar.SetSize(Size)
3835        try:
3836            peaks,mags = G2mth.SearchMap(data,keepDup=True,Pgbar=pgbar)
3837        finally:
3838            pgbar.Destroy()
3839
3840
3841#        wx.BeginBusyCursor()
3842#        try:
3843#            peaks,mags = G2mth.SearchMap(data,keepDup=True)
3844#        finally:
3845#            wx.EndBusyCursor()
3846        sortIdx = np.argsort(mags.flatten())
3847        if len(peaks):
3848            data['Map Peaks'] = np.concatenate((mags,peaks),axis=1)
3849           
3850#            print ' Map search peaks found:'
3851#            print '  No.    Mag.      x        y        z'
3852#            for j,i in enumerate(sortIdx[::-1]):
3853#                print ' %3d %8.3f %8.5f %8.5f %8.5f'%(j,mags[i],peaks[i][0],peaks[i][1],peaks[i][2])
3854            print ' Map search finished, time = %.2fs'%(time.time()-time0)
3855        Page = G2frame.dataDisplay.FindPage('Map peaks')
3856        G2frame.dataDisplay.ChangeSelection(Page)
3857        G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.MapPeaksMenu)
3858        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksMove, id=G2gd.wxID_PEAKSMOVE)
3859        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksUnique, id=G2gd.wxID_PEAKSUNIQUE)
3860        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDelete, id=G2gd.wxID_PEAKSDELETE)
3861        G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksClear, id=G2gd.wxID_PEAKSCLEAR)
3862        UpdateDrawAtoms()
3863        FillMapPeaksGrid()
3864        G2plt.PlotStructure(G2frame,data)
3865       
3866    def OnChargeFlip(event):
3867        generalData = data['General']
3868        mapData = generalData['Map']
3869        flipData = generalData['Flip']
3870        reflName = flipData['RefList']
3871        phaseName = generalData['Name']
3872        if 'PWDR' in reflName:
3873            PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName)
3874            reflSets = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))
3875            reflData = reflSets[phaseName]
3876        elif 'HKLF' in reflName:
3877            PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName)
3878            reflData = G2frame.PatternTree.GetItemPyData(PatternId)[1]
3879        else:
3880            print '**** ERROR - No data defined for charge flipping'
3881            return
3882        pgbar = wx.ProgressDialog('Charge flipping','Residual Rcf =',101.0, 
3883            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT)
3884        screenSize = wx.ClientDisplayRect()
3885        Size = pgbar.GetSize()
3886        Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x
3887        pgbar.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
3888        pgbar.SetSize(Size)
3889        try:
3890            mapData.update(G2mth.ChargeFlip(data,reflData,pgbar))
3891        finally:
3892            pgbar.Destroy()
3893        mapData['Flip'] = True       
3894        mapSig = np.std(mapData['rho'])
3895        if not data['Drawing']:                 #if new drawing - no drawing data!
3896            SetupDrawingData()
3897        data['Drawing']['contourLevel'] = 1.
3898        data['Drawing']['mapSize'] = 10.
3899        print ' Charge flip map computed: rhomax = %.3f rhomin = %.3f sigma = %.3f'%(np.max(mapData['rho']),np.min(mapData['rho']),mapSig)
3900        if mapData['Rcf'] < 99.:
3901            OnSearchMaps(event)             #does a plot structure at end
3902        else:
3903            print 'Bad charge flip map - no peak search done'
3904               
3905    def OnTextureRefine(event):
3906        print 'refine texture?'
3907        event.Skip()       
3908           
3909    def OnTextureClear(event):
3910        print 'clear texture?'
3911        event.Skip()
3912
3913    def OnPageChanged(event):
3914        page = event.GetSelection()
3915        text = G2frame.dataDisplay.GetPageText(page)
3916        if text == 'Atoms':
3917            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.AtomsMenu)
3918            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
3919            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomTestAdd, id=G2gd.wxID_ATOMSTESTADD)
3920            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
3921            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomTestInsert, id=G2gd.wxID_ATONTESTINSERT)
3922            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
3923            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
3924            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
3925            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
3926            G2frame.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS)
3927            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDistAngle, id=G2gd.wxID_ATOMSDISAGL)
3928            FillAtomsGrid()
3929        elif text == 'General':
3930            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataGeneral)
3931            G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourierMaps, id=G2gd.wxID_FOURCALC)
3932            G2frame.dataFrame.Bind(wx.EVT_MENU, OnSearchMaps, id=G2gd.wxID_FOURSEARCH)
3933            G2frame.dataFrame.Bind(wx.EVT_MENU, OnChargeFlip, id=G2gd.wxID_CHARGEFLIP)
3934            UpdateGeneral()
3935        elif text == 'Data':
3936            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataMenu)
3937            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD)
3938            G2frame.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD)
3939            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE)
3940            UpdateDData()
3941            G2plt.PlotSizeStrainPO(G2frame,data,Start=True)
3942        elif text == 'Draw Options':
3943            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataDrawOptions)
3944            UpdateDrawOptions()
3945            G2plt.PlotStructure(G2frame,data)
3946        elif text == 'Draw Atoms':
3947            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DrawAtomsMenu)
3948            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE)
3949            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL)
3950            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR)
3951            G2frame.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR)
3952            G2frame.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT)
3953            G2frame.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV)
3954            G2frame.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM)
3955            G2frame.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD)           
3956            G2frame.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL)
3957            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE)
3958            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawDAT, id=G2gd.wxID_DRAWDISAGLTOR)
3959            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawPlane, id=G2gd.wxID_DRAWPLANE)
3960            UpdateDrawAtoms()
3961            G2plt.PlotStructure(G2frame,data)
3962        elif text == 'Pawley reflections':
3963            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.PawleyMenu)
3964            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD)
3965            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyEstimate, id=G2gd.wxID_PAWLEYESTIMATE)
3966            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyDelete, id=G2gd.wxID_PAWLEYDELETE)           
3967            FillPawleyReflectionsGrid()
3968        elif text == 'Texture':
3969            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.TextureMenu)
3970            G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureRefine, id=G2gd.wxID_REFINETEXTURE)
3971            G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureClear, id=G2gd.wxID_CLEARTEXTURE)
3972            UpdateTexture()                       
3973            G2plt.PlotTexture(G2frame,data,Start=True)
3974        elif text == 'Map peaks':
3975            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.MapPeaksMenu)
3976            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksMove, id=G2gd.wxID_PEAKSMOVE)
3977            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksUnique, id=G2gd.wxID_PEAKSUNIQUE)
3978            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDelete, id=G2gd.wxID_PEAKSDELETE)
3979            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksClear, id=G2gd.wxID_PEAKSCLEAR)
3980            FillMapPeaksGrid()
3981            G2plt.PlotStructure(G2frame,data)
3982           
3983        else:
3984            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
3985        event.Skip()
3986       
3987    General = wx.Window(G2frame.dataDisplay)
3988    G2frame.dataDisplay.AddPage(General,'General')
3989    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataGeneral)
3990    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourierMaps, id=G2gd.wxID_FOURCALC)
3991    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSearchMaps, id=G2gd.wxID_FOURSEARCH)
3992    G2frame.dataFrame.Bind(wx.EVT_MENU, OnChargeFlip, id=G2gd.wxID_CHARGEFLIP)
3993    SetupGeneral()
3994    GeneralData = data['General']
3995    UpdateGeneral()
3996
3997    DData = wx.ScrolledWindow(G2frame.dataDisplay)
3998    G2frame.dataDisplay.AddPage(DData,'Data')
3999    Atoms = G2gd.GSGrid(G2frame.dataDisplay)
4000    G2frame.dataDisplay.AddPage(Atoms,'Atoms')
4001    drawOptions = wx.Window(G2frame.dataDisplay)
4002    G2frame.dataDisplay.AddPage(drawOptions,'Draw Options')
4003    drawAtoms = G2gd.GSGrid(G2frame.dataDisplay)
4004    G2frame.dataDisplay.AddPage(drawAtoms,'Draw Atoms')
4005    Texture = wx.ScrolledWindow(G2frame.dataDisplay)
4006    G2frame.dataDisplay.AddPage(Texture,'Texture')
4007    MapPeaks = G2gd.GSGrid(G2frame.dataDisplay)
4008    G2frame.dataDisplay.AddPage(MapPeaks,'Map peaks')
4009    G2frame.PawleyRefl = G2gd.GSGrid(G2frame.dataDisplay)
4010    G2frame.dataDisplay.AddPage(G2frame.PawleyRefl,'Pawley reflections')
4011           
4012    G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
4013    G2frame.dataDisplay.SetSelection(oldPage)
4014   
4015           
Note: See TracBrowser for help on using the repository browser.