source: trunk/GSASIIphsGUI.py @ 568

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

remove gsas data window placement
moved peaks are C atoms
start on a relocate map routine???

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