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, e: parser.error(str(e))
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
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