示例#1
0
def Refine(GPXfile, dlg=None, makeBack=True):
    'Global refinement -- refines to minimize against all histograms'
    import GSASIImpsubs as G2mp
    G2mp.InitMP()
    import pytexture as ptx
    ptx.pyqlmninit()  #initialize fortran arrays for spherical harmonics

    printFile = open(ospath.splitext(GPXfile)[0] + '.lst', 'w')
    G2stIO.ShowBanner(printFile)
    varyList = []
    parmDict = {}
    G2mv.InitVars()
    Controls = G2stIO.GetControls(GPXfile)
    G2stIO.ShowControls(Controls, printFile)
    calcControls = {}
    calcControls.update(Controls)
    constrDict, fixedList = G2stIO.GetConstraints(GPXfile)
    restraintDict = G2stIO.GetRestraints(GPXfile)
    Histograms, Phases = G2stIO.GetUsedHistogramsAndPhases(GPXfile)
    if not Phases:
        print(' *** ERROR - you have no phases to refine! ***')
        print(' *** Refine aborted ***')
        return False, 'No phases'
    if not Histograms:
        print(' *** ERROR - you have no data to refine with! ***')
        print(' *** Refine aborted ***')
        return False, 'No data'
    rigidbodyDict = G2stIO.GetRigidBodies(GPXfile)
    rbIds = rigidbodyDict.get('RBIds', {'Vector': [], 'Residue': []})
    rbVary, rbDict = G2stIO.GetRigidBodyModels(rigidbodyDict, pFile=printFile)
    Natoms,atomIndx,phaseVary,phaseDict,pawleyLookup,FFtables,BLtables,MFtables,maxSSwave = \
        G2stIO.GetPhaseData(Phases,restraintDict,rbIds,pFile=printFile)
    calcControls['atomIndx'] = atomIndx
    calcControls['Natoms'] = Natoms
    calcControls['FFtables'] = FFtables
    calcControls['BLtables'] = BLtables
    calcControls['MFtables'] = MFtables
    calcControls['maxSSwave'] = maxSSwave
    hapVary, hapDict, controlDict = G2stIO.GetHistogramPhaseData(
        Phases, Histograms, pFile=printFile)
    TwConstr, TwFixed = G2stIO.makeTwinFrConstr(Phases, Histograms, hapVary)
    constrDict += TwConstr
    fixedList += TwFixed
    calcControls.update(controlDict)
    histVary, histDict, controlDict = G2stIO.GetHistogramData(Histograms,
                                                              pFile=printFile)
    calcControls.update(controlDict)
    varyList = rbVary + phaseVary + hapVary + histVary
    parmDict.update(rbDict)
    parmDict.update(phaseDict)
    parmDict.update(hapDict)
    parmDict.update(histDict)
    G2stIO.GetFprime(calcControls, Histograms)
    # do constraint processing
    varyListStart = tuple(
        varyList
    )  # save the original varyList before dependent vars are removed
    try:
        groups, parmlist = G2mv.GroupConstraints(constrDict)
        G2mv.GenerateConstraints(groups, parmlist, varyList, constrDict,
                                 fixedList, parmDict)
        #print G2mv.VarRemapShow(varyList)
        #print 'DependentVars',G2mv.GetDependentVars()
        #print 'IndependentVars',G2mv.GetIndependentVars()
    except G2mv.ConstraintException:
        print(' *** ERROR - your constraints are internally inconsistent ***')
        #errmsg, warnmsg = G2mv.CheckConstraints(varyList,constrDict,fixedList)
        #print 'Errors',errmsg
        #if warnmsg: print 'Warnings',warnmsg
        return False, ' Constraint error'
