Ignore:
Timestamp:
May 27, 2019 10:02:43 PM (2 years ago)
Author:
toby
Message:

add SeqRes? section to scriptable; minor docs cleanup; show cell even if not fully refined in Seq Res table

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIscriptable.py

    r3999 r4001  
    122122:meth:`G2Project.pdfs`                                Provides a list of PDFs in the current project, as :class:`G2PDF` objects
    123123
     124:meth:`G2Project.seqref`                              Returns a :class:`G2SeqRefRes` object if there are Sequential Refinement results
     125
    124126:meth:`G2Project.do_refinements`                      This is passed a list of dictionaries, where each dict defines a refinement step.
    125127                                                      Passing a list with a single empty dict initiates a refinement with the current
     
    225227==================================================    ===============================================================================================================
    226228
     229---------------------
     230:class:`G2SeqRefRes`
     231---------------------
     232
     233  To work with Sequential Refinement results, object :class:`G2SeqRefRes`, encapsulates the sequential refinement table with methods:
     234
     235.. tabularcolumns:: |l|p{3.5in}|
     236
     237==================================================    ===============================================================================================================
     238method                                                Use
     239==================================================    ===============================================================================================================
     240:meth:`G2SeqRefRes.histograms`                         Provides a list of histograms used in the Sequential Refinement
     241:meth:`G2SeqRefRes.get_cell_and_esd`                   Returns cell dimensions and standard uncertainies for a phase and histogram from the Sequential Refinement
     242==================================================    ===============================================================================================================
    227243
    228244----------------------
     
    21032119        return G2PDF(self.data[PDFname], PDFname, self)
    21042120
    2105     # def seqref(self):
    2106     #     """
    2107     #     Returns a sequential refinement results object, if present
    2108 
    2109     #     :returns: A :class:`G2SeqRefRes` object or None if not present
    2110     #     """
    2111     #     if 'Sequential results' not in self.data: return
    2112     #     return G2SeqRefRes(self.data['Sequential results']['data'], self)
     2121    def seqref(self):
     2122        """
     2123        Returns a sequential refinement results object, if present
     2124
     2125        :returns: A :class:`G2SeqRefRes` object or None if not present
     2126        """
     2127        if 'Sequential results' not in self.data: return
     2128        return G2SeqRefRes(self.data['Sequential results']['data'], self)
    21132129   
    21142130    def update_ids(self):
     
    37603776                    print(u'Unknown HAP key: '+key)
    37613777
    3762 # class G2SeqRefRes(G2ObjectWrapper):
    3763 #     '''Wrapper for a Sequential Refinement Results tree entry, containing the
    3764 #     results for a refinement
    3765 #     '''
    3766 #     def __init__(self, data, proj):
    3767 #         self.data = data
    3768 #         self.proj = proj
     3778class G2SeqRefRes(G2ObjectWrapper):
     3779    '''Wrapper for a Sequential Refinement Results tree entry, containing the
     3780    results for a refinement
     3781
     3782    As an example::
     3783
     3784        from __future__ import division, print_function
     3785        import os,sys
     3786        sys.path.insert(0,'/Users/toby/software/G2/GSASII')
     3787        PathWrap = lambda fil: os.path.join('/Users/toby/Scratch/SeqTut2019Mar',fil)
     3788        import GSASIIscriptable as G2sc
     3789        gpx = G2sc.G2Project(PathWrap('scr4.gpx'))
     3790        seq = gpx.seqref()
     3791        lbl = ('a','b','c','alpha','beta','gamma','Volume')
     3792        for j,h in enumerate(seq.histograms()):
     3793            cell,cellU,uniq = seq.get_cell_and_esd(1,h)
     3794            print(h)
     3795            print([cell[i] for i in list(uniq)+[6]])
     3796            print([cellU[i] for i in list(uniq)+[6]])
     3797            print('')
     3798        print('printed',[lbl[i] for i in list(uniq)+[6]])
     3799
     3800    '''
     3801    def __init__(self, data, proj):
     3802        self.data = data
     3803        self.proj = proj
     3804        self.newCellDict = {} # dict with recp. cell tensor & Dij name
     3805        # newAtomDict = {} # dict with atom positions; relative & absolute
     3806        for name in self.data['histNames']:
     3807            self.newCellDict.update(self.data[name].get('newCellDict',{}))
     3808            #newAtomDict.update(self.data[name].get('newAtomDict',{}) # dict with atom positions; relative & absolute
     3809        #ESDlookup = {self.newCellDict[item][0]:item for item in self.newCellDict}
     3810        #Dlookup = {item:self.newCellDict[item][0] for item in self.newCellDict}
     3811        # Possible error: the next might need to be data[histNames[0]]['varyList']
     3812        #atomLookup = {newAtomDict[item][0]:item for item in newAtomDict if item in self.data['varyList']}
     3813        #Dlookup.update({atomLookup[parm]:parm for parm in atomLookup}
     3814        #ESDlookup.update({parm:atomLookup[parm] for parm in atomLookup})
     3815
     3816#    @property
     3817    def histograms(self):
     3818        '''returns a list of histograms in the squential fit
     3819        '''
     3820        return self.data['histNames']
     3821
     3822    def get_cell_and_esd(self,phase,hist):
     3823        '''Returns a vector of cell lengths and esd values
     3824
     3825        :param phase: A phase, which may be specified as a phase object
     3826          (see :class:`G2Phase`), the phase name (str) or the index number (int)
     3827          of the phase in the project, numbered starting from 0.
     3828        :param hist: Specify a histogram or using the histogram name (str)
     3829          or the index number (int) of the histogram in the sequential
     3830          refinement (not the project), numbered starting from 0.
     3831        :returns: cell,cellESD,uniqCellIndx where cell (list)
     3832          with the unit cell parameters (a,b,c,alpha,beta,gamma,Volume);
     3833          cellESD are the standard uncertainties on the 7 unit cell
     3834          parameters; and uniqCellIndx is a tuple with indicies for the
     3835          unique (non-symmetry determined) unit parameters (e.g.
     3836          [0,2] for a,c in a tetragonal cell)
     3837        '''
     3838        def striphist(var,insChar=''):
     3839            'strip a histogram number from a var name'
     3840            sv = var.split(':')
     3841            if len(sv) <= 1: return var
     3842            if sv[1]:
     3843                sv[1] = insChar
     3844            return ':'.join(sv)
     3845        import GSASIIlattice as G2lat
     3846        import GSASIIstrIO as G2stIO
    37693847       
    3770 # #    @property
    3771 #     def histograms(self):
    3772 #         '''returns a list of histograms in the squential fit
    3773 #         '''
    3774 #         return self.data['histNames']
    3775 
    3776 #     def get_cell_and_esd(self,phase,hist):
    3777 #         import GSASIIlattice as G2lat
    3778 #         cellGUIlist = [
    3779 #         [['m3','m3m'],(0,)],
    3780 #         [['3R','3mR'],(0,3)],
    3781 #         [['3','3m1','31m','6/m','6/mmm','4/m','4/mmm'],(0,2)],
    3782 #         [['mmm'],(0,1,2)],
    3783 #         [['2/m'+'a'],(0,1,2,3)],
    3784 #         [['2/m'+'b'],(0,1,2,4)],
    3785 #         [['2/m'+'c'],(0,1,2,5)],
    3786 #         [['-1'],(0,1,2,3,4,5)],
    3787 #         ]
    3788 
    3789 #         initialCell = {}
    3790 #         seqData,histData = self.RefData(hist)
    3791 #         hId = histData['data'][0]['hId']
    3792 #         phasedict = self.proj.phase(phase).data
    3793 #         pId = phasedict['pId']
    3794 #         pfx = str(pId)+'::' # prefix for A values from phase
    3795 #         phfx = '%d:%d:'%(pId,hId) # Dij prefix
    3796 #         RcellLbls = [pfx+'A'+str(i) for i in range(6)]
    3797 #         RecpCellTerms = G2lat.cell2A(phasedict['General']['Cell'][1:7])
    3798 #         zeroDict = dict(zip(RcellLbls[pId],6*[0.,]))
    3799 #         SGdata = phasedict['General']['SGData']
    3800 #         laue = SGdata['SGLaue']
    3801 #         if laue == '2/m':
    3802 #             laue += SGdata['SGUniq']
    3803 #         for symlist,celllist in cellGUIlist:
    3804 #             if laue in symlist:
    3805 #                 uniqCellIndx = celllist
    3806 #                 break
    3807 #         else: # should not happen
    3808 #             uniqCellIndx = list(range(6))
    3809 #         for i in uniqCellIndx:
    3810 #             initialCell[str(pId)+'::A'+str(i)] =  RecpCellTerms[i]
    3811 
    3812 
    3813 #         esdLookUp = {}
    3814 #         dLookup = {}
    3815 #         # note that varyList keys are p:h:Dij while newCellDict keys are p::Dij
    3816 #         for nKey in seqData['newCellDict']:
    3817 #             uniqCellIndx = list(range(6))
    3818 #         for i in uniqCellIndx:
    3819 #             initialCell[str(pId)+'::A'+str(i)] =  RecpCellTerms[i]
    3820 
    3821 
    3822 #         esdLookUp = {}
    3823 #         dLookup = {}
    3824 #         # note that varyList keys are p:h:Dij while newCellDict keys are p::Dij
    3825 #         for nKey in seqData['newCellDict']:
    3826 #             p = nKey.find('::')+1
    3827 #             vKey = nKey[:p] + str(hId) + nKey[p:]
    3828 #             if phfx+item.split('::')[1] in seqData['varyList']:
    3829 #                 esdLookUp[newCellDict[item][0]] = item
    3830 #                 dLookup[item] = newCellDict[item][0]
    3831 #         covData = {'varyList': [dLookup.get(striphist(v),v) for v in seqData['varyList']],
    3832 #                 'covMatrix': seqData['covMatrix']}
    3833 #         A = RecpCellTerms[pId][:] # make copy of starting A values
     3848        uniqCellLookup = [
     3849        [['m3','m3m'],(0,)],
     3850        [['3R','3mR'],(0,3)],
     3851        [['3','3m1','31m','6/m','6/mmm','4/m','4/mmm'],(0,2)],
     3852        [['mmm'],(0,1,2)],
     3853        [['2/m'+'a'],(0,1,2,3)],
     3854        [['2/m'+'b'],(0,1,2,4)],
     3855        [['2/m'+'c'],(0,1,2,5)],
     3856        [['-1'],(0,1,2,3,4,5)],
     3857        ]
     3858
     3859        seqData,histData = self.RefData(hist)
     3860        hId = histData['data'][0]['hId']
     3861        phasedict = self.proj.phase(phase).data
     3862        pId = phasedict['pId']
     3863        pfx = str(pId)+'::' # prefix for A values from phase
     3864        phfx = '%d:%d:'%(pId,hId) # Dij prefix
     3865        # get unit cell & symmetry for phase
     3866        RecpCellTerms = G2lat.cell2A(phasedict['General']['Cell'][1:7])
     3867        zeroDict = {pfx+'A'+str(i):0.0 for i in range(6)}
     3868        SGdata = phasedict['General']['SGData']
     3869        # determine the cell items not defined by symmetry
     3870        laue = SGdata['SGLaue'][:]
     3871        if laue == '2/m':
     3872            laue += SGdata['SGUniq']
     3873        for symlist,celllist in uniqCellLookup:
     3874            if laue in symlist:
     3875                uniqCellIndx = celllist
     3876                break
     3877        else: # should not happen
     3878            uniqCellIndx = list(range(6))
     3879        initialCell = {}
     3880        for i in uniqCellIndx:
     3881            initialCell[str(pId)+'::A'+str(i)] =  RecpCellTerms[i]
     3882
     3883        esdLookUp = {}
     3884        dLookup = {}
     3885        # note that varyList keys are p:h:Dij while newCellDict keys are p::Dij
     3886        for nKey in seqData['newCellDict']:
     3887            p = nKey.find('::')+1
     3888            vKey = nKey[:p] + str(hId) + nKey[p:]
     3889            if vKey in seqData['varyList']:
     3890                esdLookUp[self.newCellDict[nKey][0]] = nKey
     3891                dLookup[nKey] = self.newCellDict[nKey][0]
     3892        covData = {'varyList': [dLookup.get(striphist(v),v) for v in seqData['varyList']],
     3893                'covMatrix': seqData['covMatrix']}
     3894        A = RecpCellTerms[:] # make copy of starting A values
     3895
     3896        for i,j in enumerate(('D11','D22','D33','D12','D13','D23')):
     3897            var = pfx+'A'+str(i)
     3898            Dvar = phfx+j
     3899            # apply Dij value if non-zero
     3900            if Dvar in seqData['parmDict']:
     3901                A[i] += seqData['parmDict'][Dvar]
     3902            # override with fit result if is Dij varied
     3903            try:
     3904                A[i] = seqData['newCellDict'][esdLookUp[var]][1] # get refined value
     3905            except KeyError:
     3906                pass
     3907        Albls = [pfx+'A'+str(i) for i in range(6)]
     3908        cellDict = dict(zip(Albls,A))
    38343909
    38353910       
     3911        A,zeros = G2stIO.cellFill(pfx,SGdata,cellDict,zeroDict)
     3912        # convert to direct cell
     3913        c = G2lat.A2cell(A)
     3914        vol = G2lat.calc_V(A)
     3915        cE = G2stIO.getCellEsd(pfx,SGdata,A,covData)
     3916        return list(c)+[vol],cE,uniqCellIndx
     3917   
    38363918    def RefData(self,hist):
     3919        '''Provides access to the output from a particular histogram
     3920
     3921        :param hist: Specify a histogram or using the histogram name (str)
     3922          or the index number (int) of the histogram in the sequential
     3923          refinement (not the project), numbered starting from 0.
     3924        :returns: a list of dicts where the first element has sequential
     3925          refinement results and the second element has the contents of
     3926          the histogram tree items.
     3927        '''
    38373928        try:
    38383929            hist = self.data['histNames'][hist]
     
    38493940class G2PDF(G2ObjectWrapper):
    38503941    """Wrapper for a PDF tree entry, containing the information needed to
    3851     compute a PDF and the S(Q, G(r) etc. after the computation is done.
     3942    compute a PDF and the S(Q), G(r) etc. after the computation is done.
    38523943    Note that in a GSASIIscriptable script, instances of G2PDF will be created by
    38533944    calls to :meth:`G2Project.add_PDF` or :meth:`G2Project.pdf`, not via calls
    38543945    to :meth:`G2PDF.__init__`.
    38553946
    3856     Example use of G2PDF::
     3947    Example use of :class:`G2PDF`::
    38573948
    38583949       gpx.add_PDF('250umSiO2.pdfprm',0)
Note: See TracChangeset for help on using the changeset viewer.