Ejemplo n.º 1
0
                    rptemp.append("scale")
                refiner.refine(*rptemp)
            refiner.refine(*refpars)
        except ValueError, e:
            parser.error(str(e))
    elif "smear" in refpars and opts.baselineslope is None:
        try:
            refiner.refine("baselineslope", baselineslope = -0.5)
        except ValueError, e:
            parser.error(str(e))
    else:
        chain(xobj, yobj, xref, yref)

    # Get Rw for the morph range
    rw = tools.getRw(chain)
    pcc = tools.getPearson(chain)
    # Replace the MorphRGrid with Morph identity
    chain[0] = morphs.Morph()
    chain(xobj, yobj, xref, yref)

    items = config.items()
    items.sort()
    output = "\n".join("# %s = %f"%i for i in items)
    output += "\n# Rw = %f" % rw
    output += "\n# Pearson = %f" % pcc
    print output
    if opts.savefile is not None:
        header = "# PDF created by pdfmorph\n"
        header += "# from %s\n" % os.path.abspath(pargs[0])

        header += output
Ejemplo n.º 2
0
def main():
    parser = createOptionParser()
    (opts, pargs) = parser.parse_args()

    if len(pargs) != 2:
        parser.error("You must supply FILE1 and FILE2")

    # Get the PDFs
    xobj, yobj = getPDFFromFile(pargs[0])
    xref, yref = getPDFFromFile(pargs[1])

    # Get configuration values
    config = {}
    config["rmin"] = opts.rmin
    config["rmax"] = opts.rmax
    config["rstep"] = None
    if opts.rmin is not None and opts.rmax is not None and \
            opts.rmax <= opts.rmin:
        e = "rmin must be less than rmax"
        parser.error(e)

    # Set up the morphs
    chain = morphs.MorphChain(config)
    # Add the r-range morph, we will remove it when saving and plotting
    chain.append(morphs.MorphRGrid())
    refpars = []

    ## Scale
    if opts.scale is not None:
        chain.append(morphs.MorphScale())
        config["scale"] = opts.scale
        refpars.append("scale")
    ## Stretch
    if opts.stretch is not None:
        chain.append(morphs.MorphStretch())
        config["stretch"] = opts.stretch
        refpars.append("stretch")
    ## Smear
    if opts.smear is not None:
        chain.append(morphs.MorphXtalPDFtoRDF())
        chain.append(morphs.MorphSmear())
        chain.append(morphs.MorphXtalRDFtoPDF())
        refpars.append("smear")
        config["smear"] = opts.smear
        config["baselineslope"] = opts.baselineslope
        if opts.baselineslope is None:
            refpars.append("baselineslope")
            config["baselineslope"] = -0.5
    ## Size
    radii = [opts.radius, opts.pradius]
    nrad = 2 - radii.count(None)
    if nrad == 1:
        radii.remove(None)
        config["radius"] = radii[0]
        chain.append(morphs.MorphSphere())
        refpars.append("radius")
    elif nrad == 2:
        config["radius"] = radii[0]
        refpars.append("radius")
        config["pradius"] = radii[1]
        refpars.append("pradius")
        chain.append(morphs.MorphSpheroid())
    iradii = [opts.iradius, opts.ipradius]
    inrad = 2 - iradii.count(None)
    if inrad == 1:
        iradii.remove(None)
        config["iradius"] = iradii[0]
        chain.append(morphs.MorphISphere())
        refpars.append("iradius")
    elif inrad == 2:
        config["iradius"] = iradii[0]
        refpars.append("iradius")
        config["ipradius"] = iradii[1]
        refpars.append("ipradius")
        chain.append(morphs.MorphISpheroid())

    ## Resolution
    if opts.qdamp is not None:
        chain.append(morphs.MorphResolutionDamping())
        refpars.append("qdamp")
        config["qdamp"] = opts.qdamp

    # Now remove non-refinable parameters
    if opts.exclude is not None:
        refpars = set(refpars) - set(opts.exclude)
        refpars = list(refpars)

    # Refine or execute the morph
    refiner = refine.Refiner(chain, xobj, yobj, xref, yref)
    if opts.pearson:
        refiner.residual = refiner._pearson
    if opts.addpearson:
        refiner.residual = refiner._addpearson
    if opts.refine and refpars:
        try:
            # This works better when we adjust scale and smear first.
            if "smear" in refpars:
                rptemp = ["smear"]
                if "scale" in refpars:
                    rptemp.append("scale")
                refiner.refine(*rptemp)
            refiner.refine(*refpars)
        except ValueError as e:
            parser.error(str(e))
    elif "smear" in refpars and opts.baselineslope is None:
        try:
            refiner.refine("baselineslope", baselineslope=-0.5)
        except ValueError as e:
            parser.error(str(e))
    else:
        chain(xobj, yobj, xref, yref)

    # Get Rw for the morph range
    rw = tools.getRw(chain)
    pcc = tools.getPearson(chain)
    # Replace the MorphRGrid with Morph identity
    chain[0] = morphs.Morph()
    chain(xobj, yobj, xref, yref)

    items = list(config.items())
    items.sort()
    output = "\n".join("# %s = %f" % i for i in items)
    output += "\n# Rw = %f" % rw
    output += "\n# Pearson = %f" % pcc
    print(output)
    if opts.savefile is not None:
        header = "# PDF created by pdfmorph\n"
        header += "# from %s\n" % os.path.abspath(pargs[0])

        header += output
        if opts.savefile == "-":
            outfile = sys.stdout
        else:
            outfile = open(opts.savefile, 'w')
        print(header, file=outfile)
        import numpy
        numpy.savetxt(outfile, zip(chain.xobjout, chain.yobjout))
        outfile.close()

    if opts.plot:
        pairlist = [chain.xyobjout, chain.xyrefout]
        labels = ["objective", "reference"]
        # Plot extent defaults to calculation extent
        pmin = opts.pmin if opts.pmin is not None else opts.rmin
        pmax = opts.pmax if opts.pmax is not None else opts.rmax
        maglim = opts.maglim
        mag = opts.mag
        pdfplot.comparePDFs(pairlist,
                            labels,
                            rmin=pmin,
                            rmax=pmax,
                            maglim=maglim,
                            mag=mag,
                            rw=rw)

    return
