source: trunk/GSASIIrestrGUI.py @ 811

Last change on this file since 811 was 811, checked in by vondreele, 9 years ago

split GSASIIgrid.py into 3 parts; GSASIIconstrGUI.py & GSASIIrestrGUI.py are new

File size: 29.8 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASIIrestr - restraint GUI routines
3########### SVN repository information ###################
4# $Date: 2012-12-05 15:38:26 -0600 (Wed, 05 Dec 2012) $
5# $Author: vondreele $
6# $Revision: 810 $
7# $URL: https://subversion.xor.aps.anl.gov/pyGSAS/trunk/GSASIIrestrGUI.py $
8# $Id: GSASIIrestrGUI.py 810 2012-12-05 21:38:26Z vondreele $
9########### SVN repository information ###################
10import wx
11import wx.grid as wg
12import time
13import numpy as np
14import numpy.ma as ma
15import os.path
16import GSASIIpath
17GSASIIpath.SetVersionNumber("$Revision: 810 $")
18import GSASIImath as G2mth
19import GSASIIlattice as G2lat
20import GSASIIphsGUI as G2phG
21import GSASIIspc as G2spc
22import GSASIIgrid as G2gd
23
24VERY_LIGHT_GREY = wx.Colour(235,235,235)
25
26################################################################################
27#####  Restraints
28################################################################################           
29       
30def UpdateRestraints(G2frame,data,Phases,phaseName):
31    if not len(Phases):
32        print 'There are no phases to form restraints'
33        return
34    phasedata = Phases[phaseName]
35    if phaseName not in data:
36        data[phaseName] = {}
37    restrData = data[phaseName]
38    if 'Bond' not in restrData:
39        restrData['Bond'] = {'wtFactor':1.0,'Bonds':[],'Use':True}
40    if 'Angle' not in restrData:
41        restrData['Angle'] = {'wtFactor':1.0,'Angles':[],'Use':True}
42    if 'Plane' not in restrData:
43        restrData['Plane'] = {'wtFactor':1.0,'Planes':[],'Use':True}
44    if 'Chiral' not in restrData:
45        restrData['Chiral'] = {'wtFactor':1.0,'Volumes':[],'Use':True}
46    General = phasedata['General']
47    Cell = General['Cell'][1:7]          #skip flag & volume   
48    Amat,Bmat = G2lat.cell2AB(Cell)
49    SGData = General['SGData']
50    cx,ct = General['AtomPtrs'][:2]
51    Atoms = phasedata['Atoms']
52    AtLookUp = G2mth.FillAtomLookUp(Atoms)
53    Names = ['all '+ name for name in General['AtomTypes']]
54    iBeg = len(Names)
55    Types = [name for name in General['AtomTypes']]
56    Coords = [ [] for type in Types]
57    Ids = [ 0 for type in Types]
58    Names += [atom[ct-1] for atom in Atoms]
59    Types += [atom[ct] for atom in Atoms]
60    Coords += [atom[cx:cx+3] for atom in Atoms]
61    Ids += [atom[-1] for atom in Atoms]
62   
63    def OnSelectPhase(event):
64        dlg = wx.SingleChoiceDialog(G2frame,'Select','Phase',Phases.keys())
65        try:
66            if dlg.ShowModal() == wx.ID_OK:
67                phaseName = Phases.keys()[dlg.GetSelection()]
68                UpdateRestraints(G2frame,data,Phases,phaseName)
69        finally:
70            dlg.Destroy()
71   
72    def OnAddRestraint(event):
73        page = G2frame.dataDisplay.GetSelection()
74        if 'Bond' in G2frame.dataDisplay.GetPageText(page):
75            bondRestData = restrData['Bond']
76            AddBondRestraint(bondRestData)
77        elif 'Angle' in G2frame.dataDisplay.GetPageText(page):
78            angleRestData = restrData['Angle']
79            AddAngleRestraint(angleRestData)
80        elif 'Plane' in G2frame.dataDisplay.GetPageText(page):
81            AddPlaneRestraint()
82        elif 'Chiral' in G2frame.dataDisplay.GetPageText(page):
83            AddChiralRestraint()
84           
85    def OnAddAARestraint(event):
86        page = G2frame.dataDisplay.GetSelection()
87        if 'Bond' in G2frame.dataDisplay.GetPageText(page):
88            bondRestData = restrData['Bond']
89            AddAABondRestraint(bondRestData)
90        elif 'Angle' in G2frame.dataDisplay.GetPageText(page):
91            angleRestData = restrData['Angle']
92            AddAAAngleRestraint(angleRestData)
93        elif 'Plane' in G2frame.dataDisplay.GetPageText(page):
94            AddAAPlaneRestraint()
95        elif 'Chiral' in G2frame.dataDisplay.GetPageText(page):
96            AddAAChiralRestraint()
97           
98    def AddBondRestraint(bondRestData):
99        Radii = dict(zip(General['AtomTypes'],General['BondRadii']))
100        Lists = {'origin':[],'target':[]}
101        for listName in ['origin','target']:
102            dlg = wx.MultiChoiceDialog(G2frame,'Bond restraint '+listName+' for '+General['Name'],
103                    'Select bond restraint '+listName+' atoms',Names)
104            if dlg.ShowModal() == wx.ID_OK:
105                sel = dlg.GetSelections()
106                for x in sel:
107                    if 'all' in Names[x]:
108                        allType = Types[x]
109                        for name,Type,coords,id in zip(Names,Types,Coords,Ids):
110                            if Type == allType and 'all' not in name:
111                                Lists[listName].append([id,Type,coords])
112                    else:
113                        Lists[listName].append([Ids[x],Types[x],Coords[x],])
114        Factor = .85
115        indices = (-1,0,1)
116        Units = np.array([[h,k,l] for h in indices for k in indices for l in indices])
117        origAtoms = Lists['origin']
118        targAtoms = Lists['target']
119        dlg = wx.ProgressDialog("Generating bond restraints","Processed origin atoms",len(origAtoms), 
120            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_REMAINING_TIME)
121        try:
122            Norig = 0
123            for Oid,Otype,Ocoord in origAtoms:
124                Norig += 1
125                dlg.Update(Norig)
126                for Tid,Ttype,Tcoord in targAtoms:
127                    if 'macro' in General['Type']:
128                        result = [[Tcoord,1,[0,0,0]],]
129                    else:
130                        result = G2spc.GenAtom(Tcoord,SGData,False,Move=False)
131                    BsumR = (Radii[Otype]+Radii[Ttype])*Factor
132                    for Txyz,Top,Tunit in result:
133                        Dx = (Txyz-np.array(Ocoord))+Units
134                        dx = np.inner(Amat,Dx)
135                        dist = ma.masked_less(np.sqrt(np.sum(dx**2,axis=0)),0.5)
136                        IndB = ma.nonzero(ma.masked_greater(dist-BsumR,0.))
137                        if np.any(IndB):
138                            for indb in IndB:
139                                for i in range(len(indb)):
140                                    unit = Units[indb][i]+Tunit
141                                    if np.any(unit):
142                                        Topstr = '%d+%d,%d,%d'%(Top,unit[0],unit[1],unit[2])
143                                    else:
144                                        Topstr = str(Top)
145                                    bondRestData['Bonds'].append([[Oid,Tid],['1',Topstr], \
146                                        ma.getdata(dist[indb])[i],1.54,0.01])
147        finally:
148            dlg.Destroy()
149        UpdateBondRestr(bondRestData)               
150
151    def AddAngleRestraint(angleRestData):
152        Radii = dict(zip(General['AtomTypes'],zip(General['BondRadii'],General['AngleRadii'])))
153        origAtoms = []
154        dlg = wx.MultiChoiceDialog(G2frame,'Select atom B for angle A-B-C for '+General['Name'],
155                'Select angle restraint origin atoms',Names)
156        if dlg.ShowModal() == wx.ID_OK:
157            sel = dlg.GetSelections()
158            for x in sel:
159                if 'all' in Names[x]:
160                    allType = Types[x]
161                    for name,Type,coords,id in zip(Names,Types,Coords,Ids):
162                        if Type == allType and 'all' not in name:
163                            origAtoms.append([id,Type,coords])
164                else:
165                    origAtoms.append([Ids[x],Types[x],Coords[x]])
166        targAtoms = [[Ids[x+iBeg],Types[x+iBeg],Coords[x+iBeg]] for x in range(len(Names[iBeg:]))]
167
168        Factor = 1.0
169        indices = (-1,0,1)
170        Units = np.array([[h,k,l] for h in indices for k in indices for l in indices])
171        VectA = []
172        for Oid,Otype,Ocoord in origAtoms:
173            IndBlist = []
174            angles = []
175            VectB = []
176            for Tid,Ttype,Tcoord in targAtoms:
177                result = G2spc.GenAtom(Tcoord,SGData,False,Move=False)
178                BsumR = (Radii[Otype][0]+Radii[Ttype][0])*Factor
179                AsumR = (Radii[Otype][1]+Radii[Ttype][1])*Factor
180                for Txyz,Top,Tunit in result:
181                    Dx = (Txyz-Ocoord)+Units
182                    dx = np.inner(Amat,Dx)
183                    dist = ma.masked_less(np.sqrt(np.sum(dx**2,axis=0)),0.5)
184                    IndB = ma.nonzero(ma.masked_greater(dist-BsumR,0.))
185                    if np.any(IndB):
186                        for indb in IndB:
187                            for i in range(len(indb)):
188                                if str(dx.T[indb][i]) not in IndBlist:
189                                    IndBlist.append(str(dx.T[indb][i]))
190                                    unit = Units[indb][i]+Tunit
191                                if np.any(unit):
192                                    Topstr = '%d+%d,%d,%d'%(Top,unit[0],unit[1],unit[2])
193                                else:
194                                    Topstr = str(Top)
195                                    tunit = '[%2d%2d%2d]'%(unit[0]+Tunit[0],unit[1]+Tunit[1],unit[2]+Tunit[2])
196                                    Dist = ma.getdata(dist[indb])[i]
197                                    if (Dist-AsumR) <= 0.:
198                                        VectB.append([Oid,'1',Ocoord,Tid,Topstr,Tcoord,Dist])
199            VectA.append(VectB)
200            for Vects in VectA:
201                for i,vecta in enumerate(Vects):                   
202                    for vectb in Vects[:i]:
203                        ids = [vecta[3],vecta[0],vectb[3]]
204                        ops = [vecta[4],vecta[1],vectb[4]]
205                        XYZ = np.array([vecta[5],vecta[2],vectb[5]])
206                        angle = G2mth.getRestAngle(XYZ,Amat)
207                        angles.append([ids,ops,angle,109.5,1.0])
208            angleRestData['Angles'] += angles
209        UpdateAngleRestr(angleRestData)               
210
211    def AddPlaneRestraint():
212        origAtoms = []
213        dlg = wx.MultiChoiceDialog(G2frame,'Select atom B for angle A-B-C for '+General['Name'],
214                'Select angle restraint origin atoms',Names)
215        if dlg.ShowModal() == wx.ID_OK:
216            sel = dlg.GetSelections()
217            for x in sel:
218                if 'all' in Names[x]:
219                    allType = Types[x]
220                    for name,Type,coords,id in zip(Names,Types,Coords,Ids):
221                        if Type == allType and 'all' not in name:
222                            origAtoms.append([id,Type,coords])
223                else:
224                    origAtoms.append([Ids[x],Types[x],Coords[x]])
225
226    def AddChiralRestraint():
227        print 'Chiral restraint'
228       
229    def AddAABondRestraint(bondRestData):
230        print 'Amino acid Bond restraint'
231
232    def AddAAAngleRestraint(angleRestData):
233        print 'Amino acid Angle restraint'
234       
235    def AddAAPlaneRestraint():
236        print 'Amino acid Plane restraint'
237
238    def AddAAChiralRestraint():
239        print 'Amino acid Chiral restraint'
240       
241    def WtBox(wind,restData):
242       
243        def OnWtFactor(event):
244            try:
245                value = float(wtfactor.GetValue())
246            except ValueError:
247                value = 1.0
248            restData['wtFactor'] = value
249            wtfactor.SetValue('%.2f'%(value))
250           
251        def OnUseData(event):
252            restData['Use'] = Obj.GetValue()
253
254        wtBox = wx.BoxSizer(wx.HORIZONTAL)
255        wtBox.Add(wx.StaticText(wind,-1,'Restraint weight factor:'),0,wx.ALIGN_CENTER_VERTICAL)
256        wtfactor = wx.TextCtrl(wind,-1,value='%.2f'%(restData['wtFactor']),style=wx.TE_PROCESS_ENTER)
257        wtfactor.Bind(wx.EVT_TEXT_ENTER,OnWtFactor)
258        wtfactor.Bind(wx.EVT_KILL_FOCUS,OnWtFactor)
259        wtBox.Add(wtfactor,0,wx.ALIGN_CENTER_VERTICAL)
260        useData = wx.CheckBox(wind,-1,label=' Use?')
261        useData.Bind(wx.EVT_CHECKBOX, OnUseData)
262        useData.SetValue(restData['Use'])       
263        wtBox.Add(useData,0,wx.ALIGN_CENTER_VERTICAL)
264        return wtBox
265       
266    def UpdateBondRestr(bondRestData):
267       
268        def OnColSort(event):
269            r,c = event.GetRow(),event.GetCol()
270            if r < 0 and c == 0:
271                names = G2mth.sortArray(table,0)
272                bonds = []
273                for name in names:
274                    idx = table.index(name)
275                    bonds.append(bondList[idx])
276                bondRestData['Bonds'] = bonds
277                UpdateBondRestr(bondRestData)               
278       
279        def OnChangeValue(event):
280            rows = Bonds.GetSelectedRows()
281            if not rows:
282                return
283            Bonds.ClearSelection()
284            val = bondList[rows[0]][4]
285            dlg = G2phG.SingleFloatDialog(G2frame,'New value','Enter new value for bond',val,[0.,5.],'%.4f')
286            if dlg.ShowModal() == wx.ID_OK:
287                parm = dlg.GetValue()
288                for r in rows:
289                    bondList[r][4] = parm
290            dlg.Destroy()
291            UpdateBondRestr(bondRestData)               
292
293        def OnChangeEsd(event):
294            rows = Bonds.GetSelectedRows()
295            if not rows:
296                return
297            Bonds.ClearSelection()
298            val = bondList[rows[0]][5]
299            dlg = G2phG.SingleFloatDialog(G2frame,'New value','Enter new esd for bond',val,[0.,1.],'%.4f')
300            if dlg.ShowModal() == wx.ID_OK:
301                parm = dlg.GetValue()
302                for r in rows:
303                    bondList[r][5] = parm
304            dlg.Destroy()
305            UpdateBondRestr(bondRestData)               
306                               
307        def OnDeleteRestraint(event):
308            rows = Bonds.GetSelectedRows()
309            if not rows:
310                return
311            Bonds.ClearSelection()
312            rows.sort()
313            rows.reverse()
314            for row in rows:
315                bondList.remove(bondList[row])
316            UpdateBondRestr(bondRestData)               
317           
318        BondRestr.DestroyChildren()
319        dataDisplay = wx.Panel(BondRestr)
320        mainSizer = wx.BoxSizer(wx.VERTICAL)
321        mainSizer.Add((5,5),0)
322        mainSizer.Add(WtBox(BondRestr,bondRestData),0,wx.ALIGN_CENTER_VERTICAL)
323
324        bondList = bondRestData['Bonds']
325        if len(bondList) and len(bondList[0]) == 6:   #patch
326            bondList = bondRestData['Bonds'] = []
327        if len(bondList):
328            table = []
329            rowLabels = []
330            Types = [wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,3',]
331            if 'macro' in General['Type']:
332                colLabels = ['(res) A - (res) B','calc','obs','esd']
333                for i,[indx,ops,dcalc,dobs,esd] in enumerate(bondList):
334                    atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,0,4)
335                    name = ''
336                    for atom in atoms:
337                        name += '('+atom[1]+atom[0].strip()+atom[2]+') '+atom[3]+' - '
338                    table.append([name[:-3],dcalc,dobs,esd])
339                    rowLabels.append(str(i))               
340            else:
341                colLabels = ['A+SymOp - B+SymOp','calc','obs','esd']
342                for i,[indx,ops,dcalc,dobs,esd] in enumerate(bondList):
343                    atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
344                    table.append([atoms[0]+'+('+ops[0]+') - '+atoms[1]+'+('+ops[1]+')',dcalc,dobs,esd])
345                    rowLabels.append(str(i))
346            bondTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
347            Bonds = G2gd.GSGrid(BondRestr)
348            Bonds.SetTable(bondTable, True)
349            Bonds.AutoSizeColumns(False)
350            for r in range(len(bondList)):
351                for c in range(2):
352                    Bonds.SetReadOnly(r,c,True)
353                    Bonds.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
354            Bonds.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK,OnColSort)
355            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=G2gd.wxID_RESTDELETE)
356            G2frame.dataFrame.Bind(wx.EVT_MENU, OnChangeValue, id=G2gd.wxID_RESRCHANGEVAL)
357            G2frame.dataFrame.Bind(wx.EVT_MENU, OnChangeEsd, id=G2gd.wxID_RESTCHANGEESD)
358            mainSizer.Add(Bonds,0,)
359        else:
360            mainSizer.Add(wx.StaticText(BondRestr,-1,'No bond distance restraints for this phase'),0,)
361
362        BondRestr.SetSizer(mainSizer)
363        Size = mainSizer.Fit(G2frame.dataFrame)
364        Size[0] += 5
365        Size[1] += 50       #make room for tab
366        BondRestr.SetSize(Size)
367        BondRestr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
368        G2frame.dataFrame.setSizePosLeft(Size)
369       
370    def UpdateAngleRestr(angleRestData):
371       
372        def OnColSort(event):
373            r,c = event.GetRow(),event.GetCol()
374            if r < 0 and c == 0:
375                names = G2mth.sortArray(table,0)
376                angles = []
377                for name in names:
378                    idx = table.index(name)
379                    angles.append(angleList[idx])
380                angleRestData['Angles'] = angles
381                UpdateAngleRestr(angleRestData)               
382       
383        def OnChangeValue(event):
384            rows = Angles.GetSelectedRows()
385            if not rows:
386                return
387            Angles.ClearSelection()
388            val = angleList[rows[0]][4]
389            dlg = G2phG.SingleFloatDialog(G2frame,'New value','Enter new value for angle',val,[0.,360.],'%.2f')
390            if dlg.ShowModal() == wx.ID_OK:
391                parm = dlg.GetValue()
392                for r in rows:
393                    angleList[r][4] = parm
394            dlg.Destroy()
395            UpdateAngleRestr(angleRestData)               
396
397        def OnChangeEsd(event):
398            rows = Angles.GetSelectedRows()
399            if not rows:
400                return
401            Angles.ClearSelection()
402            val = angleList[rows[0]][5]
403            dlg = G2phG.SingleFloatDialog(G2frame,'New value','Enter new esd for angle',val,[0.,5.],'%.2f')
404            if dlg.ShowModal() == wx.ID_OK:
405                parm = dlg.GetValue()
406                for r in rows:
407                    angleList[r][5] = parm
408            dlg.Destroy()
409            UpdateAngleRestr(angleRestData)               
410                                           
411        def OnDeleteRestraint(event):
412            rows = Angles.GetSelectedRows()
413            if not rows:
414                return
415            rows.sort()
416            rows.reverse()
417            for row in rows:
418                angleList.remove(angleList[row])
419            UpdateAngleRestr(angleRestData)               
420           
421        AngleRestr.DestroyChildren()
422        dataDisplay = wx.Panel(AngleRestr)
423        mainSizer = wx.BoxSizer(wx.VERTICAL)
424        mainSizer.Add((5,5),0)
425        mainSizer.Add(WtBox(AngleRestr,angleRestData),0,wx.ALIGN_CENTER_VERTICAL)
426
427        angleList = angleRestData['Angles']
428        if len(angleList):
429            table = []
430            rowLabels = []
431            Types = [wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,2',]
432            if 'macro' in General['Type']:
433                colLabels = ['(res) A - (res) B - (res) C','calc','obs','esd']
434                for i,[indx,ops,dcalc,dobs,esd] in enumerate(angleList):
435                    atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,0,4)
436                    name = ''
437                    for atom in atoms:
438                        name += '('+atom[1]+atom[0].strip()+atom[2]+') '+atom[3]+' - '
439                    table.append([name[:-3],dcalc,dobs,esd])
440                    rowLabels.append(str(i))                               
441            else:
442                colLabels = ['A+SymOp - B+SymOp - C+SymOp','calc','obs','esd']
443                for i,[indx,ops,dcalc,dobs,esd] in enumerate(angleList):
444                    atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
445                    table.append([atoms[0]+'+('+ops[0]+') - '+atoms[1]+'+('+ops[1]+') - '+atoms[2]+ \
446                    '+('+ops[2]+')',dcalc,dobs,esd])
447                    rowLabels.append(str(i))
448            angleTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
449            Angles = G2gd.GSGrid(AngleRestr)
450            Angles.SetTable(angleTable, True)
451            Angles.AutoSizeColumns(False)
452            for r in range(len(angleList)):
453                for c in range(2):
454                    Angles.SetReadOnly(r,c,True)
455                    Angles.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
456            Angles.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK,OnColSort)
457            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=G2gd.wxID_RESTDELETE)
458            G2frame.dataFrame.Bind(wx.EVT_MENU, OnChangeValue, id=G2gd.wxID_RESRCHANGEVAL)
459            G2frame.dataFrame.Bind(wx.EVT_MENU, OnChangeEsd, id=G2gd.wxID_RESTCHANGEESD)
460            mainSizer.Add(Angles,0,)
461        else:
462            mainSizer.Add(wx.StaticText(AngleRestr,-1,'No bond angle restraints for this phase'),0,)
463
464        AngleRestr.SetSizer(mainSizer)
465        Size = mainSizer.Fit(G2frame.dataFrame)
466        Size[0] += 5
467        Size[1] += 50      #make room for tab
468        AngleRestr.SetSize(Size)
469        AngleRestr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
470        G2frame.dataFrame.setSizePosLeft(Size)
471   
472    def UpdatePlaneRestr(planeRestData):
473       
474        items = G2frame.dataFrame.RestraintEdit.GetMenuItems()
475        for item in items:
476            if item.GetLabel() in ['Change value']:
477                item.Enable(False)
478
479        def OnDeleteRestraint(event):
480            rows = Planes.GetSelectedRows()
481            if not rows:
482                return
483            rows.sort()
484            rows.reverse()
485            for row in rows:
486                planeList.remove(planeList[row])
487            UpdatePlaneRestr(planeRestData)               
488           
489        PlaneRestr.DestroyChildren()
490        dataDisplay = wx.Panel(PlaneRestr)
491        mainSizer = wx.BoxSizer(wx.VERTICAL)
492        mainSizer.Add((5,5),0)
493        mainSizer.Add(WtBox(PlaneRestr,planeRestData),0,wx.ALIGN_CENTER_VERTICAL)
494
495        planeList = planeRestData['Planes']
496        if len(planeList):
497            table = []
498            rowLabels = []
499            Types = [wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,2',]
500            if 'macro' in General['Type']:
501                colLabels = ['(res) atom','calc','obs','esd']
502                for i,[indx,ops,dcalc,dobs,esd] in enumerate(planeList):
503                    atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,0,4)
504                    name = ''
505                    for a,atom in enumerate(atoms):
506                        name += '('+atom[1]+atom[0].strip()+atom[2]+') '+atom[3]+' - '
507                        if (a+1)%3 == 0:
508                            name += '\n'
509                    table.append([name[:-3],dcalc,dobs,esd])
510                    rowLabels.append(str(i))
511            else:                               
512                colLabels = ['atom+SymOp','calc','obs','esd']
513                for i,[indx,ops,dcalc,dobs,esd] in enumerate(planeList):
514                    atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
515                    atString = ''
516                    for a,atom in enumerate(atoms):
517                        atString += atom+'+ ('+ops[a]+'),'
518                        if (a+1)%3 == 0:
519                            atString += '\n'
520                    table.append([atString[:-1],dcalc,dobs,esd])
521                    rowLabels.append(str(i))
522            planeTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
523            Planes = G2gd.GSGrid(PlaneRestr)
524            Planes.SetTable(planeTable, True)
525            Planes.AutoSizeColumns(False)
526            Planes.AutoSizeRows(False)
527            for r in range(len(planeList)):
528                for c in range(3):
529                    Planes.SetReadOnly(r,c,True)
530                    Planes.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
531            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=G2gd.wxID_RESTDELETE)
532            mainSizer.Add(Planes,0,)
533        else:
534            mainSizer.Add(wx.StaticText(PlaneRestr,-1,'No plane restraints for this phase'),0,)
535
536        PlaneRestr.SetSizer(mainSizer)
537        Size = mainSizer.Fit(G2frame.dataFrame)
538        Size[0] += 5
539        Size[1] += 50       #make room for tab
540        PlaneRestr.SetSize(Size)
541        PlaneRestr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
542        G2frame.dataFrame.setSizePosLeft(Size)
543   
544    def UpdateChiralRestr(chiralRestData):
545
546        def OnDeleteRestraint(event):
547            rows = Volumes.GetSelectedRows()
548            if not rows:
549                return
550            rows.sort()
551            rows.reverse()
552            for row in rows:
553                volumeList.remove(volumeList[row])
554            UpdateChiralRestr(chiralRestData)               
555           
556        ChiralRestr.DestroyChildren()
557        dataDisplay = wx.Panel(ChiralRestr)
558        mainSizer = wx.BoxSizer(wx.VERTICAL)
559        mainSizer.Add((5,5),0)
560        mainSizer.Add(WtBox(ChiralRestr,chiralRestData),0,wx.ALIGN_CENTER_VERTICAL)
561
562        volumeList = chiralRestData['Volumes']
563        if len(volumeList):
564            table = []
565            rowLabels = []
566            Types = [wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,2',]
567            if 'macro' in General['Type']:
568                colLabels = ['(res) O (res) A (res) B (res) C','calc','obs','esd']
569                for i,[indx,ops,dcalc,dobs,esd] in enumerate(volumeList):
570                    atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,0,4)
571                    name = ''
572                    for atom in atoms:
573                        name += '('+atom[1]+atom[0].strip()+atom[2]+') '+atom[3]+' '
574                    table.append([name[:-3],dcalc,dobs,esd])
575                    rowLabels.append(str(i))
576            else:
577                colLabels = ['O+SymOp  A+SymOp  B+SymOp  C+SymOp)','calc','obs','esd']
578                for i,[indx,ops,dcalc,dobs,esd] in enumerate(volumeList):
579                    atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
580                    table.append([atoms[0]+'+('+ops[0]+') '+atoms[1]+'+('+ops[1]+') '+atoms[2]+ \
581                    '+('+ops[2]+') '+atoms[3]+'+('+ops[3]+')',dcalc,dobs,esd])
582                    rowLabels.append(str(i))
583            volumeTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
584            Volumes = G2gd.GSGrid(ChiralRestr)
585            Volumes.SetTable(volumeTable, True)
586            Volumes.AutoSizeColumns(False)
587            for r in range(len(volumeList)):
588                for c in range(2):
589                    Volumes.SetReadOnly(r,c,True)
590                    Volumes.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
591            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=G2gd.wxID_RESTDELETE)
592            mainSizer.Add(Volumes,0,)
593        else:
594            mainSizer.Add(wx.StaticText(ChiralRestr,-1,'No chiral volume restraints for this phase'),0,)
595
596        ChiralRestr.SetSizer(mainSizer)
597        Size = mainSizer.Fit(G2frame.dataFrame)
598        Size[0] += 5
599        Size[1] += 50       #make room for tab
600        ChiralRestr.SetSize(Size)
601        ChiralRestr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
602        G2frame.dataFrame.setSizePosLeft(Size)
603   
604    def OnPageChanged(event):
605        page = event.GetSelection()
606        text = G2frame.dataDisplay.GetPageText(page)
607        if text == 'Bond restraints':
608            G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
609            bondRestData = restrData['Bond']
610            UpdateBondRestr(bondRestData)
611        elif text == 'Angle restraints':
612            G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
613            angleRestData = restrData['Angle']
614            UpdateAngleRestr(angleRestData)
615        elif text == 'Plane restraints':
616            G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
617            planeRestData = restrData['Plane']
618            UpdatePlaneRestr(planeRestData)
619        elif text == 'Chiral restraints':
620            G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
621            chiralRestData = restrData['Chiral']
622            UpdateChiralRestr(chiralRestData)
623        event.Skip()
624
625    def SetStatusLine(text):
626        Status.SetStatusText(text)                                     
627       
628    if G2frame.dataDisplay:
629        G2frame.dataDisplay.Destroy()
630       
631    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
632    G2frame.dataFrame.SetLabel('restraints for '+phaseName)
633    if not G2frame.dataFrame.GetStatusBar():
634        Status = G2frame.dataFrame.CreateStatusBar()
635    SetStatusLine('')
636   
637    G2frame.dataFrame.RestraintEdit.Enable(G2gd.wxID_RESTSELPHASE,False)
638    if len(Phases) > 1:
639        G2frame.dataFrame.RestraintEdit.Enable(G2gd.wxID_RESTSELPHASE,True)
640        G2frame.dataFrame.Bind(wx.EVT_MENU, OnSelectPhase, id=G2gd.wxID_RESTSELPHASE)
641    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddRestraint, id=G2gd.wxID_RESTRAINTADD)
642    if 'macro' in phasedata['General']['Type']:
643        G2frame.dataFrame.RestraintEdit.Enable(G2gd.wxID_AARESTRAINTADD,True)
644        G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddAARestraint, id=G2gd.wxID_AARESTRAINTADD)
645    G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
646   
647    BondRestr = wx.ScrolledWindow(G2frame.dataDisplay)
648    G2frame.dataDisplay.AddPage(BondRestr,'Bond restraints')
649    AngleRestr = wx.ScrolledWindow(G2frame.dataDisplay)
650    G2frame.dataDisplay.AddPage(AngleRestr,'Angle restraints')
651    PlaneRestr = wx.ScrolledWindow(G2frame.dataDisplay)
652    G2frame.dataDisplay.AddPage(PlaneRestr,'Plane restraints')
653    ChiralRestr = wx.ScrolledWindow(G2frame.dataDisplay)
654    G2frame.dataDisplay.AddPage(ChiralRestr,'Chiral restraints')
655    UpdateBondRestr(restrData['Bond'])
656
657    G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
Note: See TracBrowser for help on using the repository browser.