Changeset 1161


Ignore:
Timestamp:
Dec 5, 2013 2:50:03 PM (9 years ago)
Author:
toby
Message:

finish ISODISTORT occupancy modes

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIgrid.py

    r1160 r1161  
    15791579        num = len(varyList)
    15801580        mainSizer.Add(wx.StaticText(self,wx.ID_ANY,'Number of refined variables: '+str(num)))
    1581         num = len(fullVaryList)
    1582         mainSizer.Add(wx.StaticText(self,wx.ID_ANY,'Number dependent and refined variables: '+str(num)))
    1583 
     1581        if len(varyList) != len(fullVaryList):
     1582            num = len(fullVaryList) - len(varyList)
     1583            mainSizer.Add(wx.StaticText(self,wx.ID_ANY,' + '+str(num)+' parameters are varied via constraints'))
    15841584        subSizer = wx.FlexGridSizer(rows=len(parmDict)+1,cols=4,hgap=2,vgap=2)
    15851585        parmNames = parmDict.keys()
     
    16241624                wx.StaticText(self,wx.ID_ANY,
    16251625                          '"R" indicates a refined variable\n'+
    1626                           '"C" is generated from a constraint'
     1626                          '"C" indicates generated from a constraint'
    16271627                          ),
    16281628                0, wx.ALL,0)
  • trunk/GSASIIphsGUI.py

    r1160 r1161  
    4848import GSASIIpwd as G2pwd
    4949import GSASIIpy3 as G2py3
     50import GSASIIobj as G2obj
    5051import numpy as np
    5152import numpy.linalg as nl
     
    16371638        only when Phase['ISODISTORT'] is defined.
    16381639        '''
     1640        def _onClose(event):
     1641            dlg.EndModal(wx.ID_CANCEL)
     1642        def fmtHelp(item,fullname):
     1643            helptext = "A new variable"
     1644            if item[-3]:
     1645                helptext += " named "+str(item[-3])
     1646            helptext += " is a linear combination of the following parameters:\n"
     1647            first = True
     1648            for term in item[:-3]:
     1649                line = ''
     1650                var = str(term[1])
     1651                m = term[0]
     1652                if first:
     1653                    first = False
     1654                    line += ' = '
     1655                else:
     1656                    if m >= 0:
     1657                        line += ' + '
     1658                    else:
     1659                        line += ' - '
     1660                    m = abs(m)
     1661                line += '%.3f*%s '%(m,var)
     1662                varMean = G2obj.fmtVarDescr(var)
     1663                helptext += "\n" + line + " ("+ varMean + ")"
     1664            helptext += '\n\nISODISTORT full name: '+str(fullname)
     1665            return helptext
     1666
    16391667        if 'ISODISTORT' not in data:
    16401668            raise Exception,"Should not happen: 'ISODISTORT' not in data"
     
    16451673                )
    16461674            return
    1647         def _onClose(event):
    1648             dlg.EndModal(wx.ID_CANCEL)
    1649 
    16501675        Histograms,Phases = G2frame.GetUsedHistogramsAndPhasesfromTree() # init for constraint
     1676        # make a lookup table for constraints
     1677        sub = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Constraints')
     1678        Constraints = G2frame.PatternTree.GetItemPyData(sub)
     1679        constDict = {}
     1680        for item in Constraints:
     1681            if item.startswith('_'): continue
     1682            for c in Constraints[item]:
     1683                if c[-1] != 'f' or not c[-3]: continue
     1684                constDict[c[-3]] = c
     1685
    16511686        ISO = data['ISODISTORT']
    16521687        parmDict,varyList = G2frame.MakeLSParmDict()
    1653         deltaList = []
    1654         for gv,Ilbl in zip(ISO['G2VarList'],ISO['IsoVarList']):
    1655             dvar = gv.varname()
    1656             var = dvar.replace('::dA','::A')
    1657             albl = Ilbl[:Ilbl.rfind('_')]
    1658             v = Ilbl[Ilbl.rfind('_')+1:]
    1659             pval = ISO['ParentStructure'][albl][['dx','dy','dz'].index(v)]
    1660             if var in parmDict:
    1661                 cval = parmDict[var][0]
    1662             else:
    1663                 G2frame.ErrorDialog('Atom not found',"No value found for parameter "+str(var))
    1664                 return
    1665             deltaList.append(cval-pval)
    1666         modeVals = np.inner(ISO['Var2ModeMatrix'],deltaList)
     1688           
    16671689        dlg = wx.Dialog(G2frame,wx.ID_ANY,'ISODISTORT mode values',#size=(630,400),
    16681690                           style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
     
    16791701            dlg, wx.ID_ANY,#size=(100,200),
    16801702            style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
    1681         subSizer2 = wx.FlexGridSizer(rows=1,cols=2,hgap=5,vgap=2)
    1682         subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,'Parameter name'))
    1683         subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,'value '),0,wx.ALIGN_RIGHT)
    1684         subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,' Mode name  '))
    1685         subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,'value '),0,wx.ALIGN_RIGHT)
     1703        subSizer2 = wx.FlexGridSizer(rows=1,cols=3,hgap=5,vgap=2)
     1704        subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,'Parameter name  '))
     1705        subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,' value'),0,wx.ALIGN_RIGHT)
     1706        subSizer2.Add((-1,-1))
     1707        subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,'Mode name  '))
     1708        subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,' value'),0,wx.ALIGN_RIGHT)
    16861709       
    1687         for lbl,xyz,var,val in zip(ISO['IsoVarList'],deltaList,ISO['IsoModeList'],modeVals):
    1688             subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,str(lbl)))
    1689             try:
    1690                 value = G2py3.FormatValue(xyz)
    1691             except TypeError:
    1692                 value = str(xyz)           
    1693             subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,value),0,wx.ALIGN_RIGHT)
    1694             #subSizer.Add((10,-1))
    1695             subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,str(var)))
    1696             try:
    1697                 value = G2py3.FormatValue(val)
    1698             except TypeError:
    1699                 value = str(val)           
    1700             subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,value),0,wx.ALIGN_RIGHT)
     1710        if 'G2VarList' in ISO:
     1711            deltaList = []
     1712            for gv,Ilbl in zip(ISO['G2VarList'],ISO['IsoVarList']):
     1713                dvar = gv.varname()
     1714                var = dvar.replace('::dA','::A')
     1715                albl = Ilbl[:Ilbl.rfind('_')]
     1716                v = Ilbl[Ilbl.rfind('_')+1:]
     1717                pval = ISO['ParentStructure'][albl][['dx','dy','dz'].index(v)]
     1718                if var in parmDict:
     1719                    cval = parmDict[var][0]
     1720                else:
     1721                    dlg.EndModal(wx.ID_CANCEL)
     1722                    G2frame.ErrorDialog('Atom not found',"No value found for parameter "+str(var))
     1723                    return
     1724                deltaList.append(cval-pval)
     1725            modeVals = np.inner(ISO['Var2ModeMatrix'],deltaList)
     1726            for lbl,xyz,var,val,G2var in zip(ISO['IsoVarList'],deltaList,
     1727                                             ISO['IsoModeList'],modeVals,ISO['G2ModeList']):
     1728                if G2var in constDict:
     1729                    ch = G2gd.HelpButton(panel2,fmtHelp(constDict[G2var],var))
     1730                    subSizer2.Add(ch,0,wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER,1)
     1731                else:
     1732                    subSizer2.Add((-1,-1))
     1733                subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,str(lbl)))
     1734                try:
     1735                    value = G2py3.FormatValue(xyz)
     1736                except TypeError:
     1737                    value = str(xyz)           
     1738                subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,value),0,wx.ALIGN_RIGHT)
     1739                subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,str(var)))
     1740                try:
     1741                    value = G2py3.FormatValue(val)
     1742                except TypeError:
     1743                    value = str(val)           
     1744                subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,value),0,wx.ALIGN_RIGHT)
     1745        if 'G2OccVarList' in ISO:
     1746            deltaList = []
     1747            for gv,Ilbl in zip(ISO['G2OccVarList'],ISO['OccVarList']):
     1748                var = gv.varname()
     1749                albl = Ilbl[:Ilbl.rfind('_')]
     1750                #v = Ilbl[Ilbl.rfind('_')+1:]
     1751                pval = ISO['BaseOcc'][albl]
     1752                if var in parmDict:
     1753                    cval = parmDict[var][0]
     1754                else:
     1755                    dlg.EndModal(wx.ID_CANCEL)
     1756                    G2frame.ErrorDialog('Atom not found',"No value found for parameter "+str(var))
     1757                    return
     1758                deltaList.append(cval-pval)
     1759            modeVals = np.inner(ISO['Var2OccMatrix'],deltaList)
     1760            for lbl,xyz,var,val,G2var in zip(ISO['OccVarList'],deltaList,
     1761                                             ISO['OccModeList'],modeVals,ISO['G2OccModeList']):
     1762                if G2var in constDict:
     1763                    ch = G2gd.HelpButton(panel2,fmtHelp(constDict[G2var],var))
     1764                    subSizer2.Add(ch,0,wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER,1)
     1765                else:
     1766                    subSizer2.Add((-1,-1))
     1767                subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,str(lbl)))
     1768                try:
     1769                    value = G2py3.FormatValue(xyz)
     1770                except TypeError:
     1771                    value = str(xyz)           
     1772                subSizer1.Add(wx.StaticText(panel1,wx.ID_ANY,value),0,wx.ALIGN_RIGHT)
     1773                #subSizer.Add((10,-1))
     1774                subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,str(var)))
     1775                try:
     1776                    value = G2py3.FormatValue(val)
     1777                except TypeError:
     1778                    value = str(val)           
     1779                subSizer2.Add(wx.StaticText(panel2,wx.ID_ANY,value),0,wx.ALIGN_RIGHT)
     1780
    17011781        # finish up ScrolledPanel
    17021782        panel1.SetSizer(subSizer1)
     
    17271807        dlg.ShowModal()
    17281808        dlg.Destroy()
    1729        
    17301809       
    17311810    def OnReImport(event):
  • trunk/imports/G2phase_ISO.py

    r1160 r1161  
    1919
    2020class ISODISTORTPhaseReader(G2IO.ImportPhase):
    21     varLookup = {'dx':'dAx','dy':'dAy','dz':'dAz'}
     21    varLookup = {'dx':'dAx','dy':'dAy','dz':'dAz','do':'Afrac'}
    2222    def __init__(self):
    2323        super(self.__class__,self).__init__( # fancy way to say ImportPhase.__init__
     
    199199                self.Phase['General']['Name'] = name.strip()[:20]
    200200                #----------------------------------------------------------------------
    201                 # now read in the ISODISTORT modes
     201                # now read in the ISODISTORT displacement modes
    202202                #----------------------------------------------------------------------
    203                 modelist = []
    204                 shortmodelist = []
    205                 for lbl in blk.get('_iso_displacivemode_label'):
    206                     modelist.append(lbl)
    207                     # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
    208                     # where SSSSS is the parent spacegroup, [x,y,z] is a location
    209                     regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
    210                     # this extracts the AAAAA and BBBBB parts of the string
    211                     if regexp:
    212                         lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
    213                     G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
    214                    
    215                 # read in the coordinate offset variables names and map them to G2 names/objects
    216                 coordVarLbl = []
    217                 G2varLbl = []
    218                 G2varObj = []
    219                 error = False
    220                 for lbl in blk.get('_iso_deltacoordinate_label'):
    221                     coordVarLbl.append(lbl)
    222                     if '_' in lbl:
    223                         albl = lbl[:lbl.rfind('_')]
    224                         vlbl = lbl[lbl.rfind('_')+1:]
    225                     else:
    226                         self.warnings += ' ERROR: _iso_deltacoordinate_label not parsed: '+lbl
    227                         error = True
    228                         continue
    229                     if albl not in atomlbllist:
    230                         self.warnings += ' ERROR: _iso_deltacoordinate_label atom not found: '+lbl
    231                         error = True
    232                         continue
    233                     else:
    234                         anum = atomlbllist.index(albl)
    235                     var = self.varLookup.get(vlbl)
    236                     if not var:
    237                         self.warnings += ' ERROR: _iso_deltacoordinate_label variable not found: '+lbl
    238                         error = True
    239                         continue
    240                     G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID
    241                     G2varObj.append(G2obj.G2VarObj(
    242                         (self.Phase['ranId'],None,var,ranIdlookup[albl])
    243                         ))
    244                 if error:
    245                     raise Exception,"Error decoding variable labels"
    246                    
    247                 if len(G2varObj) != len(modelist):
    248                     print "non-square input"
    249                     raise Exception,"Rank of _iso_displacivemode != _iso_deltacoordinate"
    250                
    251                 error = False
    252                 ParentCoordinates = {}
    253                 for lbl,exp in zip(
    254                     blk.get('_iso_coordinate_label'),
    255                     blk.get('_iso_coordinate_formula'),
    256                     ):
    257                     if '_' in lbl:
    258                         albl = lbl[:lbl.rfind('_')]
    259                         vlbl = lbl[lbl.rfind('_')+1:]
    260                     else:
    261                         self.warnings += ' ERROR: _iso_coordinate_label not parsed: '+lbl
    262                         error = True
    263                         continue
    264                     if vlbl not in 'xyz' or len(vlbl) != 1:
    265                         self.warnings += ' ERROR: _iso_coordinate_label coordinate not parsed: '+lbl
    266                         error = True
    267                         continue
    268                     i = 'xyz'.index(vlbl)
    269                     if not ParentCoordinates.get(albl):
    270                         ParentCoordinates[albl] = [None,None,None]
    271                     if '+' in exp:
    272                         val = exp.split('+')[0].strip()
    273                     else:
    274                         self.warnings += ' ERROR: _iso_coordinate_formula not parsed: '+lbl
    275                         error = True
    276                         continue
    277                     val = G2p3.FormulaEval(val)
    278                     if val is None:
    279                         self.warnings += ' ERROR: _iso_coordinate_formula coordinate not interpreted: '+lbl
    280                         error = True
    281                         continue
    282                     ParentCoordinates[albl][i] = val
    283                 if error:
    284                     raise Exception,"Error decoding variable labels"
    285                 # get mapping of modes to atomic coordinate displacements
    286                 displacivemodematrix = np.zeros((len(G2varObj),len(G2varObj)))
    287                 for row,col,val in zip(
    288                     blk.get('_iso_displacivemodematrix_row'),
    289                     blk.get('_iso_displacivemodematrix_col'),
    290                     blk.get('_iso_displacivemodematrix_value'),):
    291                     displacivemodematrix[int(row)-1,int(col)-1] = float(val)
    292                 # Invert to get mapping of atom displacements to modes
    293                 displacivemodeInvmatrix = np.linalg.inv(displacivemodematrix)
    294                 # create the constraints
    295203                self.Constraints = []
    296                 for i,row in enumerate(displacivemodeInvmatrix):
    297                     constraint = []
    298                     for j,(lbl,k) in enumerate(zip(coordVarLbl,row)):
    299                         if k == 0: continue
    300                         constraint.append([k,G2varObj[j]])
    301                     constraint += [shortmodelist[i],False,'f']
    302                     self.Constraints.append(constraint)
    303                 # save the ISODISTORT info for "mode analysis"
    304                 self.Phase['ISODISTORT'] = {
    305                     'IsoModeList' : modelist,
    306                     'G2ModeList' : shortmodelist,
    307                     'IsoVarList' : coordVarLbl,
    308                     'G2VarList' : G2varObj,
    309                     'ParentStructure' : ParentCoordinates,
    310                     'Var2ModeMatrix' : displacivemodeInvmatrix,
    311                     'Mode2VarMatrix' : displacivemodematrix,
    312                     }
    313                 # make explaination dictionary
    314204                explaination = {}
    315                 for mode,shortmode in zip(modelist,shortmodelist):
    316                     explaination[shortmode] = "ISODISTORT full name "+str(mode)
    317                 self.Constraints.append(explaination)
     205                if blk.get('_iso_displacivemode_label'):
     206                    modelist = []
     207                    shortmodelist = []
     208                    for lbl in blk.get('_iso_displacivemode_label'):
     209                        modelist.append(lbl)
     210                        # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
     211                        # where SSSSS is the parent spacegroup, [x,y,z] is a location
     212                        regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
     213                        # this extracts the AAAAA and BBBBB parts of the string
     214                        if regexp:
     215                            lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
     216                        G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
     217                    # read in the coordinate offset variables names and map them to G2 names/objects
     218                    coordVarLbl = []
     219                    G2varLbl = []
     220                    G2varObj = []
     221                    error = False
     222                    for lbl in blk.get('_iso_deltacoordinate_label'):
     223                        coordVarLbl.append(lbl)
     224                        if '_' in lbl:
     225                            albl = lbl[:lbl.rfind('_')]
     226                            vlbl = lbl[lbl.rfind('_')+1:]
     227                        else:
     228                            self.warnings += ' ERROR: _iso_deltacoordinate_label not parsed: '+lbl
     229                            error = True
     230                            continue
     231                        if albl not in atomlbllist:
     232                            self.warnings += ' ERROR: _iso_deltacoordinate_label atom not found: '+lbl
     233                            error = True
     234                            continue
     235                        else:
     236                            anum = atomlbllist.index(albl)
     237                        var = self.varLookup.get(vlbl)
     238                        if not var:
     239                            self.warnings += ' ERROR: _iso_deltacoordinate_label variable not found: '+lbl
     240                            error = True
     241                            continue
     242                        G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID
     243                        G2varObj.append(G2obj.G2VarObj(
     244                            (self.Phase['ranId'],None,var,ranIdlookup[albl])
     245                            ))
     246                    if error:
     247                        raise Exception,"Error decoding variable labels"
     248
     249                    if len(G2varObj) != len(modelist):
     250                        print "non-square input"
     251                        raise Exception,"Rank of _iso_displacivemode != _iso_deltacoordinate"
     252
     253                    error = False
     254                    ParentCoordinates = {}
     255                    for lbl,exp in zip(
     256                        blk.get('_iso_coordinate_label'),
     257                        blk.get('_iso_coordinate_formula'),
     258                        ):
     259                        if '_' in lbl:
     260                            albl = lbl[:lbl.rfind('_')]
     261                            vlbl = lbl[lbl.rfind('_')+1:]
     262                        else:
     263                            self.warnings += ' ERROR: _iso_coordinate_label not parsed: '+lbl
     264                            error = True
     265                            continue
     266                        if vlbl not in 'xyz' or len(vlbl) != 1:
     267                            self.warnings += ' ERROR: _iso_coordinate_label coordinate not parsed: '+lbl
     268                            error = True
     269                            continue
     270                        i = 'xyz'.index(vlbl)
     271                        if not ParentCoordinates.get(albl):
     272                            ParentCoordinates[albl] = [None,None,None]
     273                        if '+' in exp:
     274                            val = exp.split('+')[0].strip()
     275                            val = G2p3.FormulaEval(val)
     276                            if val is None:
     277                                self.warnings += ' ERROR: _iso_coordinate_formula coordinate not interpreted: '+lbl
     278                                error = True
     279                                continue
     280                        ParentCoordinates[albl][i] = val
     281                    if error:
     282                        print self.warnings
     283                        raise Exception,"Error decoding variable labels"
     284                    # get mapping of modes to atomic coordinate displacements
     285                    displacivemodematrix = np.zeros((len(G2varObj),len(G2varObj)))
     286                    for row,col,val in zip(
     287                        blk.get('_iso_displacivemodematrix_row'),
     288                        blk.get('_iso_displacivemodematrix_col'),
     289                        blk.get('_iso_displacivemodematrix_value'),):
     290                        displacivemodematrix[int(row)-1,int(col)-1] = float(val)
     291                    # Invert to get mapping of atom displacements to modes
     292                    displacivemodeInvmatrix = np.linalg.inv(displacivemodematrix)
     293                    # create the constraints
     294                    for i,row in enumerate(displacivemodeInvmatrix):
     295                        constraint = []
     296                        for j,(lbl,k) in enumerate(zip(coordVarLbl,row)):
     297                            if k == 0: continue
     298                            constraint.append([k,G2varObj[j]])
     299                        constraint += [shortmodelist[i],False,'f']
     300                        self.Constraints.append(constraint)
     301                    #----------------------------------------------------------------------
     302                    # save the ISODISTORT info for "mode analysis"
     303                    if 'ISODISTORT' not in self.Phase: self.Phase['ISODISTORT'] = {}
     304                    self.Phase['ISODISTORT'].update({
     305                        'IsoModeList' : modelist,
     306                        'G2ModeList' : shortmodelist,
     307                        'IsoVarList' : coordVarLbl,
     308                        'G2VarList' : G2varObj,
     309                        'ParentStructure' : ParentCoordinates,
     310                        'Var2ModeMatrix' : displacivemodeInvmatrix,
     311                        'Mode2VarMatrix' : displacivemodematrix,
     312                        })
     313                    # make explaination dictionary
     314                    for mode,shortmode in zip(modelist,shortmodelist):
     315                        explaination[shortmode] = "ISODISTORT full name "+str(mode)
     316                #----------------------------------------------------------------------
     317                # now read in the ISODISTORT occupancy modes
     318                #----------------------------------------------------------------------
     319                if blk.get('_iso_occupancymode_label'):
     320                    modelist = []
     321                    shortmodelist = []
     322                    for lbl in blk.get('_iso_occupancymode_label'):
     323                        modelist.append(lbl)
     324                        # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
     325                        # where SSSSS is the parent spacegroup, [x,y,z] is a location
     326                        regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
     327                        # this extracts the AAAAA and BBBBB parts of the string
     328                        if regexp:
     329                            lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
     330                        lbl = lbl.replace('order','o')
     331                        G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
     332                    # read in the coordinate offset variables names and map them to G2 names/objects
     333                    occVarLbl = []
     334                    G2varLbl = []
     335                    G2varObj = []
     336                    error = False
     337                    for lbl in blk.get('_iso_deltaoccupancy_label'):
     338                        occVarLbl.append(lbl)
     339                        if '_' in lbl:
     340                            albl = lbl[:lbl.rfind('_')]
     341                            vlbl = lbl[lbl.rfind('_')+1:]
     342                        else:
     343                            self.warnings += ' ERROR: _iso_deltaoccupancy_label not parsed: '+lbl
     344                            error = True
     345                            continue
     346                        if albl not in atomlbllist:
     347                            self.warnings += ' ERROR: _iso_deltaoccupancy_label atom not found: '+lbl
     348                            error = True
     349                            continue
     350                        else:
     351                            anum = atomlbllist.index(albl)
     352                        var = self.varLookup.get(vlbl)
     353                        if not var:
     354                            self.warnings += ' ERROR: _iso_deltaoccupancy_label variable not found: '+lbl
     355                            error = True
     356                            continue
     357                        G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID
     358                        G2varObj.append(G2obj.G2VarObj(
     359                            (self.Phase['ranId'],None,var,ranIdlookup[albl])
     360                            ))
     361                    if error:
     362                        raise Exception,"Error decoding variable labels"
     363
     364                    if len(G2varObj) != len(modelist):
     365                        print "non-square input"
     366                        raise Exception,"Rank of _iso_occupancymode != _iso_deltaoccupancy"
     367
     368                    error = False
     369                    ParentCoordinates = {}
     370                    for lbl,exp in zip(
     371                        blk.get('_iso_occupancy_label'),
     372                        blk.get('_iso_occupancy_formula'),
     373                        ):
     374                        if '_' in lbl:
     375                            albl = lbl[:lbl.rfind('_')]
     376                            vlbl = lbl[lbl.rfind('_')+1:]
     377                        else:
     378                            self.warnings += ' ERROR: _iso_occupancy_label not parsed: '+lbl
     379                            error = True
     380                            continue
     381                        if vlbl != 'occ':
     382                            self.warnings += ' ERROR: _iso_occupancy_label coordinate not parsed: '+lbl
     383                            error = True
     384                            continue
     385                        if '+' in exp:
     386                            val = exp.split('+')[0].strip()
     387                            val = G2p3.FormulaEval(val)
     388                            if val is None:
     389                                self.warnings += ' ERROR: _iso_occupancy_formula coordinate not interpreted: '+lbl
     390                                error = True
     391                                continue
     392                            ParentCoordinates[albl] = val
     393                    if error:
     394                        raise Exception,"Error decoding occupancy labels"
     395                    # get mapping of modes to atomic coordinate displacements
     396                    occupancymodematrix = np.zeros((len(G2varObj),len(G2varObj)))
     397                    for row,col,val in zip(
     398                        blk.get('_iso_occupancymodematrix_row'),
     399                        blk.get('_iso_occupancymodematrix_col'),
     400                        blk.get('_iso_occupancymodematrix_value'),):
     401                        occupancymodematrix[int(row)-1,int(col)-1] = float(val)
     402                    # Invert to get mapping of atom displacements to modes
     403                    occupancymodeInvmatrix = np.linalg.inv(occupancymodematrix)
     404                    # create the constraints
     405                    for i,row in enumerate(occupancymodeInvmatrix):
     406                        constraint = []
     407                        for j,(lbl,k) in enumerate(zip(occVarLbl,row)):
     408                            if k == 0: continue
     409                            constraint.append([k,G2varObj[j]])
     410                        constraint += [shortmodelist[i],False,'f']
     411                        self.Constraints.append(constraint)
     412                    #----------------------------------------------------------------------
     413                    # save the ISODISTORT info for "mode analysis"
     414                    if 'ISODISTORT' not in self.Phase: self.Phase['ISODISTORT'] = {}
     415                    self.Phase['ISODISTORT'].update({
     416                        'OccModeList' : modelist,
     417                        'G2OccModeList' : shortmodelist,
     418                        'OccVarList' : occVarLbl,
     419                        'G2OccVarList' : G2varObj,
     420                        'BaseOcc' : ParentCoordinates,
     421                        'Var2OccMatrix' : occupancymodeInvmatrix,
     422                        'Occ2VarMatrix' : occupancymodematrix,
     423                        })
     424                    # make explaination dictionary
     425                    for mode,shortmode in zip(modelist,shortmodelist):
     426                        explaination[shortmode] = "ISODISTORT full name "+str(mode)
     427                #----------------------------------------------------------------------
     428                # done with read
     429                #----------------------------------------------------------------------
     430                if explaination: self.Constraints.append(explaination)
    318431
    319432                # # debug: show the mode var to mode relations
Note: See TracChangeset for help on using the changeset viewer.