Changeset 811


Ignore:
Timestamp:
Dec 8, 2012 10:31:48 AM (9 years ago)
Author:
vondreele
Message:

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

Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIgrid.py

    r810 r811  
    11# -*- coding: utf-8 -*-
    2 #GSASII - data display routines
     2#GSASIIgrid - data display routines
    33########### SVN repository information ###################
    44# $Date$
     
    3030import GSASIIspc as G2spc
    3131import GSASIImapvars as G2mv
     32import GSASIIconstrGUI as G2cnstG
     33import GSASIIrestrGUI as G2restG
    3234
    3335# globals we will use later
     
    4749] = [wx.NewId() for item in range(12)]
    4850
    49 [ wxID_PWDRADD, wxID_HKLFADD, wxID_DATADELETE,
    50 ] = [wx.NewId() for item in range(3)]
     51[ wxID_PWDRADD, wxID_HKLFADD,wxID_PWDANALYSIS,wxID_DATADELETE,
     52] = [wx.NewId() for item in range(4)]
    5153
    5254[ wxID_ATOMSEDITADD, wxID_ATOMSEDITINSERT, wxID_ATOMSEDITDELETE, wxID_ATOMSREFINE,
     
    98100] = [wx.NewId() for item in range(4)]
    99101
    100 [ wxID_RESTRAINTADD,wxID_PWDANALYSIS, wxID_RESTSELPHASE,wxID_RESTDELETE, wxID_RESRCHANGEVAL,
    101     wxID_RESTCHANGEESD,
     102[ wxID_RESTRAINTADD, wxID_RESTSELPHASE,wxID_RESTDELETE, wxID_RESRCHANGEVAL,
     103    wxID_RESTCHANGEESD,wxID_AARESTRAINTADD,
    102104] = [wx.NewId() for item in range(6)]
    103105
     
    455457        self.RestraintEdit.Append(id=wxID_RESTRAINTADD, kind=wx.ITEM_NORMAL,text='Add restraints',
    456458            help='Add restraints')
     459        self.RestraintEdit.Append(id=wxID_AARESTRAINTADD, kind=wx.ITEM_NORMAL,text='Add residue restraints',
     460            help='Add residue based restraints for macromolecules')
     461        self.RestraintEdit.Enable(wxID_AARESTRAINTADD,False)    #gets enabled if macromolecule phase
    457462        self.RestraintEdit.Append(id=wxID_RESRCHANGEVAL, kind=wx.ITEM_NORMAL,text='Change value',
    458463            help='Change observed value')
     
    13681373    G2frame.dataDisplay.AutoSizeColumns(True)
    13691374    G2frame.dataFrame.setSizePosLeft([700,350])
    1370    
    1371 ################################################################################
    1372 #####  Constraints
    1373 ################################################################################           
    1374        
    1375 def UpdateConstraints(G2frame,data):
    1376     '''Called when Constraints tree item is selected.
    1377     Displays the constraints in the data window
    1378     '''
    1379     if not data:
    1380         data.update({'Hist':[],'HAP':[],'Phase':[]})       #empty dict - fill it
    1381     Histograms,Phases = G2frame.GetUsedHistogramsAndPhasesfromTree()
    1382     AtomDict = dict([Phases[phase]['pId'],Phases[phase]['Atoms']] for phase in Phases)
    1383     Natoms,atomIndx,phaseVary,phaseDict,pawleyLookup,FFtable,BLtable = G2str.GetPhaseData(Phases,Print=False)
    1384     phaseList = []
    1385     for item in phaseDict:
    1386         if item.split(':')[2] not in ['Ax','Ay','Az','Amul','AI/A','Atype','SHorder']:
    1387             phaseList.append(item)
    1388     phaseList.sort()
    1389     phaseAtNames = {}
    1390     phaseAtTypes = {}
    1391     TypeList = []
    1392     for item in phaseList:
    1393         Split = item.split(':')
    1394         if Split[2][:2] in ['AU','Af','dA']:
    1395             Id = int(Split[0])
    1396             phaseAtNames[item] = AtomDict[Id][int(Split[3])][0]
    1397             phaseAtTypes[item] = AtomDict[Id][int(Split[3])][1]
    1398             if phaseAtTypes[item] not in TypeList:
    1399                 TypeList.append(phaseAtTypes[item])
    1400         else:
    1401             phaseAtNames[item] = ''
    1402             phaseAtTypes[item] = ''
    1403            
    1404     hapVary,hapDict,controlDict = G2str.GetHistogramPhaseData(Phases,Histograms,Print=False)
    1405     hapList = hapDict.keys()
    1406     hapList.sort()
    1407     histVary,histDict,controlDict = G2str.GetHistogramData(Histograms,Print=False)
    1408     histList = []
    1409     for item in histDict:
    1410         if item.split(':')[2] not in ['Omega','Type','Chi','Phi','Azimuth','Gonio. radius','Lam1','Lam2','Back']:
    1411             histList.append(item)
    1412     histList.sort()
    1413     Indx = {}
    1414     scope = {}                          #filled out later
    1415     G2frame.Page = [0,'phs']
    1416    
    1417     def GetPHlegends(Phases,Histograms):
    1418         plegend = '\n In p::name'
    1419         hlegend = '\n In :h:name'
    1420         phlegend = '\n In p:h:name'
    1421         for phase in Phases:
    1422             plegend += '\n p:: = '+str(Phases[phase]['pId'])+':: for '+phase
    1423             count = 0
    1424             for histogram in Phases[phase]['Histograms']:
    1425                 if count < 3:
    1426                     phlegend += '\n p:h: = '+str(Phases[phase]['pId'])+':'+str(Histograms[histogram]['hId'])+': for '+phase+' in '+histogram
    1427                 else:
    1428                     phlegend += '\n ... etc.'
    1429                     break
    1430                 count += 1
    1431         count = 0
    1432         for histogram in Histograms:
    1433             if count < 3:
    1434                 hlegend += '\n :h: = :'+str(Histograms[histogram]['hId'])+': for '+histogram
    1435             else:
    1436                 hlegend += '\n ... etc.'
    1437                 break
    1438             count += 1
    1439         return plegend,hlegend,phlegend
    1440        
    1441     def FindEquivVarb(name,nameList):
    1442         outList = []
    1443         phlist = []
    1444         items = name.split(':')
    1445         namelist = [items[2],]
    1446         if 'dA' in name:
    1447             namelist = ['dAx','dAy','dAz']
    1448         elif 'AU' in name:
    1449             namelist = ['AUiso','AU11','AU22','AU33','AU12','AU13','AU23']
    1450         for item in nameList:
    1451             keys = item.split(':')
    1452             if keys[0] not in phlist:
    1453                 phlist.append(keys[0])
    1454             if keys[2] in namelist and item != name:
    1455                 outList.append(item)
    1456         if items[1]:
    1457             for key in phlist:
    1458                 outList.append(key+':all:'+items[2])
    1459         return outList
    1460        
    1461     def SelectVarbs(page,FrstVarb,varList,legend,constType):
    1462         '''Select variables used in Constraints after one variable has
    1463         been selected which determines the appropriate variables to be
    1464         used here. Then creates the constraint and adds it to the
    1465         constraints list.
    1466         Called from OnAddEquivalence, OnAddFunction & OnAddConstraint
    1467         '''
    1468         #future -  add 'all:all:name', '0:all:name', etc. to the varList
    1469         if page[1] == 'phs':
    1470             atchoice = [item+' for '+phaseAtNames[item] for item in varList]
    1471             atchoice += [FrstVarb+' for all']
    1472             atchoice += [FrstVarb+' for all '+atype for atype in TypeList]
    1473             dlg = wx.MultiChoiceDialog(G2frame,'Select more variables:'+legend,
    1474                 'Constrain '+FrstVarb+' and...',atchoice)
    1475         else:
    1476             dlg = wx.MultiChoiceDialog(G2frame,'Select more variables:'+legend,
    1477                 'Constrain '+FrstVarb+' and...',varList)
    1478         varbs = [FrstVarb,]
    1479         if dlg.ShowModal() == wx.ID_OK:
    1480             sel = dlg.GetSelections()
    1481             try:
    1482                 for x in sel:
    1483                     if ':all:' in varList[x]:       #a histogram 'all' - supercedes any individual selection
    1484                         varbs = [FrstVarb,]
    1485                         items = varList[x].split(':')
    1486                         for item in varList:
    1487                             if items[0] == item.split(':')[0]:
    1488                                 varbs.append(item)
    1489                         break
    1490                     else:
    1491                         varbs.append(varList[x])
    1492             except IndexError:      # one of the 'all' chosen - supercedes any individual selection
    1493                 varbs = [FrstVarb,]
    1494                 Atypes = []
    1495                 for x in sel:
    1496                     item = atchoice[x]
    1497                     if 'all' in item:
    1498                         Atypes.append(item.split('all')[1].strip())
    1499                 if '' in Atypes:
    1500                     varbs += varList
    1501                 else:
    1502                     for item in varList:
    1503                         if phaseAtTypes[item] in Atypes:
    1504                             varbs.append(item) 
    1505         dlg.Destroy()
    1506         if len(varbs) > 1:
    1507             if 'equivalence' in constType:
    1508                 constr = [[1.0,FrstVarb]]
    1509                 for item in varbs[1:]:
    1510                     constr += [[1.0,item]]
    1511                 return [constr+[None,None,'e']]      # list of equivalent variables & mults
    1512             elif 'function' in constType:
    1513                 constr = map(list,zip([1.0 for i in range(len(varbs))],varbs))
    1514                 return [constr+[None,False,'f']]         #just one constraint
    1515             else:       #'constraint'
    1516                 constr = map(list,zip([1.0 for i in range(len(varbs))],varbs))
    1517                 return [constr+[1.0,None,'c']]          #just one constraint - default sum to one
    1518         return []
    1519 
    1520     def CheckAddedConstraint(newcons):
    1521         '''Check a new constraint that has just been input.
    1522         If there is an error display a message and give the user a
    1523         choice to keep or discard the last entry (why keep? -- they
    1524         may want to delete something else or edit multipliers).
    1525         Since the varylist is not available, no warning messages
    1526         should be generated.
    1527         Returns True if constraint should be added
    1528         '''
    1529         allcons = []
    1530         for key in 'Hist','HAP','Phase':
    1531             allcons += data[key]
    1532         allcons += newcons
    1533         if not len(allcons): return True
    1534         G2mv.InitVars()   
    1535         constDictList,fixedList,ignored = G2str.ProcessConstraints(allcons)
    1536         errmsg, warnmsg = G2mv.CheckConstraints('',constDictList,fixedList)
    1537         if errmsg:
    1538             res = G2frame.ErrorDialog('Constraint Error',
    1539                 'Error with newly added constraint:\n'+errmsg+
    1540                 '\n\nDiscard newly added constraint?',parent=G2frame.dataFrame,
    1541                 wtype=wx.YES_NO)
    1542             return res != wx.ID_YES
    1543         elif warnmsg:
    1544             print 'Unexpected contraint warning:\n',warnmsg
    1545         return True
    1546 
    1547     def CheckChangedConstraint():
    1548         '''Check all constraints after an edit has been made.
    1549         If there is an error display a message and give the user a
    1550         choice to keep or discard the last edit.
    1551         Since the varylist is not available, no warning messages
    1552         should be generated.
    1553         Returns True if the edit should be retained
    1554         '''
    1555         allcons = []
    1556         for key in 'Hist','HAP','Phase':
    1557             allcons += data[key]
    1558         if not len(allcons): return True
    1559         G2mv.InitVars()   
    1560         constDictList,fixedList,ignored = G2str.ProcessConstraints(allcons)
    1561         errmsg, warnmsg = G2mv.CheckConstraints('',constDictList,fixedList)
    1562         if errmsg:
    1563             res = G2frame.ErrorDialog('Constraint Error',
    1564                 'Error after editing constraint:\n'+errmsg+
    1565                 '\n\nDiscard last constraint edit?',parent=G2frame.dataFrame,
    1566                 wtype=wx.YES_NO)
    1567             return res != wx.ID_YES
    1568         elif warnmsg:
    1569             print 'Unexpected contraint warning:\n',warnmsg
    1570         return True
    1571              
    1572     def OnAddHold(event):
    1573         '''add a Hold constraint'''
    1574         for phase in Phases:
    1575             Phase = Phases[phase]
    1576             Atoms = Phase['Atoms']
    1577         constr = []
    1578         page = G2frame.Page
    1579         choice = scope[page[1]]
    1580         if page[1] == 'phs':
    1581             atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
    1582             dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice)
    1583         else:   
    1584             dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2])
    1585         if dlg.ShowModal() == wx.ID_OK:
    1586             sel = dlg.GetSelection()
    1587             FrstVarb = choice[2][sel]
    1588             newcons = [[[0.0,FrstVarb],None,None,'h']]
    1589             if CheckAddedConstraint(newcons):
    1590                 data[choice[3]] += newcons
    1591         dlg.Destroy()
    1592         choice[4]()
    1593        
    1594     def OnAddEquivalence(event):
    1595         '''add an Equivalence constraint'''
    1596         constr = []
    1597         page = G2frame.Page
    1598         choice = scope[page[1]]
    1599         if page[1] == 'phs':
    1600             atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
    1601             dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice)
    1602         else:   
    1603             dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2])
    1604         if dlg.ShowModal() == wx.ID_OK:
    1605             sel = dlg.GetSelection()
    1606             FrstVarb = choice[2][sel]
    1607             moreVarb = FindEquivVarb(FrstVarb,choice[2])
    1608             newcons = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'equivalence')
    1609             if len(newcons) > 0:
    1610                 if CheckAddedConstraint(newcons):
    1611                     data[choice[3]] += newcons
    1612         dlg.Destroy()
    1613         choice[4]()
    1614    
    1615     def OnAddFunction(event):
    1616         '''add a Function (new variable) constraint'''
    1617         constr = []
    1618         page = G2frame.Page
    1619         choice = scope[page[1]]
    1620         if page[1] == 'phs':
    1621             atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
    1622             dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice)
    1623         else:   
    1624             dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2])
    1625         if dlg.ShowModal() == wx.ID_OK:
    1626             sel = dlg.GetSelection()
    1627             FrstVarb = choice[2][sel]
    1628             moreVarb = FindEquivVarb(FrstVarb,choice[2])
    1629             newcons = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'function')
    1630             if len(newcons) > 0:
    1631                 if CheckAddedConstraint(newcons):
    1632                     data[choice[3]] += newcons
    1633         dlg.Destroy()
    1634         choice[4]()
    1635                        
    1636     def OnAddConstraint(event):
    1637         '''add a constraint equation to the constraints list'''
    1638         constr = []
    1639         page = G2frame.Page
    1640         choice = scope[page[1]]
    1641         if page[1] == 'phs':
    1642             atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
    1643             dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice)
    1644         else:   
    1645             dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2])
    1646         if dlg.ShowModal() == wx.ID_OK:
    1647             sel = dlg.GetSelection()
    1648             FrstVarb = choice[2][sel]
    1649             moreVarb = FindEquivVarb(FrstVarb,choice[2])
    1650             newcons = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'constraint')
    1651             if len(newcons) > 0:
    1652                 if CheckAddedConstraint(newcons):
    1653                     data[choice[3]] += newcons
    1654         dlg.Destroy()
    1655         choice[4]()
    1656                        
    1657     def ConstSizer(name,pageDisplay):
    1658         '''This creates a sizer displaying all of the constraints entered
    1659         '''
    1660         constSizer = wx.FlexGridSizer(1,4,0,0)
    1661         maxlen = 70 # characters before wrapping a constraint
    1662         for Id,item in enumerate(data[name]):
    1663             eqString = ['',]
    1664             if item[-1] == 'h':
    1665                 constSizer.Add((5,5),0)              # blank space for edit button
    1666                 typeString = ' FIXED   '
    1667                 eqString[-1] = item[0][1]+'   '
    1668             elif isinstance(item[-1],str):
    1669                 constEdit = wx.Button(pageDisplay,-1,'Edit',style=wx.BU_EXACTFIT)
    1670                 constEdit.Bind(wx.EVT_BUTTON,OnConstEdit)
    1671                 constSizer.Add(constEdit)            # edit button
    1672                 Indx[constEdit.GetId()] = [Id,name]
    1673                 if item[-1] == 'f':
    1674                     for term in item[:-3]:
    1675                         if len(eqString[-1]) > maxlen:
    1676                             eqString.append(' ')
    1677                         m = term[0]
    1678                         if eqString[-1] != '':
    1679                             if m >= 0:
    1680                                 eqString[-1] += ' + '
    1681                             else:
    1682                                 eqString[-1] += ' - '
    1683                                 m = abs(m)
    1684                         eqString[-1] += '%.3f*%s '%(m,term[1])
    1685                     typeString = ' NEWVAR  '
    1686                     eqString[-1] += ' = New Variable   '
    1687                 elif item[-1] == 'c':
    1688                     for term in item[:-3]:
    1689                         if len(eqString[-1]) > maxlen:
    1690                             eqString.append(' ')
    1691                         if eqString[-1] != '':
    1692                             if term[0] > 0:
    1693                                 eqString[-1] += ' + '
    1694                             else:
    1695                                 eqString[-1] += ' - '
    1696                         eqString[-1] += '%.3f*%s '%(abs(term[0]),term[1])
    1697                     typeString = ' CONSTR  '
    1698                     eqString[-1] += ' = %.3f'%(item[-3])+'  '
    1699                 elif item[-1] == 'e':
    1700                     for term in item[:-3]:
    1701                         if term[0] == 0: term[0] = 1.0
    1702                         if len(eqString[-1]) > maxlen:
    1703                             eqString.append(' ')
    1704                         if eqString[-1] == '':
    1705                             eqString[-1] += '%s '%(term[1])
    1706                             first = term[0]
    1707                         else:
    1708                             eqString[-1] += ' = %.3f*%s '%(first/term[0],term[1])
    1709                     typeString = ' EQUIV   '
    1710                 else:
    1711                     print 'Unexpected constraint',item
    1712             else:
    1713                 print 'Removing old-style constraints'
    1714                 data[name] = []
    1715                 return constSizer
    1716             constDel = wx.Button(pageDisplay,-1,'Delete',style=wx.BU_EXACTFIT)
    1717             constDel.Bind(wx.EVT_BUTTON,OnConstDel)
    1718             Indx[constDel.GetId()] = [Id,name]
    1719             constSizer.Add(constDel)             # delete button
    1720             constSizer.Add(wx.StaticText(pageDisplay,-1,typeString),0,wx.ALIGN_CENTER_VERTICAL)
    1721             EqSizer = wx.BoxSizer(wx.VERTICAL)
    1722             for s in eqString:
    1723                 EqSizer.Add(wx.StaticText(pageDisplay,-1,s),0,wx.ALIGN_CENTER_VERTICAL)
    1724             constSizer.Add(EqSizer,0,wx.ALIGN_CENTER_VERTICAL)
    1725             # if item[-1] == 'f':
    1726             #     constRef = wx.CheckBox(pageDisplay,-1,label=' Refine?')
    1727             #     constRef.SetValue(item[-2])
    1728             #     constRef.Bind(wx.EVT_CHECKBOX,OnConstRef)
    1729             #     Indx[constRef.GetId()] = item
    1730             #     constSizer.Add(constRef)
    1731             # else:
    1732             #     constSizer.Add((5,5),0)
    1733         return constSizer
    1734                
    1735     # def OnConstRef(event):
    1736     #     Obj = event.GetEventObject()
    1737     #     Indx[Obj.GetId()][-2] = Obj.GetValue()
    1738        
    1739     def OnConstDel(event):
    1740         Obj = event.GetEventObject()
    1741         Id,name = Indx[Obj.GetId()]
    1742         del(data[name][Id])
    1743         OnPageChanged(None)       
    1744        
    1745     def OnConstEdit(event):
    1746         '''Called to edit an individual contraint by the Edit button'''
    1747         Obj = event.GetEventObject()
    1748         Id,name = Indx[Obj.GetId()]
    1749         sep = '*'
    1750         if data[name][Id][-1] == 'f':
    1751             items = data[name][Id][:-3]+[[],]
    1752             constType = 'New Variable'
    1753             lbl = 'Enter value for each term in constraint; sum = new variable'
    1754         elif data[name][Id][-1] == 'c':
    1755             items = data[name][Id][:-3]+[
    1756                 [data[name][Id][-3],'fixed value ='],[]]
    1757             constType = 'Constraint'
    1758             lbl = 'Edit value for each term in constant constraint sum'
    1759         elif data[name][Id][-1] == 'e':
    1760             items = data[name][Id][:-3]+[[],]
    1761             constType = 'Equivalence'
    1762             lbl = 'The following terms are set to be equal:'
    1763             sep = '/'
    1764         else:
    1765             return
    1766         dlg = G2frame.ConstraintDialog(G2frame.dataFrame,constType,lbl,items,sep)
    1767         try:
    1768             if dlg.ShowModal() == wx.ID_OK:
    1769                 prev = data[name][Id]
    1770                 result = dlg.GetData()
    1771                 if data[name][Id][-1] == 'c':
    1772                     data[name][Id][:-3] = result[:-2]
    1773                     data[name][Id][-3] = result[-2][0]
    1774                 else:
    1775                     data[name][Id][:-3] = result[:-1]
    1776                 if not CheckChangedConstraint():
    1777                     data[name][Id] = prev
    1778         except:
    1779             import traceback
    1780             print traceback.format_exc()
    1781         finally:
    1782             dlg.Destroy()           
    1783         OnPageChanged(None)                     
    1784    
    1785     def UpdateHAPConstr():
    1786         '''Responds to press on Histogram/Phase Constraints tab,
    1787         shows constraints in data window'''
    1788         HAPConstr.DestroyChildren()
    1789         HAPDisplay = wx.Panel(HAPConstr)
    1790         HAPSizer = wx.BoxSizer(wx.VERTICAL)
    1791         HAPSizer.Add((5,5),0)
    1792         HAPSizer.Add(ConstSizer('HAP',HAPDisplay))
    1793         HAPDisplay.SetSizer(HAPSizer,True)
    1794         Size = HAPSizer.GetMinSize()
    1795         Size[0] += 40
    1796         Size[1] = max(Size[1],250) + 20
    1797         HAPDisplay.SetSize(Size)
    1798         # scroll bar not working, at least not on Mac
    1799         HAPConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
    1800         Size[1] = min(Size[1],250)
    1801         G2frame.dataFrame.setSizePosLeft(Size)
    1802        
    1803     def UpdateHistConstr():
    1804         '''Responds to press on Histogram Constraints tab,
    1805         shows constraints in data window'''
    1806         HistConstr.DestroyChildren()
    1807         HistDisplay = wx.Panel(HistConstr)
    1808         HistSizer = wx.BoxSizer(wx.VERTICAL)
    1809         HistSizer.Add((5,5),0)       
    1810         HistSizer.Add(ConstSizer('Hist',HistDisplay))
    1811         HistDisplay.SetSizer(HistSizer,True)
    1812         Size = HistSizer.GetMinSize()
    1813         Size[0] += 40
    1814         Size[1] = max(Size[1],250) + 20
    1815         HistDisplay.SetSize(Size)
    1816         HistConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
    1817         Size[1] = min(Size[1],250)
    1818         G2frame.dataFrame.setSizePosLeft(Size)
    1819        
    1820     def UpdatePhaseConstr():
    1821         '''Responds to press on Phase Constraint tab,
    1822         shows constraints in data window'''
    1823         PhaseConstr.DestroyChildren()
    1824         PhaseDisplay = wx.Panel(PhaseConstr)
    1825         PhaseSizer = wx.BoxSizer(wx.VERTICAL)
    1826         PhaseSizer.Add((5,5),0)       
    1827         PhaseSizer.Add(ConstSizer('Phase',PhaseDisplay))
    1828         PhaseDisplay.SetSizer(PhaseSizer,True)
    1829         Size = PhaseSizer.GetMinSize()
    1830         Size[0] += 40
    1831         Size[1] = max(Size[1],250) + 20
    1832         PhaseDisplay.SetSize(Size)
    1833         PhaseConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
    1834         Size[1] = min(Size[1],250)
    1835         G2frame.dataFrame.setSizePosLeft(Size)
    1836    
    1837     def OnPageChanged(event):
    1838         if event:       #page change event!
    1839             page = event.GetSelection()
    1840         else:
    1841             page = G2frame.dataDisplay.GetSelection()
    1842         oldPage = G2frame.dataDisplay.ChangeSelection(page)
    1843         text = G2frame.dataDisplay.GetPageText(page)
    1844         if text == 'Histogram/Phase constraints':
    1845             G2frame.Page = [page,'hap']
    1846             UpdateHAPConstr()
    1847         elif text == 'Histogram constraints':
    1848             G2frame.Page = [page,'hst']
    1849             UpdateHistConstr()
    1850         elif text == 'Phase constraints':
    1851             G2frame.Page = [page,'phs']
    1852             UpdatePhaseConstr()
    1853 
    1854     def SetStatusLine(text):
    1855         Status.SetStatusText(text)                                     
    1856        
    1857     plegend,hlegend,phlegend = GetPHlegends(Phases,Histograms)
    1858     scope = {'hst':['Histogram contraints:',hlegend,histList,'Hist',UpdateHistConstr],
    1859         'hap':['Histogram * Phase contraints:',phlegend,hapList,'HAP',UpdateHAPConstr],
    1860         'phs':['Phase contraints:',plegend,phaseList,'Phase',UpdatePhaseConstr]}
    1861     if G2frame.dataDisplay:
    1862         G2frame.dataDisplay.Destroy()
    1863     SetDataMenuBar(G2frame,G2frame.dataFrame.ConstraintMenu)
    1864     G2frame.dataFrame.SetLabel('Constraints')
    1865     if not G2frame.dataFrame.GetStatusBar():
    1866         Status = G2frame.dataFrame.CreateStatusBar()
    1867     SetStatusLine('')
    1868    
    1869     SetDataMenuBar(G2frame,G2frame.dataFrame.ConstraintMenu)
    1870     G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddConstraint, id=wxID_CONSTRAINTADD)
    1871     G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddFunction, id=wxID_FUNCTADD)
    1872     G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddEquivalence, id=wxID_EQUIVADD)
    1873     G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddHold, id=wxID_HOLDADD)
    1874     G2frame.dataDisplay = GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
    1875    
    1876     PhaseConstr = wx.ScrolledWindow(G2frame.dataDisplay)
    1877     G2frame.dataDisplay.AddPage(PhaseConstr,'Phase constraints')
    1878     HAPConstr = wx.ScrolledWindow(G2frame.dataDisplay)
    1879     G2frame.dataDisplay.AddPage(HAPConstr,'Histogram/Phase constraints')
    1880     HistConstr = wx.ScrolledWindow(G2frame.dataDisplay)
    1881     G2frame.dataDisplay.AddPage(HistConstr,'Histogram constraints')
    1882     UpdatePhaseConstr()
    1883 
    1884     G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
    1885     # validate all the constrants -- should not see any errors here normally
    1886     allcons = []
    1887     for key in 'Hist','HAP','Phase':
    1888         allcons += data[key]
    1889     if not len(allcons): return
    1890     G2mv.InitVars()   
    1891     constDictList,fixedList,ignored = G2str.ProcessConstraints(allcons)
    1892     errmsg, warnmsg = G2mv.CheckConstraints('',constDictList,fixedList)
    1893     if errmsg:
    1894         G2frame.ErrorDialog('Constraint Error','Error in constraints:\n'+errmsg,
    1895             parent=G2frame.dataFrame)
    1896     elif warnmsg:
    1897         print 'Unexpected contraint warning:\n',warnmsg
    1898        
    1899 ################################################################################
    1900 #####  Restraints
    1901 ################################################################################           
    1902        
    1903 def UpdateRestraints(G2frame,data,Phases,phaseName):
    1904     if not len(Phases):
    1905         print 'There are no phases to form restraints'
    1906         return
    1907     phasedata = Phases[phaseName]
    1908     if phaseName not in data:
    1909         data[phaseName] = {}
    1910     restrData = data[phaseName]
    1911     if 'Bond' not in restrData:
    1912         restrData['Bond'] = {'wtFactor':1.0,'Bonds':[],'Use':True}
    1913     if 'Angle' not in restrData:
    1914         restrData['Angle'] = {'wtFactor':1.0,'Angles':[],'Use':True}
    1915     if 'Plane' not in restrData:
    1916         restrData['Plane'] = {'wtFactor':1.0,'Planes':[],'Use':True}
    1917     if 'Chiral' not in restrData:
    1918         restrData['Chiral'] = {'wtFactor':1.0,'Volumes':[],'Use':True}
    1919     General = phasedata['General']
    1920     Cell = General['Cell'][1:7]          #skip flag & volume   
    1921     Amat,Bmat = G2lat.cell2AB(Cell)
    1922     SGData = General['SGData']
    1923     cx,ct = General['AtomPtrs'][:2]
    1924     Atoms = phasedata['Atoms']
    1925     AtLookUp = G2mth.FillAtomLookUp(Atoms)
    1926     Names = ['all '+ name for name in General['AtomTypes']]
    1927     iBeg = len(Names)
    1928     Types = [name for name in General['AtomTypes']]
    1929     Coords = [ [] for type in Types]
    1930     Ids = [ 0 for type in Types]
    1931     Names += [atom[ct-1] for atom in Atoms]
    1932     Types += [atom[ct] for atom in Atoms]
    1933     Coords += [atom[cx:cx+3] for atom in Atoms]
    1934     Ids += [atom[-1] for atom in Atoms]
    1935    
    1936     def OnSelectPhase(event):
    1937         dlg = wx.SingleChoiceDialog(G2frame,'Select','Phase',Phases.keys())
    1938         try:
    1939             if dlg.ShowModal() == wx.ID_OK:
    1940                 phaseName = Phases.keys()[dlg.GetSelection()]
    1941                 UpdateRestraints(G2frame,data,Phases,phaseName)
    1942         finally:
    1943             dlg.Destroy()
    1944    
    1945     def OnAddRestraint(event):
    1946         page = G2frame.dataDisplay.GetSelection()
    1947         if 'Bond' in G2frame.dataDisplay.GetPageText(page):
    1948             bondRestData = restrData['Bond']
    1949             AddBondRestraint(bondRestData)
    1950         elif 'Angle' in G2frame.dataDisplay.GetPageText(page):
    1951             angleRestData = restrData['Angle']
    1952             AddAngleRestraint(angleRestData)
    1953         elif 'Plane' in G2frame.dataDisplay.GetPageText(page):
    1954             AddPlaneRestraint()
    1955         elif 'Chiral' in G2frame.dataDisplay.GetPageText(page):
    1956             AddChiralRestraint()
    1957            
    1958     def AddBondRestraint(bondRestData):
    1959         Radii = dict(zip(General['AtomTypes'],General['BondRadii']))
    1960         Lists = {'origin':[],'target':[]}
    1961         for listName in ['origin','target']:
    1962             dlg = wx.MultiChoiceDialog(G2frame,'Bond restraint '+listName+' for '+General['Name'],
    1963                     'Select bond restraint '+listName+' atoms',Names)
    1964             if dlg.ShowModal() == wx.ID_OK:
    1965                 sel = dlg.GetSelections()
    1966                 for x in sel:
    1967                     if 'all' in Names[x]:
    1968                         allType = Types[x]
    1969                         for name,Type,coords,id in zip(Names,Types,Coords,Ids):
    1970                             if Type == allType and 'all' not in name:
    1971                                 Lists[listName].append([id,Type,coords])
    1972                     else:
    1973                         Lists[listName].append([Ids[x],Types[x],Coords[x],])
    1974         Factor = .85
    1975         indices = (-1,0,1)
    1976         Units = np.array([[h,k,l] for h in indices for k in indices for l in indices])
    1977         origAtoms = Lists['origin']
    1978         targAtoms = Lists['target']
    1979         for Oid,Otype,Ocoord in origAtoms:
    1980             for Tid,Ttype,Tcoord in targAtoms:
    1981                 result = G2spc.GenAtom(Tcoord,SGData,False,Move=False)
    1982                 BsumR = (Radii[Otype]+Radii[Ttype])*Factor
    1983                 for Txyz,Top,Tunit in result:
    1984                     Dx = (Txyz-np.array(Ocoord))+Units
    1985                     dx = np.inner(Amat,Dx)
    1986                     dist = ma.masked_less(np.sqrt(np.sum(dx**2,axis=0)),0.5)
    1987                     IndB = ma.nonzero(ma.masked_greater(dist-BsumR,0.))
    1988                     if np.any(IndB):
    1989                         for indb in IndB:
    1990                             for i in range(len(indb)):
    1991                                 unit = Units[indb][i]+Tunit
    1992                                 if np.any(unit):
    1993                                     Topstr = '%d+%d,%d,%d'%(Top,unit[0],unit[1],unit[2])
    1994                                 else:
    1995                                     Topstr = str(Top)
    1996                                 bondRestData['Bonds'].append([[Oid,Tid],['1',Topstr], \
    1997                                     ma.getdata(dist[indb])[i],1.54,0.01])
    1998         UpdateBondRestr(bondRestData)               
    1999 
    2000     def AddAngleRestraint(angleRestData):
    2001         Radii = dict(zip(General['AtomTypes'],General['AngleRadii']))
    2002         origAtoms = []
    2003         targAtoms = [[Ids[x],Types[x],Coords[x]] for x in enumerate(Names[iBeg:])]
    2004         dlg = wx.MultiChoiceDialog(G2frame,'Select atom B for angle A-B-C for '+General['Name'],
    2005                 'Select angle restraint origin atoms',Names)
    2006         if dlg.ShowModal() == wx.ID_OK:
    2007             sel = dlg.GetSelections()
    2008             for x in sel:
    2009                 if 'all' in Names[x]:
    2010                     allType = Types[x]
    2011                     for name,Type,coords,id in zip(Names,Types,Coords,Ids):
    2012                         if Type == allType and 'all' not in name:
    2013                             origAtoms.append([id,Type,coords])
    2014                 else:
    2015                     origAtoms.append([Ids[x],Types[x],Coords[x]])
    2016 
    2017         Factor = .85
    2018         indices = (-1,0,1)
    2019         Units = np.array([[h,k,l] for h in indices for k in indices for l in indices])
    2020         for Oid,Otype,Ocoord in origAtoms:
    2021             IndBlist = []
    2022             Dist = []
    2023             Vect = []
    2024             VectA = []
    2025             angles = []
    2026             for Tid,Ttype,Tcoord in targAtoms:
    2027                 result = G2spc.GenAtom(Tcoord,SGData,False,Move=False)
    2028                 BsumR = (Radii[Otype]+Radii[Ttype])*Factor
    2029                 AsumR = (Radii[Otype]+Radii[Ttype])*Factor
    2030                 for Txyz,Top,Tunit in result:
    2031                     Dx = (Txyz-np.array(Ocoord))+Units
    2032                     dx = np.inner(Amat,Dx)
    2033                     dist = ma.masked_less(np.sqrt(np.sum(dx**2,axis=0)),0.5)
    2034                     IndB = ma.nonzero(ma.masked_greater(dist-BsumR,0.))
    2035                     if np.any(IndB):
    2036                         for indb in IndB:
    2037                             for i in range(len(indb)):
    2038                                 if str(dx.T[indb][i]) not in IndBlist:
    2039                                     IndBlist.append(str(dx.T[indb][i]))
    2040                                     unit = Units[indb][i]+Tunit
    2041                                 if np.any(unit):
    2042                                     Topstr = '%d+%d,%d,%d'%(Top,unit[0],unit[1],unit[2])
    2043                                 else:
    2044                                     Topstr = str(Top)
    2045                                     tunit = '[%2d%2d%2d]'%(unit[0]+Tunit[0],unit[1]+Tunit[1],unit[2]+Tunit[2])
    2046                                     Dist.append([Oatom[1],Tatom[1],tunit,Top,ma.getdata(dist[indb])[i],sig])
    2047                                     if (Dist[-1][-1]-AsumR) <= 0.:
    2048                                         Vect.append(dx.T[indb][i]/Dist[-1][-2])
    2049                                         VectA.append([OxyzNames,np.array(Oatom[3:6]),TxyzNames,np.array(Tatom[3:6]),unit,Top])
    2050                                     else:
    2051                                         Vect.append([0.,0.,0.])
    2052                                         VectA.append([])
    2053             Vect = np.array(Vect)
    2054             angles = np.zeros((len(Vect),len(Vect)))
    2055             angsig = np.zeros((len(Vect),len(Vect)))
    2056             for i,veca in enumerate(Vect):
    2057                 if np.any(veca):
    2058                     for j,vecb in enumerate(Vect):
    2059                         if np.any(vecb):
    2060                             angles[i][j] = G2mth.getAngSig(VectA[i],VectA[j],Amat,SGData)[0]
    2061 
    2062 
    2063 
    2064     def AddPlaneRestraint():
    2065         print 'Plane restraint'
    2066 
    2067     def AddChiralRestraint():
    2068         print 'Chiral restraint'
    2069        
    2070     def WtBox(wind,restData):
    2071        
    2072         def OnWtFactor(event):
    2073             try:
    2074                 value = float(wtfactor.GetValue())
    2075             except ValueError:
    2076                 value = 1.0
    2077             restData['wtFactor'] = value
    2078             wtfactor.SetValue('%.2f'%(value))
    2079            
    2080         def OnUseData(event):
    2081             restData['Use'] = Obj.GetValue()
    2082 
    2083         wtBox = wx.BoxSizer(wx.HORIZONTAL)
    2084         wtBox.Add(wx.StaticText(wind,-1,'Restraint weight factor:'),0,wx.ALIGN_CENTER_VERTICAL)
    2085         wtfactor = wx.TextCtrl(wind,-1,value='%.2f'%(restData['wtFactor']),style=wx.TE_PROCESS_ENTER)
    2086         wtfactor.Bind(wx.EVT_TEXT_ENTER,OnWtFactor)
    2087         wtfactor.Bind(wx.EVT_KILL_FOCUS,OnWtFactor)
    2088         wtBox.Add(wtfactor,0,wx.ALIGN_CENTER_VERTICAL)
    2089         useData = wx.CheckBox(wind,-1,label=' Use?')
    2090         useData.Bind(wx.EVT_CHECKBOX, OnUseData)
    2091         useData.SetValue(restData['Use'])       
    2092         wtBox.Add(useData,0,wx.ALIGN_CENTER_VERTICAL)
    2093         return wtBox
    2094        
    2095     def UpdateBondRestr(bondRestData):
    2096        
    2097         def OnColSort(event):
    2098             r,c = event.GetRow(),event.GetCol()
    2099             if r < 0 and c == 0:
    2100                 names = G2mth.sortArray(table,0)
    2101                 bonds = []
    2102                 for name in names:
    2103                     idx = table.index(name)
    2104                     bonds.append(bondList[idx])
    2105                 bondRestData['Bonds'] = bonds
    2106                 UpdateBondRestr(bondRestData)               
    2107        
    2108         def OnChangeValue(event):
    2109             rows = Bonds.GetSelectedRows()
    2110             if not rows:
    2111                 return
    2112             Bonds.ClearSelection()
    2113             val = bondList[rows[0]][4]
    2114             dlg = G2phG.SingleFloatDialog(G2frame,'New value','Enter new value for bond',val,[0.,5.],'%.4f')
    2115             if dlg.ShowModal() == wx.ID_OK:
    2116                 parm = dlg.GetValue()
    2117                 for r in rows:
    2118                     bondList[r][4] = parm
    2119             dlg.Destroy()
    2120             UpdateBondRestr(bondRestData)               
    2121 
    2122         def OnChangeEsd(event):
    2123             rows = Bonds.GetSelectedRows()
    2124             if not rows:
    2125                 return
    2126             Bonds.ClearSelection()
    2127             val = bondList[rows[0]][5]
    2128             dlg = G2phG.SingleFloatDialog(G2frame,'New value','Enter new esd for bond',val,[0.,1.],'%.4f')
    2129             if dlg.ShowModal() == wx.ID_OK:
    2130                 parm = dlg.GetValue()
    2131                 for r in rows:
    2132                     bondList[r][5] = parm
    2133             dlg.Destroy()
    2134             UpdateBondRestr(bondRestData)               
    2135                                
    2136         def OnDeleteRestraint(event):
    2137             rows = Bonds.GetSelectedRows()
    2138             if not rows:
    2139                 return
    2140             Bonds.ClearSelection()
    2141             rows.sort()
    2142             rows.reverse()
    2143             for row in rows:
    2144                 bondList.remove(bondList[row])
    2145             UpdateBondRestr(bondRestData)               
    2146            
    2147         BondRestr.DestroyChildren()
    2148         dataDisplay = wx.Panel(BondRestr)
    2149         mainSizer = wx.BoxSizer(wx.VERTICAL)
    2150         mainSizer.Add((5,5),0)
    2151         mainSizer.Add(WtBox(BondRestr,bondRestData),0,wx.ALIGN_CENTER_VERTICAL)
    2152 
    2153         bondList = bondRestData['Bonds']
    2154         if len(bondList[0]) == 6:   #patch
    2155             bondList = bondRestData['Bonds'] = []
    2156         if len(bondList):
    2157             table = []
    2158             rowLabels = []
    2159             colLabels = ['A+SymOp  B+SymOp','d-calc','d-obs','esd']
    2160             Types = [wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,3',]
    2161             for i,[indx,ops,dcalc,dobs,esd] in enumerate(bondList):
    2162                 atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
    2163                 table.append([atoms[0]+'+ ('+ops[0]+')  '+atoms[1]+'+ ('+ops[1]+')',dcalc,dobs,esd])
    2164                 rowLabels.append(str(i))
    2165             bondTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
    2166             Bonds = GSGrid(BondRestr)
    2167             Bonds.SetTable(bondTable, True)
    2168             Bonds.AutoSizeColumns(False)
    2169             for r in range(len(bondList)):
    2170                 for c in range(2):
    2171                     Bonds.SetReadOnly(r,c,True)
    2172                     Bonds.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
    2173             Bonds.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK,OnColSort)
    2174             G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=wxID_RESTDELETE)
    2175             G2frame.dataFrame.Bind(wx.EVT_MENU, OnChangeValue, id=wxID_RESRCHANGEVAL)
    2176             G2frame.dataFrame.Bind(wx.EVT_MENU, OnChangeEsd, id=wxID_RESTCHANGEESD)
    2177             mainSizer.Add(Bonds,0,)
    2178         else:
    2179             mainSizer.Add(wx.StaticText(BondRestr,-1,'No bond distance restraints for this phase'),0,)
    2180 
    2181         BondRestr.SetSizer(mainSizer)
    2182         Size = mainSizer.Fit(G2frame.dataFrame)
    2183         Size[0] += 5
    2184         Size[1] += 25       #make room for tab
    2185         BondRestr.SetSize(Size)
    2186         G2frame.dataFrame.setSizePosLeft(Size)
    2187        
    2188     def UpdateAngleRestr(angleRestData):
    2189        
    2190         def OnColSort(event):
    2191             r,c = event.GetRow(),event.GetCol()
    2192             if r < 0 and c == 0:
    2193                 names = G2mth.sortArray(table,0)
    2194                 angles = []
    2195                 for name in names:
    2196                     idx = table.index(name)
    2197                     angles.append(angleList[idx])
    2198                 angleRestData['Angles'] = angles
    2199                 UpdateAngleRestr(angleRestData)               
    2200        
    2201         def OnChangeValue(event):
    2202             rows = Angles.GetSelectedRows()
    2203             if not rows:
    2204                 return
    2205             Angles.ClearSelection()
    2206             val = angleList[rows[0]][4]
    2207             dlg = G2phG.SingleFloatDialog(G2frame,'New value','Enter new value for angle',val,[0.,360.],'%.2f')
    2208             if dlg.ShowModal() == wx.ID_OK:
    2209                 parm = dlg.GetValue()
    2210                 for r in rows:
    2211                     angleList[r][4] = parm
    2212             dlg.Destroy()
    2213             UpdateAngleRestr(angleRestData)               
    2214 
    2215         def OnChangeEsd(event):
    2216             rows = Angles.GetSelectedRows()
    2217             if not rows:
    2218                 return
    2219             Angles.ClearSelection()
    2220             val = angleList[rows[0]][5]
    2221             dlg = G2phG.SingleFloatDialog(G2frame,'New value','Enter new esd for angle',val,[0.,5.],'%.2f')
    2222             if dlg.ShowModal() == wx.ID_OK:
    2223                 parm = dlg.GetValue()
    2224                 for r in rows:
    2225                     angleList[r][5] = parm
    2226             dlg.Destroy()
    2227             UpdateAngleRestr(angleRestData)               
    2228                                            
    2229         def OnDeleteRestraint(event):
    2230             rows = Angles.GetSelectedRows()
    2231             if not rows:
    2232                 return
    2233             rows.sort()
    2234             rows.reverse()
    2235             for row in rows:
    2236                 angleList.remove(angleList[row])
    2237             UpdateAngleRestr(angleRestData)               
    2238            
    2239         AngleRestr.DestroyChildren()
    2240         dataDisplay = wx.Panel(AngleRestr)
    2241         mainSizer = wx.BoxSizer(wx.VERTICAL)
    2242         mainSizer.Add((5,5),0)
    2243         mainSizer.Add(WtBox(AngleRestr,angleRestData),0,wx.ALIGN_CENTER_VERTICAL)
    2244 
    2245         angleList = angleRestData['Angles']
    2246         if len(angleList):
    2247             table = []
    2248             rowLabels = []
    2249             colLabels = ['A+SymOp  B+SymOp  C+SymOp','calc','obs','esd']
    2250             Types = [wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,2',]
    2251             for i,[indx,ops,dcalc,dobs,esd] in enumerate(angleList):
    2252                 atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
    2253                 table.append([atoms[0]+'+ ('+ops[0]+')  '+atoms[1]+'+ ('+ops[1]+')  '+atoms[2]+ \
    2254                 '+ ('+ops[2]+')',dcalc,dobs,esd])
    2255                 rowLabels.append(str(i))
    2256             angleTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
    2257             Angles = GSGrid(AngleRestr)
    2258             Angles.SetTable(angleTable, True)
    2259             Angles.AutoSizeColumns(False)
    2260             for r in range(len(angleList)):
    2261                 for c in range(2):
    2262                     Angles.SetReadOnly(r,c,True)
    2263                     Angles.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
    2264             Angles.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK,OnColSort)
    2265             G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=wxID_RESTDELETE)
    2266             G2frame.dataFrame.Bind(wx.EVT_MENU, OnChangeValue, id=wxID_RESRCHANGEVAL)
    2267             G2frame.dataFrame.Bind(wx.EVT_MENU, OnChangeEsd, id=wxID_RESTCHANGEESD)
    2268             mainSizer.Add(Angles,0,)
    2269         else:
    2270             mainSizer.Add(wx.StaticText(AngleRestr,-1,'No bond angle restraints for this phase'),0,)
    2271 
    2272         AngleRestr.SetSizer(mainSizer)
    2273         Size = mainSizer.Fit(G2frame.dataFrame)
    2274         Size[0] += 5
    2275         Size[1] += 25       #make room for tab
    2276         AngleRestr.SetSize(Size)
    2277         G2frame.dataFrame.setSizePosLeft(Size)
    2278    
    2279     def UpdatePlaneRestr(planeRestData):
    2280        
    2281         items = G2frame.dataFrame.RestraintEdit.GetMenuItems()
    2282         for item in items:
    2283             if item.GetLabel() in ['Change value']:
    2284                 item.Enable(False)
    2285 
    2286         def OnDeleteRestraint(event):
    2287             rows = Planes.GetSelectedRows()
    2288             if not rows:
    2289                 return
    2290             rows.sort()
    2291             rows.reverse()
    2292             for row in rows:
    2293                 planeList.remove(planeList[row])
    2294             UpdatePlaneRestr(planeRestData)               
    2295            
    2296         PlaneRestr.DestroyChildren()
    2297         dataDisplay = wx.Panel(PlaneRestr)
    2298         mainSizer = wx.BoxSizer(wx.VERTICAL)
    2299         mainSizer.Add((5,5),0)
    2300         mainSizer.Add(WtBox(PlaneRestr,planeRestData),0,wx.ALIGN_CENTER_VERTICAL)
    2301 
    2302         planeList = planeRestData['Planes']
    2303         if len(planeList):
    2304             table = []
    2305             rowLabels = []
    2306             colLabels = ['atom+SymOp','calc','obs','esd']
    2307             Types = [wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,2',]
    2308             for i,[indx,ops,dcalc,dobs,esd] in enumerate(planeList):
    2309                 atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
    2310                 atString = ''
    2311                 for a,atom in enumerate(atoms):
    2312                     atString += atom+'+ ('+ops[a]+'),'
    2313                     if (a+1)%3 == 0:
    2314                         atString += '\n'
    2315                 table.append([atString[:-1],dcalc,dobs,esd])
    2316                 rowLabels.append(str(i))
    2317             planeTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
    2318             Planes = GSGrid(PlaneRestr)
    2319             Planes.SetTable(planeTable, True)
    2320             Planes.AutoSizeColumns(False)
    2321             Planes.AutoSizeRows(False)
    2322             for r in range(len(planeList)):
    2323                 for c in range(3):
    2324                     Planes.SetReadOnly(r,c,True)
    2325                     Planes.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
    2326             G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=wxID_RESTDELETE)
    2327             mainSizer.Add(Planes,0,)
    2328         else:
    2329             mainSizer.Add(wx.StaticText(PlaneRestr,-1,'No plane restraints for this phase'),0,)
    2330 
    2331         PlaneRestr.SetSizer(mainSizer)
    2332         Size = mainSizer.Fit(G2frame.dataFrame)
    2333         Size[0] += 5
    2334         Size[1] += 25       #make room for tab
    2335         PlaneRestr.SetSize(Size)
    2336         G2frame.dataFrame.setSizePosLeft(Size)
    2337    
    2338     def UpdateChiralRestr(chiralRestData):
    2339 
    2340         def OnDeleteRestraint(event):
    2341             rows = Volumes.GetSelectedRows()
    2342             if not rows:
    2343                 return
    2344             rows.sort()
    2345             rows.reverse()
    2346             for row in rows:
    2347                 volumeList.remove(volumeList[row])
    2348             UpdateChiralRestr(chiralRestData)               
    2349            
    2350         ChiralRestr.DestroyChildren()
    2351         dataDisplay = wx.Panel(ChiralRestr)
    2352         mainSizer = wx.BoxSizer(wx.VERTICAL)
    2353         mainSizer.Add((5,5),0)
    2354         mainSizer.Add(WtBox(ChiralRestr,chiralRestData),0,wx.ALIGN_CENTER_VERTICAL)
    2355 
    2356         volumeList = chiralRestData['Volumes']
    2357         if len(volumeList):
    2358             table = []
    2359             rowLabels = []
    2360             colLabels = ['O+SymOp  A+SymOp  B+SymOp  C+SymOp','calc','obs','esd']
    2361             Types = [wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,2',]
    2362             for i,[indx,ops,dcalc,dobs,esd] in enumerate(volumeList):
    2363                 atoms = G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,ct-1)
    2364                 table.append([atoms[0]+'+ ('+ops[0]+') '+atoms[1]+'+ ('+ops[1]+') '+atoms[2]+ \
    2365                 '+ ('+ops[2]+') '+atoms[3]+'+ ('+ops[3]+')',dcalc,dobs,esd])
    2366                 rowLabels.append(str(i))
    2367             volumeTable = Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
    2368             Volumes = GSGrid(ChiralRestr)
    2369             Volumes.SetTable(volumeTable, True)
    2370             Volumes.AutoSizeColumns(False)
    2371             for r in range(len(volumeList)):
    2372                 for c in range(2):
    2373                     Volumes.SetReadOnly(r,c,True)
    2374                     Volumes.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
    2375             G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteRestraint, id=wxID_RESTDELETE)
    2376             mainSizer.Add(Volumes,0,)
    2377         else:
    2378             mainSizer.Add(wx.StaticText(ChiralRestr,-1,'No chiral volume restraints for this phase'),0,)
    2379 
    2380         ChiralRestr.SetSizer(mainSizer)
    2381         Size = mainSizer.Fit(G2frame.dataFrame)
    2382         Size[0] += 5
    2383         Size[1] += 25       #make room for tab
    2384         ChiralRestr.SetSize(Size)
    2385         G2frame.dataFrame.setSizePosLeft(Size)
    2386    
    2387     def OnPageChanged(event):
    2388         page = event.GetSelection()
    2389         text = G2frame.dataDisplay.GetPageText(page)
    2390         if text == 'Bond restraints':
    2391             SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
    2392             bondRestData = restrData['Bond']
    2393             UpdateBondRestr(bondRestData)
    2394         elif text == 'Angle restraints':
    2395             SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
    2396             angleRestData = restrData['Angle']
    2397             UpdateAngleRestr(angleRestData)
    2398         elif text == 'Plane restraints':
    2399             SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
    2400             planeRestData = restrData['Plane']
    2401             UpdatePlaneRestr(planeRestData)
    2402         elif text == 'Chiral restraints':
    2403             SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
    2404             chiralRestData = restrData['Chiral']
    2405             UpdateChiralRestr(chiralRestData)
    2406         event.Skip()
    2407 
    2408     if G2frame.dataDisplay:
    2409         G2frame.dataDisplay.Destroy()
    2410        
    2411     SetDataMenuBar(G2frame,G2frame.dataFrame.RestraintMenu)
    2412     G2frame.dataFrame.SetLabel('restraints for '+phaseName)
    2413     G2frame.dataFrame.RestraintEdit.Enable(wxID_RESTSELPHASE,False)
    2414     if len(Phases) > 1:
    2415         G2frame.dataFrame.RestraintEdit.Enable(wxID_RESTSELPHASE,True)
    2416         G2frame.dataFrame.Bind(wx.EVT_MENU, OnSelectPhase, id=wxID_RESTSELPHASE)
    2417     G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddRestraint, id=wxID_RESTRAINTADD)
    2418     G2frame.dataDisplay = GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
    2419    
    2420     BondRestr = wx.ScrolledWindow(G2frame.dataDisplay)
    2421     G2frame.dataDisplay.AddPage(BondRestr,'Bond restraints')
    2422     AngleRestr = wx.ScrolledWindow(G2frame.dataDisplay)
    2423     G2frame.dataDisplay.AddPage(AngleRestr,'Angle restraints')
    2424     PlaneRestr = wx.ScrolledWindow(G2frame.dataDisplay)
    2425     G2frame.dataDisplay.AddPage(PlaneRestr,'Plane restraints')
    2426     ChiralRestr = wx.ScrolledWindow(G2frame.dataDisplay)
    2427     G2frame.dataDisplay.AddPage(ChiralRestr,'Chiral restraints')
    2428     UpdateBondRestr(restrData['Bond'])
    2429 
    2430     G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
    2431    
     1375       
    24321376################################################################################
    24331377#####  Main PWDR panel
     
    26651609        elif G2frame.PatternTree.GetItemText(item) == 'Constraints':
    26661610            data = G2frame.PatternTree.GetItemPyData(item)
    2667             UpdateConstraints(G2frame,data)
     1611            G2cnstG.UpdateConstraints(G2frame,data)
    26681612        elif G2frame.PatternTree.GetItemText(item) == 'Restraints':
    26691613            data = G2frame.PatternTree.GetItemPyData(item)
     
    26731617            if Phases:
    26741618                phaseName = Phases.keys()[0]
    2675             UpdateRestraints(G2frame,data,Phases,phaseName)
     1619            G2frame.dataFrame.setSizePosLeft(defWid)
     1620            G2restG.UpdateRestraints(G2frame,data,Phases,phaseName)
    26761621        elif 'IMG' in G2frame.PatternTree.GetItemText(item):
    26771622            G2frame.Image = item
  • trunk/GSASIImath.py

    r808 r811  
    178178def GetAtomItemsById(atomData,atomLookUp,IdList,itemLoc,numItems=1):
    179179    Items = []
     180    if not isinstance(IdList,list):
     181        IdList = [IdList,]
    180182    for id in IdList:
    181183        if numItems == 1:
  • trunk/GSASIIstruct.py

    r808 r811  
    36803680                                    sig = np.sqrt(np.inner(pdpx,np.inner(Xvcov,pdpx)))
    36813681                                Dist.append([Oatom[1],Tatom[1],tunit,Top,ma.getdata(dist[indb])[i],sig])
    3682                                 if (Dist[-1][-1]-AsumR) <= 0.:
     3682                                if (Dist[-1][-2]-AsumR) <= 0.:
    36833683                                    Vect.append(dx.T[indb][i]/Dist[-1][-2])
    36843684                                    VectA.append([OxyzNames,np.array(Oatom[3:6]),TxyzNames,np.array(Tatom[3:6]),unit,Top])
Note: See TracChangeset for help on using the changeset viewer.