#    print G2mv.VarRemapShow(varyList)

    ifSeq = False
    printFile.write('\n Refinement results:\n')
    printFile.write(135 * '-' + '\n')
    if True:
        #    try:
        covData = {}
        IfOK, Rvals, result, covMatrix, sig = RefineCore(
            Controls, Histograms, Phases, restraintDict, rigidbodyDict,
            parmDict, varyList, calcControls, pawleyLookup, ifSeq, printFile,
            dlg)
        if IfOK:
            sigDict = dict(zip(varyList, sig))
            newCellDict = G2stMth.GetNewCellParms(parmDict, varyList)
            newAtomDict = G2stMth.ApplyXYZshifts(parmDict, varyList)
            covData = {
                'variables': result[0],
                'varyList': varyList,
                'sig': sig,
                'Rvals': Rvals,
                'varyListStart': varyListStart,
                'covMatrix': covMatrix,
                'title': GPXfile,
                'newAtomDict': newAtomDict,
                'newCellDict': newCellDict,
                'freshCOV': True
            }
            # add the uncertainties into the esd dictionary (sigDict)
            sigDict.update(G2mv.ComputeDepESD(covMatrix, varyList, parmDict))
            G2mv.PrintIndependentVars(parmDict,
                                      varyList,
                                      sigDict,
                                      pFile=printFile)
            G2stMth.ApplyRBModels(parmDict, Phases, rigidbodyDict, True)
            G2stIO.SetRigidBodyModels(parmDict, sigDict, rigidbodyDict,
                                      printFile)
            G2stIO.SetPhaseData(parmDict, sigDict, Phases, rbIds, covData,
                                restraintDict, printFile)
            G2stIO.SetHistogramPhaseData(parmDict,
                                         sigDict,
                                         Phases,
                                         Histograms,
                                         calcControls['FFtables'],
                                         pFile=printFile)
            G2stIO.SetHistogramData(parmDict,
                                    sigDict,
                                    Histograms,
                                    calcControls['FFtables'],
                                    pFile=printFile)
            G2stIO.SetUsedHistogramsAndPhases(GPXfile, Histograms, Phases,
                                              rigidbodyDict, covData, makeBack)
            printFile.close()
            print(' Refinement results are in file: ' +
                  ospath.splitext(GPXfile)[0] + '.lst')
            print(' ***** Refinement successful *****')
        else:
            print('****ERROR - Refinement failed')
            raise G2obj.G2Exception('****ERROR - Refinement failed')


#    except G2obj.G2Exception(Msg):
#        printFile.close()
#        return False,Msg.msg

#for testing purposes!!!
    if DEBUG and IfOK:
        #needs: values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup
        fl = open(ospath.splitext(GPXfile)[0] + '.testDeriv', 'wb')
        cPickle.dump(result[0], fl, 1)
        cPickle.dump([Histograms, Phases, restraintDict, rigidbodyDict], fl, 1)
        cPickle.dump([constrDict, fixedList, G2mv.GetDependentVars()], fl, 1)
        cPickle.dump(parmDict, fl, 1)
        cPickle.dump(varyList, fl, 1)
        cPickle.dump(calcControls, fl, 1)
        cPickle.dump(pawleyLookup, fl, 1)
        fl.close()
    if dlg:
        return True, Rvals
