Changeset 4379


Ignore:
Timestamp:
Mar 22, 2020 8:53:24 PM (19 months ago)
Author:
toby
Message:

fix isodistort constraint processing

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIconstrGUI.py

    r4270 r4379  
    126126#####  Constraints
    127127################################################################################           
    128        
    129128def UpdateConstraints(G2frame,data):
    130129    '''Called when Constraints tree item is selected.
  • trunk/GSASIIdataGUI.py

    r4377 r4379  
    960960            self.GPXtree.Expand(psub)
    961961            self.PickIdText = None
    962 
     962           
     963            # add constraints imported with phase to tree
     964            #    at present, constraints are generated only in ISODISTORT_proc in the
     965            #    CIF import
    963966            if rd.Constraints:
    964967                sub = GetGPXtreeItemId(self,self.root,'Constraints') # was created in CheckNotebook if needed
     
    970973                        if '_Explain' not in Constraints: Constraints['_Explain'] = {}
    971974                        Constraints['_Explain'].update(i)
    972                         continue
    973                     Constraints['Phase'].append(i)
     975                    else:
     976                        Constraints['Phase'].append(i)
    974977        if not newPhaseList: return # somehow, no new phases
    975978        # get a list of existing histograms
  • trunk/GSASIImapvars.py

    r4370 r4379  
    13361336   
    13371337    :param list constList: a list of dicts containing constraint expressions
    1338     :param \*dict1: one or more dicts containing GSAS-II parameters and their values
     1338    :param \*dicts: one or more dicts containing GSAS-II parameters and their values
    13391339       can be specified
    13401340    :returns: an empty string if there were no errors, or an error message listing
     
    13521352    for const in constList:
    13531353        for key in const:
    1354             try:
     1354            if key.startswith('_'): continue
     1355            try: # is this already a float, etc?
    13551356                1+const[key]
    13561357                continue
  • trunk/imports/G2phase_CIF.py

    r4158 r4379  
    3434GSASIIpath.SetVersionNumber("$Revision$")
    3535import CifFile as cif # PyCifRW from James Hester
     36#debug = GSASIIpath.GetConfigValue('debug')
     37debug = False
    3638
    3739class CIFPhaseReader(G2obj.ImportPhase):
     
    5153
    5254    def Reader(self,filename, ParentFrame=None, usedRanIdList=[], **unused):
    53         self.isodistort_warnings = ''
     55        isodistort_warnings = '' # errors that would prevent an isodistort analysis
    5456        self.Phase = G2obj.SetNewPhase(Name='new phase') # create a new empty phase dict
    5557        # make sure the ranId is really unique!
     
    361363            atomkeys = [i.lower() for i in atomloop.keys()]
    362364            if not blk.get('_atom_site_type_symbol'):
    363                 self.isodistort_warnings += '\natom types are missing. \n Check & revise atom types as needed'
     365                isodistort_warnings += '\natom types are missing. \n Check & revise atom types as needed'
    364366            if magnetic:
    365367                try:
     
    579581                    atomlist.append(SSdict)
    580582            if len(atomlbllist) != len(self.Phase['Atoms']):
    581                 self.isodistort_warnings += '\nRepeated atom labels prevents ISODISTORT decode'
     583                isodistort_warnings += '\nRepeated atom labels prevents ISODISTORT decode'
    582584            for lbl in phasenamefields: # get a name for the phase
    583585                name = blk.get(lbl)
     
    622624                if not self.Phase['General']['SGData']['SGFixed']:
    623625                    self.Phase['General']['SSGData'] = G2spc.SSpcGroup(SGData,SuperSg)[1]
    624             if not self.isodistort_warnings:
    625                 if blk.get('_iso_displacivemode_label') or blk.get('_iso_occupancymode_label'):
     626            if self.ISODISTORT_test(blk):
     627                if isodistort_warnings:
     628                    self.warnings += isodistort_warnings
     629                else:
    626630                    self.errors = "Error while processing ISODISTORT constraints"
    627631                    self.ISODISTORT_proc(blk,atomlbllist,ranIdlookup)
    628             else:
    629                 self.warnings += self.isodistort_warnings
     632                    self.errors = ""
    630633            returnstat = True
    631634        return returnstat
    632 
     635       
     636    def ISODISTORT_test(self,blk):
     637        '''Test if there is any ISODISTORT information in CIF
     638
     639        At present only _iso_displacivemode... and _iso_occupancymode... are
     640        tested.
     641        '''
     642        for i in ('_iso_displacivemode_label',
     643                  '_iso_occupancymode_label'):
     644            if blk.get(i): return True
     645        return False
     646       
    633647    def ISODISTORT_proc(self,blk,atomlbllist,ranIdlookup):
    634         'Process ISODISTORT items to create constraints etc.'
     648        '''Process ISODISTORT items to create constraints etc.
     649        Constraints are generated from information extracted from
     650        loop_'s beginning with _iso_ and are placed into
     651        self.Constraints, which contains a list of
     652        :ref:`constraints tree items <Constraint_definitions_table>`
     653        and one dict.
     654        The dict contains help text for each generated ISODISTORT variable
     655
     656        At present only _iso_displacivemode... and _iso_occupancymode... are
     657        processed. Not yet processed: _iso_magneticmode...,
     658        _iso_rotationalmode... & _iso_strainmode...
     659        '''
    635660        varLookup = {'dx':'dAx','dy':'dAy','dz':'dAz','do':'Afrac'}
    636661        'Maps ISODISTORT parm names to GSAS-II names'
     
    645670            for lbl in blk.get('_iso_displacivemode_label'):
    646671                modelist.append(lbl)
    647                 # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
    648                 # where SSSSS is the parent spacegroup, [x,y,z] is a location
    649                 regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
    650                 # this extracts the AAAAA and BBBBB parts of the string
    651                 if regexp:
    652                     lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
    653                 G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
     672                ISODISTORT_shortLbl(lbl,shortmodelist) # shorten & make unique
    654673            # read in the coordinate offset variables names and map them to G2 names/objects
    655674            coordVarLbl = []
     
    761780            for lbl in blk.get('_iso_occupancymode_label'):
    762781                modelist.append(lbl)
    763                 # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
    764                 # where SSSSS is the parent spacegroup, [x,y,z] is a location
    765                 regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
    766                 # this extracts the AAAAA and BBBBB parts of the string
    767                 if regexp:
    768                     lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
    769                 lbl = lbl.replace('order','o')
    770                 G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
     782                ISODISTORT_shortLbl(lbl,shortmodelist) # shorten & make unique
    771783            # read in the coordinate offset variables names and map them to G2 names/objects
    772784            occVarLbl = []
     
    869881        if explaination: self.Constraints.append(explaination)
    870882
    871         # # debug: show the mode var to mode relations
    872         # for i,row in enumerate(displacivemodeInvmatrix):
    873         #     l = ''
    874         #     for j,(lbl,k) in enumerate(zip(coordVarLbl,row)):
    875         #         if k == 0: continue
    876         #         if l: l += ' + '
    877         #         #l += lbl+' * '+str(k)
    878         #         l += G2varLbl[j]+' * '+str(k)
    879         #     print str(i) + ': '+shortmodelist[i]+' = '+l
    880         # print 70*'='
    881 
    882         # # debug: Get the ISODISTORT offset values
    883         # coordVarDelta = {}
    884         # for lbl,val in zip(
    885         #     blk.get('_iso_deltacoordinate_label'),
    886         #     blk.get('_iso_deltacoordinate_value'),):
    887         #     coordVarDelta[lbl] = float(val)
    888         # modeVarDelta = {}
    889         # for lbl,val in zip(
    890         #     blk.get('_iso_displacivemode_label'),
    891         #     blk.get('_iso_displacivemode_value'),):
    892         #     modeVarDelta[lbl] = cif.get_number_with_esd(val)[0]
    893 
    894         # print 70*'='
    895         # # compute the mode values from the reported coordinate deltas
    896         # for i,row in enumerate(displacivemodeInvmatrix):
    897         #     l = ''
    898         #     sl = ''
    899         #     s = 0.
    900         #     for lbl,k in zip(coordVarLbl,row):
    901         #         if k == 0: continue
    902         #         if l: l += ' + '
    903         #         l += lbl+' * '+str(k)
    904         #         if sl: sl += ' + '
    905         #         sl += str(coordVarDelta[lbl])+' * '+str(k)
    906         #         s += coordVarDelta[lbl] * k
    907         #     print 'a'+str(i)+' = '+l
    908         #     print '\t= '+sl
    909         #     print  modelist[i],shortmodelist[i],modeVarDelta[modelist[i]],s
    910         #     print
    911 
    912         # print 70*'='
    913         # # compute the coordinate displacements from the reported mode values
    914         # for i,lbl,row in zip(range(len(coordVarLbl)),coordVarLbl,displacivemodematrix):
    915         #     l = ''
    916         #     sl = ''
    917         #     s = 0.0
    918         #     for j,k in enumerate(row):
    919         #         if k == 0: continue
    920         #         if l: l += ' + '
    921         #         l += 'a'+str(j+1)+' * '+str(k)
    922         #         if sl: sl += ' + '
    923         #         sl += str(shortmodelist[j]) +' = '+ str(modeVarDelta[modelist[j]]) + ' * '+str(k)
    924         #         s += modeVarDelta[modelist[j]] * k
    925         #     print lbl+' = '+l
    926         #     print '\t= '+sl
    927         #     print lbl,G2varLbl[i],coordVarDelta[lbl],s
    928         #     print
     883        if not debug: return
     884
     885        # debug: show the mode var to mode relations
     886        print("shortname ==> ISODISTORT full name")
     887        for mode,shortmode in zip(modelist,shortmodelist):
     888            print(shortmode,' ==>', mode)
     889        print()
     890        for i,row in enumerate(displacivemodeInvmatrix):
     891            l = ''
     892            for j,(lbl,k) in enumerate(zip(coordVarLbl,row)):
     893                if k == 0: continue
     894                if l: l += ' + '
     895                #l += lbl+' * '+str(k)
     896                l += G2varLbl[j]+' * '+str(k)
     897            print( str(i) + ': '+shortmodelist[i]+' = '+l)
     898        print( 70*'=')
     899
     900        # debug: Get the ISODISTORT offset values
     901        coordVarDelta = {}
     902        for lbl,val in zip(
     903            blk.get('_iso_deltacoordinate_label'),
     904            blk.get('_iso_deltacoordinate_value'),):
     905            coordVarDelta[lbl] = float(val)
     906        modeVarDelta = {}
     907        for lbl,val in zip(
     908            blk.get('_iso_displacivemode_label'),
     909            blk.get('_iso_displacivemode_value'),):
     910            modeVarDelta[lbl] = cif.get_number_with_esd(val)[0]
     911
     912        print( 70*'=')
     913        # compute the mode values from the reported coordinate deltas
     914        for i,row in enumerate(displacivemodeInvmatrix):
     915            l = ''
     916            sl = ''
     917            s = 0.
     918            for lbl,k in zip(coordVarLbl,row):
     919                if k == 0: continue
     920                if l: l += ' + '
     921                l += lbl+' * '+str(k)
     922                if sl: sl += ' + '
     923                sl += str(coordVarDelta[lbl])+' * '+str(k)
     924                s += coordVarDelta[lbl] * k
     925            print('a'+str(i)+' = '+l)
     926            print('\t= '+sl)
     927            print(modelist[i],shortmodelist[i],modeVarDelta[modelist[i]],s)
     928            print()
     929
     930        print( 70*'=')
     931        # compute the coordinate displacements from the reported mode values
     932        for i,lbl,row in zip(range(len(coordVarLbl)),coordVarLbl,displacivemodematrix):
     933            l = ''
     934            sl = ''
     935            s = 0.0
     936            for j,k in enumerate(row):
     937                if k == 0: continue
     938                if l: l += ' + '
     939                l += 'a'+str(j+1)+' * '+str(k)
     940                if sl: sl += ' + '
     941                sl += str(shortmodelist[j]) +' = '+ str(modeVarDelta[modelist[j]]) + ' * '+str(k)
     942                s += modeVarDelta[modelist[j]] * k
     943            print( lbl+' = '+l)
     944            print( '\t= '+sl)
     945            print( lbl,G2varLbl[i],coordVarDelta[lbl],s)
     946            print()
    929947
    930948        # determine the coordinate delta values from deviations from the parent structure
    931         # for atmline in self.Phase['Atoms']:
    932         #     lbl = atmline[0]
    933         #     x,y,z = atmline[3:6]
    934         #     if lbl not in ParentCoordinates:
    935         #         print lbl,x,y,z
    936         #         continue
    937         #     px,py,pz = ParentCoordinates[lbl]
    938         #     print lbl,x,y,z,x-px,y-py,z-pz
     949        for atmline in self.Phase['Atoms']:
     950            lbl = atmline[0]
     951            x,y,z = atmline[3:6]
     952            if lbl not in ParentCoordinates:
     953                print( lbl,x,y,z)
     954                continue
     955            px,py,pz = ParentCoordinates[lbl]
     956            print( lbl,x,y,z,x-px,y-py,z-pz)
     957        print('\nGenerated constraints')
     958        for i in self.Constraints:
     959            if type(i) is dict:
     960                print('\n  constraint help')
     961                for key in i:
     962                    print('\t',key,i[key])
     963            elif i[-1] == 'f':
     964                print('\n\tNewvar',i[-3],' =')
     965                for m,j in i[:-3]:
     966                    print('\t\t+',m,' * ',j)
     967            else:
     968                print('  unexpected: ',repr(i))
     969                   
     970def ISODISTORT_shortLbl(lbl,shortmodelist):
     971    '''Shorten model labels and remove special characters
     972    '''
     973    regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)\[.*?\](.*)',lbl)
     974    # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)[...]BBBBB
     975    # where SSSSS is the parent spacegroup, [x,y,z] is a location, etc.
     976    if regexp:
     977        # this extracts the AAAAA and BBBBB parts of the string
     978        lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
     979    else:
     980        # try form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
     981        regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
     982        if regexp:
     983            lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
     984    lbl = lbl.replace('order','o')
     985    lbl = lbl.replace('+','_')
     986    lbl = lbl.replace('-','_')
     987    G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
     988               
Note: See TracChangeset for help on using the changeset viewer.