Ejemplo n.º 3
0
def pdfmorph(xobj,
             yobj,
             xref,
             yref,
             rmin=None,
             rmax=None,
             rstep=None,
             pearson=False,
             add_pearson=False,
             fixed_operations=None,
             refine=True,
             verbose=False,
             **kwargs):
    """function to perfom PDF morphing.

    Parameters
    ----------
    xobj : numpy.array
        An array of objective x values, i.e., those will be manipulated by
        morphing.
    yobj : numpy.array
        An array of objective y values, i.e., those will be manipulated by
        morphing.
    xref : numpy.array
        An array of reference x values, i.e., those will be kept constant by
        morphing.
    yobj : numpy.array
        An array of reference y values, i.e., those will be kept constant by
        morphing.
    rmin : float, optional
        A value to specify lower r-limit of morph operations.
    rmax : float, optional
        A value to specify upper r-limit of morph operations.
    rstep : float, optional
        A value to specify rstep of morph operations.
    pearson: Bool, optional
        Option to include Pearson coefficient as a minimizing target
         during morphing. Default to False.
    add_pearson: Bool, optional
        Option to include **both** Pearson coefficient and Rw as
        minimizing targets during morphing. Default to False.
    fixed_operations : list, optional
        A list of string specifying operations will be keep fixed during
        morphing. Default is None.
    refine : bool, optional
        Option to execute the minimization step in morphing. If False,
        the morphing will be applied with parameter values specified in
        `morph_config`. Default to True.
    verbose : bool, optional
        Option to print full result after morph. Default to False.
    kwargs : dict, optional
        A dictionary with morph parameters as keys and initial
        values of morph parameters as values. Currently supported morph
        parparameters are:

            - 'scale'
            - 'stretch'
            - 'smear'
            - 'baselineslope'
            - 'qdamp'

    Returns
    -------
    morph_rv_dict : dict
        A dictionary contains following key-value pairs:

        - morph_chain : diffpy.pdfmorph.morphs.morphchain.MorphChain
              The instance of processed morph chain.
              Calling ``xobj, yobj, xref, yref = morph_chain.xyallout``
              will conviniently retrun morphed data and reference data
        - morphed_cfg : dict
              A dictionary of refined morphing parameters
        - rw : float
              The agreement factor between morphed data and reference
              data
        - pcc : float
              The pearson correlation coefficient between morphed
               data and referenced data

    Examples
    --------
    # morphing (xobj, yobj) pair to (xref, yref) pair with scaling
    from diffpy.pdfmorph import pdfmorph, morph_default_config, plot_morph

    morph_cfg = morph_default_config(scale=1.01)
    morph_rv_dict = pdfmorph(xobj, yobj, xref, yref, **morph_cfg)

    # plot morhing result
    plot_morph(morph_rv_dict['morph_chain'])

    # print morphing parameters, pearson correlation coefficient, Rw
    print(morph_rv_dict['morphed_cfg'])
    print(morph_rv_dict['pcc'])
    print(morph_rv_dict['rw'])
    """
    operation_dict = {}
    refpars = []
    # input config
    rv_cfg = dict(kwargs)
    # configure morph operations
    active_morphs = [
        k for k, v in rv_cfg.items()
        if (v is not None) and k in _morph_step_dict
    ]
    rv_cfg['rmin'] = rmin
    rv_cfg['rmax'] = rmax
    rv_cfg['rstep'] = rstep
    # configure smear, guess baselineslope when it is not provided
    if (rv_cfg.get('smear') is not None
            and rv_cfg.get('baselineslope') is None):
        rv_cfg['baselineslope'] = -0.5
    # config dict defines initial guess of parameters
    chain = morphs.MorphChain(rv_cfg)
    # rgrid
    chain.append(morphs.MorphRGrid())
    # configure morph chain
    for k in active_morphs:
        morph_cls = _morph_step_dict[k]
        if k == 'smear':
            [chain.append(el()) for el in morph_cls]
            refpars.append('baselineslope')
        else:
            chain.append(morph_cls())
        refpars.append(k)
    # exclude fixed options
    if fixed_operations:
        if not isinstance(fixed_operations, Iterable):
            fixed_operations = [fixed_operations]
        for opt in fixed_operations:
            refpars.remove(opt)
    # define refiner
    refiner = ref.Refiner(chain, xobj, yobj, xref, yref)
    if pearson:
        refiner.residual = refiner._pearson
    if add_pearson:
        refiner.residual = refiner._addpearson
    # execute morphing
    if refpars and refine:
        # This works better when we adjust scale and smear first.
        if "smear" in refpars:
            rptemp = ["smear"]
            if "scale" in refpars:
                rptemp.append("scale")
            refiner.refine(*rptemp)
        # Refine all params
        refiner.refine(*refpars)
    else:
        # no operation if refine=False or refpars is empty list
        chain(xobj, yobj, xref, yref)

    # summary
    rw = tools.getRw(chain)
    pcc = tools.getPearson(chain)
    # restore rgrid
    chain[0] = morphs.Morph()
    chain(xobj, yobj, xref, yref)
    # print output
    if verbose:
        if fixed_operations:
            print("== INFO: Following steps are fixed during morphing ==:\n")
            print('\n'.join(fixed_operations))
        print("== INFO: Refined morph parameters ==:\n")
        output = "\n".join(["# %s = %f" % (k, v) for k, v in \
                rv_cfg.items() if v is not None])
        output += "\n# Rw = %f" % rw
        output += "\n# Pearson = %f" % pcc
        print(output)

    rv_dict = dict(morph_chain=chain, morphed_config=rv_cfg, rw=rw, pcc=pcc)
    return rv_dict