示例#2
0
def SeqRefine(GPXfile, dlg, refPlotUpdate=None):
    '''Perform a sequential refinement -- cycles through all selected histgrams,
    one at a time
    '''
    import GSASIImpsubs as G2mp
    G2mp.InitMP()
    import pytexture as ptx
    ptx.pyqlmninit()  #initialize fortran arrays for spherical harmonics

    printFile = open(ospath.splitext(GPXfile)[0] + '.lst', 'w')
    G2fil.G2Print('Starting Sequential Refinement')
    G2stIO.ShowBanner(printFile)
    Controls = G2stIO.GetControls(GPXfile)
    G2stIO.ShowControls(Controls, printFile, SeqRef=True)
    restraintDict = G2stIO.GetRestraints(GPXfile)
    Histograms, Phases = G2stIO.GetUsedHistogramsAndPhases(GPXfile)
    if not Phases:
        G2fil.G2Print(' *** ERROR - you have no phases to refine! ***')
        G2fil.G2Print(' *** Refine aborted ***')
        return False, 'No phases'
    if not Histograms:
        G2fil.G2Print(' *** ERROR - you have no data to refine with! ***')
        G2fil.G2Print(' *** Refine aborted ***')
        return False, 'No data'
    rigidbodyDict = G2stIO.GetRigidBodies(GPXfile)
    rbIds = rigidbodyDict.get('RBIds', {'Vector': [], 'Residue': []})
    rbVary, rbDict = G2stIO.GetRigidBodyModels(rigidbodyDict, pFile=printFile)
    G2mv.InitVars()
    (Natoms, atomIndx, phaseVary, phaseDict, pawleyLookup, FFtables, BLtables,
     MFtables, maxSSwave) = G2stIO.GetPhaseData(Phases,
                                                restraintDict,
                                                rbIds,
                                                Print=False,
                                                pFile=printFile,
                                                seqRef=True)
    for item in phaseVary:
        if '::A0' in item:
            G2fil.G2Print(
                '**** WARNING - lattice parameters should not be refined in a sequential refinement ****'
            )
            G2fil.G2Print(
                '****           instead use the Dij parameters for each powder histogram            ****'
            )
            return False, 'Lattice parameter refinement error - see console message'
        if '::C(' in item:
            G2fil.G2Print(
                '**** WARNING - phase texture parameters should not be refined in a sequential refinement ****'
            )
            G2fil.G2Print(
                '****           instead use the C(L,N) parameters for each powder histogram               ****'
            )
            return False, 'Phase texture refinement error - see console message'
    if 'Seq Data' in Controls:
        histNames = Controls['Seq Data']
    else:  # patch from before Controls['Seq Data'] was implemented?
        histNames = G2stIO.GetHistogramNames(GPXfile, [
            'PWDR',
        ])
    if Controls.get('Reverse Seq'):
        histNames.reverse()
    SeqResult = G2stIO.GetSeqResult(GPXfile)
    #    SeqResult = {'SeqPseudoVars':{},'SeqParFitEqList':[]}
    Histo = {}
    NewparmDict = {}
    G2stIO.SetupSeqSavePhases(GPXfile)
    for ihst, histogram in enumerate(histNames):
        if GSASIIpath.GetConfigValue('Show_timing'): t1 = time.time()
        G2fil.G2Print('\nRefining with ' + str(histogram))
        G2mv.InitVars()
        (Natoms, atomIndx, phaseVary, phaseDict, pawleyLookup, FFtables,
         BLtables, MFtables, maxSSwave) = G2stIO.GetPhaseData(Phases,
                                                              restraintDict,
                                                              rbIds,
                                                              Print=False,
                                                              pFile=printFile,
                                                              seqRef=True)
        ifPrint = False
        if dlg:
            dlg.SetTitle('Residual for histogram ' + str(ihst))
        calcControls = {}
        calcControls['atomIndx'] = atomIndx
        calcControls['Natoms'] = Natoms
        calcControls['FFtables'] = FFtables
        calcControls['BLtables'] = BLtables
        calcControls['MFtables'] = MFtables
        calcControls['maxSSwave'] = maxSSwave
        if histogram not in Histograms:
            G2fil.G2Print("Error: not found!")
            continue
    #TODO - implement "Fix FXU" for seq refinement here - done?
        hId = Histograms[histogram]['hId']
        redphaseVary = phaseCheck(phaseVary, Phases, histogram)
        Histo = {
            histogram: Histograms[histogram],
        }
        hapVary, hapDict, controlDict = G2stIO.GetHistogramPhaseData(
            Phases, Histo, Print=False)
        calcControls.update(controlDict)
        histVary, histDict, controlDict = G2stIO.GetHistogramData(Histo, False)
        calcControls.update(controlDict)
        varyList = rbVary + redphaseVary + hapVary + histVary
        #        if not ihst:
        # save the initial vary list, but without histogram numbers on parameters
        saveVaryList = varyList[:]
        for i, item in enumerate(saveVaryList):
            items = item.split(':')
            if items[1]:
                items[1] = ''
            item = ':'.join(items)
            saveVaryList[i] = item
        if not ihst:
            SeqResult['varyList'] = saveVaryList
        else:
            SeqResult['varyList'] = list(
                set(SeqResult['varyList'] + saveVaryList))
        parmDict = {}
        parmDict.update(rbDict)
        parmDict.update(phaseDict)
        parmDict.update(hapDict)
        parmDict.update(histDict)
        if Controls['Copy2Next']:  # update with parms from last histogram
            #parmDict.update(NewparmDict) # don't use in case extra entries would cause a problem
            for parm in NewparmDict:
                if parm in parmDict:
                    parmDict[parm] = NewparmDict[parm]
        elif histogram in SeqResult:  # update phase from last seq ref
            NewparmDict = SeqResult[histogram].get('parmDict', {})
            for parm in NewparmDict:
                if '::' in parm and parm in parmDict:
                    parmDict[parm] = NewparmDict[parm]

        G2stIO.GetFprime(calcControls, Histo)
        # do constraint processing
        #reload(G2mv) # debug
        constrDict, fixedList = G2stIO.GetConstraints(GPXfile)
        varyListStart = tuple(
            varyList
        )  # save the original varyList before dependent vars are removed
        msg = G2mv.EvaluateMultipliers(constrDict, parmDict)
        if msg:
            return False, 'Unable to interpret multiplier(s): ' + msg
        try:
            groups, parmlist = G2mv.GenerateConstraints(varyList,
                                                        constrDict,
                                                        fixedList,
                                                        parmDict,
                                                        SeqHist=hId)
            #            if GSASIIpath.GetConfigValue('debug'): print("DBG_"+
            #                G2mv.VarRemapShow(varyList,True))
            #            print('DependentVars',G2mv.GetDependentVars())
            #            print('IndependentVars',G2mv.GetIndependentVars())
            constraintInfo = (groups, parmlist, constrDict, fixedList, ihst)
        except G2mv.ConstraintException:
            G2fil.G2Print(
                ' *** ERROR - your constraints are internally inconsistent ***'
            )
            #errmsg, warnmsg = G2mv.CheckConstraints(varyList,constrDict,fixedList)
            #print 'Errors',errmsg
            #if warnmsg: print 'Warnings',warnmsg
            return False, ' Constraint error'
        #print G2mv.VarRemapShow(varyList)
        if not ihst:
            # first histogram to refine against
            firstVaryList = []
            for item in varyList:
                items = item.split(':')
                if items[1]:
                    items[1] = ''
                item = ':'.join(items)
                firstVaryList.append(item)
            newVaryList = firstVaryList
        else:
            newVaryList = []
            for item in varyList:
                items = item.split(':')
                if items[1]:
                    items[1] = ''
                item = ':'.join(items)
                newVaryList.append(item)
        if newVaryList != firstVaryList and Controls['Copy2Next']:
            # variable lists are expected to match between sequential refinements when Copy2Next is on
            #print '**** ERROR - variable list for this histogram does not match previous'
            #print '     Copy of variables is not possible'
            #print '\ncurrent histogram',histogram,'has',len(newVaryList),'variables'
            combined = list(set(firstVaryList + newVaryList))
            c = [var for var in combined if var not in newVaryList]
            p = [var for var in combined if var not in firstVaryList]
            G2fil.G2Print('*** Variables change ***')
            for typ, vars in [('Removed', c), ('Added', p)]:
                line = '  ' + typ + ': '
                if vars:
                    for var in vars:
                        if len(line) > 70:
                            G2fil.G2Print(line)
                            line = '    '
                        line += var + ', '
                else:
                    line += 'none, '
                G2fil.G2Print(line[:-2])
            firstVaryList = newVaryList

        ifSeq = True
        printFile.write('\n Refinement results for histogram: %s\n' %
                        histogram)
        printFile.write(135 * '-' + '\n')
        try:
            IfOK, Rvals, result, covMatrix, sig = RefineCore(
                Controls,
                Histo,
                Phases,
                restraintDict,
                rigidbodyDict,
                parmDict,
                varyList,
                calcControls,
                pawleyLookup,
                ifSeq,
                printFile,
                dlg,
                refPlotUpdate=refPlotUpdate)
            G2fil.G2Print(
                '  wR = %7.2f%%, chi**2 = %12.6g, reduced chi**2 = %6.2f, last delta chi = %.4f, last shft/sig = %.4f'
                % (Rvals['Rwp'], Rvals['chisq'], Rvals['GOF']**
                   2, Rvals['DelChi2'], Rvals.get('Max shft/sig', np.nan)))
            # add the uncertainties into the esd dictionary (sigDict)
            if not IfOK:
                G2fil.G2Print(
                    '***** Sequential refinement failed at histogram ' +
                    histogram,
                    mode='warn')
                break
            sigDict = dict(zip(varyList, sig))
            # the uncertainties for dependent constrained parms into the esd dict
            sigDict.update(G2mv.ComputeDepESD(covMatrix, varyList, parmDict))

            # a dict with values & esds for dependent (constrained) parameters - avoid extraneous holds
            depParmDict = {
                i: (parmDict[i], sigDict[i])
                for i in varyListStart if i in sigDict and i not in varyList
            }
            newCellDict = copy.deepcopy(
                G2stMth.GetNewCellParms(parmDict, varyList))
            newAtomDict = copy.deepcopy(
                G2stMth.ApplyXYZshifts(parmDict, varyList))
            histRefData = {
                'variables': result[0],
                'varyList': varyList,
                'sig': sig,
                'Rvals': Rvals,
                'varyListStart': varyListStart,
                'covMatrix': covMatrix,
                'title': histogram,
                'newAtomDict': newAtomDict,
                'newCellDict': newCellDict,
                'depParmDict': depParmDict,
                'constraintInfo': constraintInfo,
                'parmDict': parmDict
            }
            SeqResult[histogram] = histRefData
            G2stMth.ApplyRBModels(parmDict, Phases, rigidbodyDict, True)
            #            G2stIO.SetRigidBodyModels(parmDict,sigDict,rigidbodyDict,printFile)
            G2stIO.SetHistogramPhaseData(parmDict, sigDict, Phases, Histo,
                                         None, ifPrint, printFile)
            G2stIO.SetHistogramData(parmDict, sigDict, Histo, None, ifPrint,
                                    printFile)
            G2stIO.SaveUpdatedHistogramsAndPhases(GPXfile, Histo, Phases,
                                                  rigidbodyDict, histRefData)
            NewparmDict = {}
            # make dict of varied parameters in current histogram, renamed to
            # next histogram, for use in next refinement.
            if Controls['Copy2Next'] and ihst < len(histNames) - 1:
                hId = Histo[histogram]['hId']  # current histogram
                nexthId = Histograms[histNames[ihst + 1]]['hId']
                for parm in set(list(varyList) + list(varyListStart)):
                    items = parm.split(':')
                    if len(items) < 3:
                        continue
                    if str(hId) in items[1]:
                        items[1] = str(nexthId)
                        newparm = ':'.join(items)
                        NewparmDict[newparm] = parmDict[parm]
                    else:
                        if items[2].startswith('dA'):
                            parm = parm.replace(':dA', ':A')
                        NewparmDict[parm] = parmDict[parm]

        except G2obj.G2RefineCancel as Msg:
            printFile.close()
            G2fil.G2Print(' ***** Refinement stopped *****')
            return False, Msg.msg
        except G2obj.G2Exception as Msg:  # cell metric error, others?
            printFile.close()
            G2fil.G2Print(' ***** Refinement error *****')
            return False, Msg.msg
        if GSASIIpath.GetConfigValue('Show_timing'):
            t2 = time.time()
            G2fil.G2Print("Fit step time {:.2f} sec.".format(t2 - t1))
            t1 = t2
    SeqResult['histNames'] = [
        itm for itm in G2stIO.GetHistogramNames(GPXfile, [
            'PWDR',
        ]) if itm in SeqResult.keys()
    ]
    G2stIO.SetSeqResult(GPXfile, Histograms, SeqResult)
    printFile.close()
    G2fil.G2Print(' Sequential refinement results are in file: ' +
                  ospath.splitext(GPXfile)[0] + '.lst')
    G2fil.G2Print(' ***** Sequential refinement successful *****')
    return True, 'Success'