From 2884fd597adac5c2873faa0ded610e9c6f2d36b6 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Thu, 15 Jun 2023 14:43:03 -0400 Subject: [PATCH 1/4] Moved function for readability --- diffpy/pdfmorph/pdfmorphapp.py | 20 ++++++-------------- diffpy/pdfmorph/tools.py | 9 +++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/diffpy/pdfmorph/pdfmorphapp.py b/diffpy/pdfmorph/pdfmorphapp.py index 0d135f42..7eece397 100755 --- a/diffpy/pdfmorph/pdfmorphapp.py +++ b/diffpy/pdfmorph/pdfmorphapp.py @@ -258,39 +258,31 @@ def main(): if opts.baselineslope is None: refpars.append("baselineslope") config["baselineslope"] = -0.5 - - def nn_value(val, name): - if val < 0: - negative_value_warning = f"\n# Negative value for {name} given. Using absolute value instead." - print(negative_value_warning) - return -val - return val - ## Size radii = [opts.radius, opts.pradius] nrad = 2 - radii.count(None) if nrad == 1: radii.remove(None) - config["radius"] = nn_value(radii[0], "radius or pradius") + config["radius"] = tools.nn_value(radii[0], "radius or pradius") chain.append(morphs.MorphSphere()) refpars.append("radius") elif nrad == 2: - config["radius"] = nn_value(radii[0], "radius") + config["radius"] = tools.nn_value(radii[0], "radius") refpars.append("radius") - config["pradius"] = nn_value(radii[1], "pradius") + config["pradius"] = tools.nn_value(radii[1], "pradius") 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"] = nn_value(iradii[0], "iradius or ipradius") + config["iradius"] = tools.nn_value(iradii[0], "iradius or ipradius") chain.append(morphs.MorphISphere()) refpars.append("iradius") elif inrad == 2: - config["iradius"] = nn_value(iradii[0], "iradius") + config["iradius"] = tools.nn_value(iradii[0], "iradius") refpars.append("iradius") - config["ipradius"] = nn_value(iradii[1], "ipradius") + config["ipradius"] = tools.nn_value(iradii[1], "ipradius") refpars.append("ipradius") chain.append(morphs.MorphISpheroid()) diff --git a/diffpy/pdfmorph/tools.py b/diffpy/pdfmorph/tools.py index 074e8950..208e7916 100644 --- a/diffpy/pdfmorph/tools.py +++ b/diffpy/pdfmorph/tools.py @@ -110,3 +110,12 @@ def readPDF(fname): if len(rv) >= 2: return rv[:2] return (None, None) + + +def nn_value(val, name): + # Convenience function for ensuring certain non-negative inputs + if val < 0: + negative_value_warning = f"\n# Negative value for {name} given. Using absolute value instead." + print(negative_value_warning) + return -val + return val From 6ceaed07370a78364763d6f2e27576aa840e9a5d Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Sat, 17 Jun 2023 22:36:41 -0400 Subject: [PATCH 2/4] Remove top-level tests dir, fix docs build error --- doc/source/conf.py | 2 +- requirements/docs.txt | 1 + {tests/testdata => tutorial}/tutorialData.zip | Bin 3 files changed, 2 insertions(+), 1 deletion(-) rename {tests/testdata => tutorial}/tutorialData.zip (100%) diff --git a/doc/source/conf.py b/doc/source/conf.py index 60d64c7b..d5dcb378 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -69,7 +69,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = [] htmlhelp_basename = 'PDFmorphdoc' diff --git a/requirements/docs.txt b/requirements/docs.txt index 92f4ff09..c9f58142 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,3 +1,4 @@ sphinx sphinx_rtd_theme +m2r doctr diff --git a/tests/testdata/tutorialData.zip b/tutorial/tutorialData.zip similarity index 100% rename from tests/testdata/tutorialData.zip rename to tutorial/tutorialData.zip From ed89286689c3c2191ce483bd61ec64a2f5d70472 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Sat, 17 Jun 2023 22:38:31 -0400 Subject: [PATCH 3/4] Wholescale refactoring obj->morph, ref->target --- TUTORIAL.rst | 4 +- diffpy/pdfmorph/morphs/morph.py | 112 +++++++++--------- diffpy/pdfmorph/morphs/morphchain.py | 69 ++++++----- diffpy/pdfmorph/morphs/morphishape.py | 28 ++--- diffpy/pdfmorph/morphs/morphpdftordf.py | 16 +-- diffpy/pdfmorph/morphs/morphrdftopdf.py | 24 ++-- diffpy/pdfmorph/morphs/morphresolution.py | 14 +-- diffpy/pdfmorph/morphs/morphrgrid.py | 26 ++-- diffpy/pdfmorph/morphs/morphscale.py | 16 +-- diffpy/pdfmorph/morphs/morphshape.py | 28 ++--- diffpy/pdfmorph/morphs/morphshift.py | 20 ++-- diffpy/pdfmorph/morphs/morphsmear.py | 20 ++-- diffpy/pdfmorph/morphs/morphstretch.py | 18 +-- diffpy/pdfmorph/pdfmorph_api.py | 44 +++---- diffpy/pdfmorph/pdfmorphapp.py | 18 +-- diffpy/pdfmorph/refine.py | 32 ++--- diffpy/pdfmorph/tests/test_morph_func.py | 52 ++++---- diffpy/pdfmorph/tests/test_morphchain.py | 26 ++-- diffpy/pdfmorph/tests/test_morphpdftordf.py | 18 +-- diffpy/pdfmorph/tests/test_morphrdftopdf.py | 18 +-- diffpy/pdfmorph/tests/test_morphresolution.py | 14 +-- diffpy/pdfmorph/tests/test_morphrgrid.py | 28 ++--- diffpy/pdfmorph/tests/test_morphscale.py | 14 +-- diffpy/pdfmorph/tests/test_morphshape.py | 28 ++--- diffpy/pdfmorph/tests/test_morphsmear.py | 18 +-- diffpy/pdfmorph/tests/test_morphstretch.py | 28 ++--- diffpy/pdfmorph/tests/test_plot_morph.py | 10 +- diffpy/pdfmorph/tests/test_refine.py | 48 ++++---- diffpy/pdfmorph/tests/test_tools.py | 8 +- diffpy/pdfmorph/tools.py | 16 +-- doc/source/quickstart.rst | 4 +- 31 files changed, 409 insertions(+), 410 deletions(-) diff --git a/TUTORIAL.rst b/TUTORIAL.rst index 4e1b33cd..1cee58c0 100644 --- a/TUTORIAL.rst +++ b/TUTORIAL.rst @@ -75,8 +75,8 @@ Basic PDFmorph Workflow will get morphed, while the second PDF file argument you provide (here, ``darkSub_rh20_C_44.gr``) is the PDF which acts as the model and does not get morphed. Hereinafter, - we will refer to the first PDF argument as the "objective" - and the second as the "reference", as the PDFmorph display + we will refer to the first PDF argument as the "morph" + and the second as the "target", as the PDFmorph display does. 6. Now, we will start the morphing process, which requires us to diff --git a/diffpy/pdfmorph/morphs/morph.py b/diffpy/pdfmorph/morphs/morph.py index 1799643b..324fce38 100644 --- a/diffpy/pdfmorph/morphs/morph.py +++ b/diffpy/pdfmorph/morphs/morph.py @@ -24,11 +24,11 @@ class Morph(object): - '''Base class for implementing a morph on an objective given a reference. + '''Base class for implementing a morph given a target. Adapted from diffpy.pdfgetx to include two sets of arrays that get passed - through. In most cases, the objective is modified by a morph, but it is - acceptable for morph the reference as well, such as to change the range of + through. In most cases, only the morph is modified, but it is + acceptable for morph the target as well, such as to change the range of the array. Note that attributes are taken from config when not found locally. The @@ -47,22 +47,22 @@ class Morph(object): Instance attributes: config -- dictionary that contains all configuration variables - xobjin -- last objective input x data - yobjin -- last objective input y data - xobjout -- last objective result x data - yobjout -- last objective result y data - xrefin -- last reference input x data - yrefin -- last reference input y data - xrefout -- last reference result x data - yrefout -- last reference result y data + x_morph_in -- last morph input x data + y_morph_in -- last morph input y data + x_morph_out -- last morph result x data + y_morph_out -- last morph result y data + x_target_in -- last target input x data + y_target_in -- last target input y data + x_target_out -- last target result x data + y_target_out -- last target result y data Properties: - xyobjin -- tuple of (xobjin, yobjin) - xyobjout -- tuple of (xobjout, yobjout) - xyrefin -- tuple of (xrefin, yrefin) - xyrefout -- tuple of (xrefout, yrefout) - xyallout -- tuple of (xobjout, yobjout, xrefout, yrefout) + xy_morph_in -- tuple of (x_morph_in, y_morph_in) + xy_morph_out -- tuple of (x_morph_out, y_morph_out) + xy_target_in -- tuple of (x_target_in, y_target_in) + xy_target_out -- tuple of (x_target_out, y_target_out) + xyallout -- tuple of (x_morph_out, y_morph_out, x_target_out, y_target_out) ''' # Class variables @@ -76,24 +76,24 @@ class Morph(object): # Properties - xyobjin = property( - lambda self: (self.xobjin, self.yobjin), - doc='Return a tuple of objective input arrays', + xy_morph_in = property( + lambda self: (self.x_morph_in, self.y_morph_in), + doc='Return a tuple of morph input arrays', ) - xyobjout = property( - lambda self: (self.xobjout, self.yobjout), - doc='Return a tuple of objective output arrays', + xy_morph_out = property( + lambda self: (self.x_morph_out, self.y_morph_out), + doc='Return a tuple of morph output arrays', ) - xyrefin = property( - lambda self: (self.xrefin, self.yrefin), - doc='Return a tuple of reference input arrays', + xy_target_in = property( + lambda self: (self.x_target_in, self.y_target_in), + doc='Return a tuple of target input arrays', ) - xyrefout = property( - lambda self: (self.xrefout, self.yrefout), - doc='Return a tuple of reference output arrays', + xy_target_out = property( + lambda self: (self.x_target_out, self.y_target_out), + doc='Return a tuple of target output arrays', ) xyallout = property( - lambda self: (self.xobjout, self.yobjout, self.xrefout, self.yrefout), + lambda self: (self.x_morph_out, self.y_morph_out, self.x_target_out, self.y_target_out), doc='Return a tuple of all output arrays', ) @@ -105,43 +105,43 @@ def __init__(self, config=None): # declare empty attributes if config is None: config = {} - self.xobjin = None - self.yobjin = None - self.xobjout = None - self.yobjout = None - self.xrefin = None - self.yrefin = None - self.xrefout = None - self.yrefout = None + self.x_morph_in = None + self.y_morph_in = None + self.x_morph_out = None + self.y_morph_out = None + self.x_target_in = None + self.y_target_in = None + self.x_target_out = None + self.y_target_out = None # process arguments self.applyConfig(config) return - def morph(self, xobj, yobj, xref, yref): - '''Morph arrays objective or reference. + def morph(self, x_morph, y_morph, x_target, y_target): + '''Morph arrays morphed or target. - xobj, yobj -- Objective arrays. - xref, yref -- Reference arrays. + x_morph, y_morph -- Morphed arrays. + x_target, y_target -- Target arrays. Identity operation. This method should be overloaded in a derived class. - Return a tuple of numpy arrays (xobjout, yobjout, xrefout, yrefout) + Return a tuple of numpy arrays (x_morph_out, y_morph_out, x_target_out, y_target_out) ''' - self.xobjin = xobj - self.yobjin = yobj - self.xrefin = xref - self.yrefin = yref - self.xobjout = xobj.copy() - self.yobjout = yobj.copy() - self.xrefout = xref.copy() - self.yrefout = yref.copy() + self.x_morph_in = x_morph + self.y_morph_in = y_morph + self.x_target_in = x_target + self.y_target_in = y_target + self.x_morph_out = x_morph.copy() + self.y_morph_out = y_morph.copy() + self.x_target_out = x_target.copy() + self.y_target_out = y_target.copy() self.checkConfig() return self.xyallout - def __call__(self, xobj, yobj, xref, yref): + def __call__(self, x_morph, y_morph, x_target, y_target): '''Alias for morph.''' - return self.morph(xobj, yobj, xref, yref) + return self.morph(x_morph, y_morph, x_target, y_target) def applyConfig(self, config): '''Process any configuration data from a dictionary. @@ -169,8 +169,8 @@ def plotInputs(self, xylabels=True): ''' from matplotlib.pyplot import plot, xlabel, ylabel - rv = plot(self.xrefin, self.yrefin, label="reference") - rv = plot(self.xobjin, self.yobjin, label="objective") + rv = plot(self.x_target_in, self.y_target_in, label="***TARGET***") + rv = plot(self.x_morph_in, self.y_morph_in, label="***MORPH***") if xylabels: xlabel(self.xinlabel) ylabel(self.yinlabel) @@ -189,8 +189,8 @@ def plotOutputs(self, xylabels=True, **plotargs): pargs = dict(plotargs) pargs.pop("label", None) - rv = plot(self.xrefout, self.yrefout, label="reference", **pargs) - rv = plot(self.xobjout, self.yobjout, label="objective", **pargs) + rv = plot(self.x_target_out, self.y_target_out, label="***TARGET***", **pargs) + rv = plot(self.x_morph_out, self.y_morph_out, label="***MORPH***", **pargs) if xylabels: xlabel(self.xoutlabel) ylabel(self.youtlabel) diff --git a/diffpy/pdfmorph/morphs/morphchain.py b/diffpy/pdfmorph/morphs/morphchain.py index d062aff9..5b38e937 100644 --- a/diffpy/pdfmorph/morphs/morphchain.py +++ b/diffpy/pdfmorph/morphs/morphchain.py @@ -33,40 +33,39 @@ class MorphChain(list): Properties: These return tuples of None if there are no morphs. - xobjin -- last objective input x data - yobjin -- last objective input y data - xobjout -- last objective result x data - yobjout -- last objective result y data - xrefin -- last reference input x data - yrefin -- last reference input y data - xrefout -- last reference result x data - yrefout -- last reference result y data - xyobjin -- tuple of (xobjin, yobjin) from first morph - xyobjout -- tuple of (xobjout, yobjout) from last morph - xyrefin -- tuple of (xrefin, yrefin) from first morph - xyrefout -- tuple of (xrefout, yrefout) from last morph - xyallout -- tuple of (xobjout, yobjout, xrefout, yrefout) from last - morph + x_morph_in -- last morph input x data + y_morph_in -- last morph input y data + x_morph_out -- last morph result x data + y_morph_out -- last morph result y data + x_target_in -- last target input x data + y_target_in -- last target input y data + x_target_out -- last target result x data + y_target_out -- last target result y data + xy_morph_in -- tuple of (x_morph_in, y_morph_in) from first morph + xy_morph_out -- tuple of (x_morph_out, y_morph_out) from last morph + xy_target_in -- tuple of (x_target_in, y_target_in) from first morph + xy_target_out -- tuple of (x_target_out, y_target_out) from last morph + xyallout -- tuple of (x_morph_out, y_morph_out, x_target_out, y_target_out) from last morph parnames -- Names of parameters collected from morphs (Read only). ''' - xobjin = property(lambda self: None if len(self) == 0 else self[0].xobjin) - yobjin = property(lambda self: None if len(self) == 0 else self[0].yobjin) - xrefin = property(lambda self: None if len(self) == 0 else self[0].xrefin) - yrefin = property(lambda self: None if len(self) == 0 else self[0].yrefin) - xobjout = property(lambda self: None if len(self) == 0 else self[-1].xobjout) - yobjout = property(lambda self: None if len(self) == 0 else self[-1].yobjout) - xrefout = property(lambda self: None if len(self) == 0 else self[-1].xrefout) - yrefout = property(lambda self: None if len(self) == 0 else self[-1].yrefout) - xyobjin = property(lambda self: (None, None) if len(self) == 0 else self[0].xyobjin) - xyobjout = property( - lambda self: (None, None) if len(self) == 0 else self[-1].xyobjout + x_morph_in = property(lambda self: None if len(self) == 0 else self[0].x_morph_in) + y_morph_in = property(lambda self: None if len(self) == 0 else self[0].y_morph_in) + x_target_in = property(lambda self: None if len(self) == 0 else self[0].x_target_in) + y_target_in = property(lambda self: None if len(self) == 0 else self[0].y_target_in) + x_morph_out = property(lambda self: None if len(self) == 0 else self[-1].x_morph_out) + y_morph_out = property(lambda self: None if len(self) == 0 else self[-1].y_morph_out) + x_target_out = property(lambda self: None if len(self) == 0 else self[-1].x_target_out) + y_target_out = property(lambda self: None if len(self) == 0 else self[-1].y_target_out) + xy_morph_in = property(lambda self: (None, None) if len(self) == 0 else self[0].xy_morph_in) + xy_morph_out = property( + lambda self: (None, None) if len(self) == 0 else self[-1].xy_morph_out ) - xyrefin = property(lambda self: (None, None) if len(self) == 0 else self[0].xyrefin) - xyrefout = property( - lambda self: (None, None) if len(self) == 0 else self[-1].xyrefout + xy_target_in = property(lambda self: (None, None) if len(self) == 0 else self[0].xy_target_in) + xy_target_out = property( + lambda self: (None, None) if len(self) == 0 else self[-1].xy_target_out ) xyallout = property( lambda self: (None, None, None, None) if len(self) == 0 else self[-1].xyallout @@ -85,26 +84,26 @@ def __init__(self, config, *args): self.extend(args) return - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): '''Apply the chain of morphs to the input data. Note that config may be altered by the morphs. - xobj, yobj -- Objective arrays. - xref, yref -- Reference arrays. + x_morph, y_morph -- Morphed arrays. + x_target, y_target -- Target arrays. - Return a tuple of numpy arrays (xobjout, yobjout, xrefout, yrefout) + Return a tuple of numpy arrays (x_morph_out, y_morph_out, x_target_out, y_target_out) ''' - xyall = (xobj, yobj, xref, yref) + xyall = (x_morph, y_morph, x_target, y_target) for morph in self: morph.applyConfig(self.config) xyall = morph(*xyall) return xyall - def __call__(self, xobj, yobj, xref, yref): + def __call__(self, x_morph, y_morph, x_target, y_target): '''Alias for morph.''' - return self.morph(xobj, yobj, xref, yref) + return self.morph(x_morph, y_morph, x_target, y_target) def __getattr__(self, name): '''Obtain the value from self.config, when normal lookup fails. diff --git a/diffpy/pdfmorph/morphs/morphishape.py b/diffpy/pdfmorph/morphs/morphishape.py index f2d191f5..864292a3 100644 --- a/diffpy/pdfmorph/morphs/morphishape.py +++ b/diffpy/pdfmorph/morphs/morphishape.py @@ -24,7 +24,7 @@ class MorphISpheroid -- apply inverse spheroidal shape function class MorphISphere(Morph): - '''Apply inverse spherical characteristic function to the objective + '''Apply inverse spherical characteristic function to the morph Configuration variables: @@ -33,19 +33,19 @@ class MorphISphere(Morph): ''' # Define input output types - summary = 'Apply inverse spherical characteristic function to objective' + summary = 'Apply inverse spherical characteristic function to morph' xinlabel = LABEL_RA yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_GR parnames = ["iradius"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Apply a scale factor.""" - Morph.morph(self, xobj, yobj, xref, yref) - f = _sphericalCF(xobj, 2 * self.iradius) - self.yobjout /= f - self.yobjout[f == 0] = 0 + Morph.morph(self, x_morph, y_morph, x_target, y_target) + f = _sphericalCF(x_morph, 2 * self.iradius) + self.y_morph_out /= f + self.y_morph_out[f == 0] = 0 return self.xyallout @@ -53,7 +53,7 @@ def morph(self, xobj, yobj, xref, yref): class MorphISpheroid(Morph): - '''Apply inverse spherical characteristic function to the objective + '''Apply inverse spherical characteristic function to the morph Configuration variables: @@ -63,19 +63,19 @@ class MorphISpheroid(Morph): ''' # Define input output types - summary = 'Apply inverse spheroidal characteristic function to objective' + summary = 'Apply inverse spheroidal characteristic function to morph' xinlabel = LABEL_RA yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_GR parnames = ["iradius", "ipradius"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Apply a scale factor.""" - Morph.morph(self, xobj, yobj, xref, yref) - f = _spheroidalCF(xobj, self.iradius, self.ipradius) - self.yobjout /= f - self.yobjout[f == 0] == 0 + Morph.morph(self, x_morph, y_morph, x_target, y_target) + f = _spheroidalCF(x_morph, self.iradius, self.ipradius) + self.y_morph_out[f != 0] /= f # Divide non-zero entries + self.y_morph_out[f == 0] = 0 # Set zero entries to zero return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphpdftordf.py b/diffpy/pdfmorph/morphs/morphpdftordf.py index 130a146e..a88dfbb0 100644 --- a/diffpy/pdfmorph/morphs/morphpdftordf.py +++ b/diffpy/pdfmorph/morphs/morphpdftordf.py @@ -24,7 +24,7 @@ class MorphXtalPDFtoRDF(Morph): '''Morph crystal PDFs to RDFs. - This morphs both the objective and the reference. + This morphs both the morph data and the target data. Configuration variables: @@ -38,20 +38,20 @@ class MorphXtalPDFtoRDF(Morph): ''' # Define input output types - summary = 'Turn the PDF into the RDF for both the objective and reference' + summary = 'Turn the PDF into the RDF for both the morph and target' xinlabel = LABEL_RA yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_RR parnames = ["baselineslope"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Morph to the RDF.""" - Morph.morph(self, xobj, yobj, xref, yref) - objbaseline = self.baselineslope * self.xobjin - self.yobjout = self.xobjin * (self.yobjin - objbaseline) - refbaseline = self.baselineslope * self.xrefin - self.yrefout = self.xrefin * (self.yrefin - refbaseline) + Morph.morph(self, x_morph, y_morph, x_target, y_target) + morph_baseline = self.baselineslope * self.x_morph_in + self.y_morph_out = self.x_morph_in * (self.y_morph_in - morph_baseline) + target_baseline = self.baselineslope * self.x_target_in + self.y_target_out = self.x_target_in * (self.y_target_in - target_baseline) return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphrdftopdf.py b/diffpy/pdfmorph/morphs/morphrdftopdf.py index e6577064..38ba0a58 100644 --- a/diffpy/pdfmorph/morphs/morphrdftopdf.py +++ b/diffpy/pdfmorph/morphs/morphrdftopdf.py @@ -24,7 +24,7 @@ class MorphXtalRDFtoPDF(Morph): '''Morph crystal RDFs to PDFs. - This morphs both the objective and the reference. + This morphs both the morph data and the target data. Configuration variables: @@ -38,24 +38,24 @@ class MorphXtalRDFtoPDF(Morph): ''' # Define input output types - summary = 'Turn the PDF into the RDF for both the objective and reference' + summary = 'Turn the PDF into the RDF for both the morph and target' xinlabel = LABEL_RA yinlabel = LABEL_RR xoutlabel = LABEL_RA youtlabel = LABEL_GR parnames = ["baselineslope"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Morph to the PDF.""" - Morph.morph(self, xobj, yobj, xref, yref) - objbaseline = self.baselineslope * self.xobjin - refbaseline = self.baselineslope * self.xrefin - self.yrefout = self.yrefin / self.xrefin + refbaseline - if self.xrefin[0] == 0: - self.yrefout[0] = 0 - self.yobjout = self.yobjin / self.xobjin + objbaseline - if self.xobjin[0] == 0: - self.yobjout[0] = 0 + Morph.morph(self, x_morph, y_morph, x_target, y_target) + morph_baseline = self.baselineslope * self.x_morph_in + target_baseline = self.baselineslope * self.x_target_in + self.y_target_out = self.y_target_in / self.x_target_in + target_baseline + if self.x_target_in[0] == 0: + self.y_target_out[0] = 0 + self.y_morph_out = self.y_morph_in / self.x_morph_in + morph_baseline + if self.x_morph_in[0] == 0: + self.y_morph_out[0] = 0 return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphresolution.py b/diffpy/pdfmorph/morphs/morphresolution.py index a57c8991..e2b8cb5d 100644 --- a/diffpy/pdfmorph/morphs/morphresolution.py +++ b/diffpy/pdfmorph/morphs/morphresolution.py @@ -14,7 +14,7 @@ ############################################################################## -"""class MorphResolutionDamping -- apply resolution broadening to the objective +"""class MorphResolutionDamping -- apply resolution broadening to the morph """ @@ -24,7 +24,7 @@ class MorphResolutionDamping(Morph): - '''Apply resolution damping and broadening to the objective. + '''Apply resolution damping and broadening to the morph. Configuration variables: @@ -35,18 +35,18 @@ class MorphResolutionDamping(Morph): ''' # Define input output types - summary = 'Apply resolution damping to the objective' + summary = 'Apply resolution damping to the morph' xinlabel = LABEL_RA yinlabel = LABEL_RR xoutlabel = LABEL_RA youtlabel = LABEL_RR parnames = ["qdamp"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Apply a resolution damping.""" - Morph.morph(self, xobj, yobj, xref, yref) - b = numpy.exp(-0.5 * (self.xobjin * self.qdamp) ** 2) - self.yobjout *= b + Morph.morph(self, x_morph, y_morph, x_target, y_target) + b = numpy.exp(-0.5 * (self.x_morph_in * self.qdamp) ** 2) + self.y_morph_out *= b return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphrgrid.py b/diffpy/pdfmorph/morphs/morphrgrid.py index 8c620e0d..a3a77c91 100644 --- a/diffpy/pdfmorph/morphs/morphrgrid.py +++ b/diffpy/pdfmorph/morphs/morphrgrid.py @@ -14,7 +14,7 @@ ############################################################################## -"""class MorphRGrid -- put objective and reference on desired grid. +"""class MorphRGrid -- put morph and target on desired grid. """ @@ -28,7 +28,7 @@ class MorphRGrid(Morph): '''Resample to specified r-grid. - This resamples both the objective and reference arrays to be on the + This resamples both the morph and target arrays to be on the specified grid. Configuration variables: @@ -52,14 +52,14 @@ class MorphRGrid(Morph): youtlabel = LABEL_GR parnames = ["rmin", "rmax", "rstep"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Resample arrays onto specified grid.""" - Morph.morph(self, xobj, yobj, xref, yref) - rmininc = max(self.xrefin[0], self.xobjin[0]) - rstepref = self.xrefin[1] - self.xrefin[0] - rstepobj = self.xobjin[1] - self.xobjin[0] - rstepinc = max(rstepref, rstepobj) - rmaxinc = min(self.xrefin[-1] + rstepref, self.xobjin[-1] + rstepobj) + Morph.morph(self, x_morph, y_morph, x_target, y_target) + rmininc = max(self.x_target_in[0], self.x_morph_in[0]) + r_step_target = self.x_target_in[1] - self.x_target_in[0] + r_step_morph = self.x_morph_in[1] - self.x_morph_in[0] + rstepinc = max(r_step_target, r_step_morph) + rmaxinc = min(self.x_target_in[-1] + r_step_target, self.x_morph_in[-1] + r_step_morph) if self.rmin is None or self.rmin < rmininc: self.rmin = rmininc if self.rmax is None or self.rmax > rmaxinc: @@ -67,10 +67,10 @@ def morph(self, xobj, yobj, xref, yref): if self.rstep is None or self.rstep < rstepinc: self.rstep = rstepinc # Make sure that rmax is exclusive - self.xobjout = numpy.arange(self.rmin, self.rmax - epsilon, self.rstep) - self.yobjout = numpy.interp(self.xobjout, self.xobjin, self.yobjin) - self.xrefout = self.xobjout.copy() - self.yrefout = numpy.interp(self.xrefout, self.xrefin, self.yrefin) + self.x_morph_out = numpy.arange(self.rmin, self.rmax - epsilon, self.rstep) + self.y_morph_out = numpy.interp(self.x_morph_out, self.x_morph_in, self.y_morph_in) + self.x_target_out = self.x_morph_out.copy() + self.y_target_out = numpy.interp(self.x_target_out, self.x_target_in, self.y_target_in) return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphscale.py b/diffpy/pdfmorph/morphs/morphscale.py index e5f4ad2d..4f70314a 100644 --- a/diffpy/pdfmorph/morphs/morphscale.py +++ b/diffpy/pdfmorph/morphs/morphscale.py @@ -14,7 +14,7 @@ ############################################################################## -"""class MorphScale -- scale the objective +"""class MorphScale -- scale the morph data """ @@ -22,28 +22,28 @@ class MorphScale(Morph): - '''Scale the objective. + '''Scale the morph. - This scales the objective. + This scales the morph. Configuration variables: - scale -- The scale to apply to yrefin. + scale -- The scale to apply to y_target_in. ''' # Define input output types - summary = 'Scale objective by specified amount' + summary = 'Scale morph by specified amount' xinlabel = LABEL_RA yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_GR parnames = ["scale"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Apply a scale factor.""" - Morph.morph(self, xobj, yobj, xref, yref) - self.yobjout *= self.scale + Morph.morph(self, x_morph, y_morph, x_target, y_target) + self.y_morph_out *= self.scale return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphshape.py b/diffpy/pdfmorph/morphs/morphshape.py index a7f75bc7..0403fce8 100644 --- a/diffpy/pdfmorph/morphs/morphshape.py +++ b/diffpy/pdfmorph/morphs/morphshape.py @@ -14,8 +14,8 @@ ############################################################################## -"""class MorphSphere -- apply a spherical shape function to the objective -class MorphSpheroid -- apply a spheroidal shape function to the objective +"""class MorphSphere -- apply a spherical shape function to the morph +class MorphSpheroid -- apply a spheroidal shape function to the morph """ @@ -28,7 +28,7 @@ class MorphSpheroid -- apply a spheroidal shape function to the objective class MorphSphere(Morph): - '''Apply a spherical characteristic function to the objective + '''Apply a spherical characteristic function to the morph Configuration variables: @@ -37,18 +37,18 @@ class MorphSphere(Morph): ''' # Define input output types - summary = 'Apply spherical characteristic function to objective' + summary = 'Apply spherical characteristic function to morph' xinlabel = LABEL_RA yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_GR parnames = ["radius"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Apply a scale factor.""" - Morph.morph(self, xobj, yobj, xref, yref) - f = _sphericalCF(xobj, 2 * self.radius) - self.yobjout *= f + Morph.morph(self, x_morph, y_morph, x_target, y_target) + f = _sphericalCF(x_morph, 2 * self.radius) + self.y_morph_out *= f return self.xyallout @@ -56,7 +56,7 @@ def morph(self, xobj, yobj, xref, yref): class MorphSpheroid(Morph): - '''Apply a spherical characteristic function to the objective + '''Apply a spherical characteristic function to the morph Configuration variables: @@ -66,18 +66,18 @@ class MorphSpheroid(Morph): ''' # Define input output types - summary = 'Apply spheroidal characteristic function to objective' + summary = 'Apply spheroidal characteristic function to morph' xinlabel = LABEL_RA yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_GR parnames = ["radius", "pradius"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Apply a scale factor.""" - Morph.morph(self, xobj, yobj, xref, yref) - f = _spheroidalCF(xobj, self.radius, self.pradius) - self.yobjout *= f + Morph.morph(self, x_morph, y_morph, x_target, y_target) + f = _spheroidalCF(x_morph, self.radius, self.pradius) + self.y_morph_out *= f return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphshift.py b/diffpy/pdfmorph/morphs/morphshift.py index 18148a2d..9744fdaf 100644 --- a/diffpy/pdfmorph/morphs/morphshift.py +++ b/diffpy/pdfmorph/morphs/morphshift.py @@ -14,7 +14,7 @@ ############################################################################## -"""class MorphShift -- shift the objective +"""class MorphShift -- shift the morph """ @@ -23,12 +23,12 @@ class MorphShift(Morph): - '''Shift the objective. + '''Shift the morph. Configuration variables: - vshift -- The vertical shift to apply to yrefin. - hshift -- The horizontal shift to apply to yrefin. + vshift -- The vertical shift to apply to the morph. + hshift -- The horizontal shift to apply to the morph. Note that a horizontal shift may cause edge effects, since the morph does not know what lies beyond the edge of the signals. @@ -36,19 +36,19 @@ class MorphShift(Morph): ''' # Define input output types - summary = 'Shift objective by specified amount' + summary = 'Shift morph by specified amount' xinlabel = LABEL_RA yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_GR parnames = ["hshift", "vshift"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Apply the shifts.""" - Morph.morph(self, xobj, yobj, xref, yref) - r = self.xobjin - self.hshift - self.yobjout = numpy.interp(r, self.xobjin, self.yobjin) - self.yobjout += self.vshift + Morph.morph(self, x_morph, y_morph, x_target, y_target) + r = self.x_morph_in - self.hshift + self.y_morph_out = numpy.interp(r, self.x_morph_in, self.y_morph_in) + self.y_morph_out += self.vshift return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphsmear.py b/diffpy/pdfmorph/morphs/morphsmear.py index 0484acca..b1d0ea9e 100644 --- a/diffpy/pdfmorph/morphs/morphsmear.py +++ b/diffpy/pdfmorph/morphs/morphsmear.py @@ -14,7 +14,7 @@ ############################################################################## -"""class MorphSmear -- smear the objective. +"""class MorphSmear -- smear the morph. """ @@ -23,36 +23,36 @@ class MorphSmear(Morph): - '''Smear the objective function. + '''Smear the morph function. - This smears (broadens) the peaks of the objective. Note that this operates + This smears (broadens) the peaks of the morph. Note that this operates on the RDF. Inputs are not automatically converted to the RDF. Configuration variables: - smear -- The smear factor to apply to yobjin. + smear -- The smear factor to apply to y_morph_in. ''' # Define input output types - summary = 'Smear objective by desired amount' + summary = 'Smear morph by desired amount' xinlabel = LABEL_RA yinlabel = LABEL_RR xoutlabel = LABEL_RA youtlabel = LABEL_RR parnames = ["smear"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Resample arrays onto specified grid.""" - Morph.morph(self, xobj, yobj, xref, yref) + Morph.morph(self, x_morph, y_morph, x_target, y_target) if self.smear == 0: return self.xyallout # The Gaussian to convolute with. No need to normalize, we'll do that # later. - r = self.xobjin - rr = self.yobjin + r = self.x_morph_in + rr = self.y_morph_in r0 = r[len(r) // 2] gaussian = numpy.exp(-0.5 * ((r - r0) / self.smear) ** 2) @@ -74,7 +74,7 @@ def morph(self, xobj, yobj, xref, yref): # Normalize so that the integrated magnitude of the RDF doesn't change. rrbroad /= sum(gaussian) - self.yobjout = rrbroad + self.y_morph_out = rrbroad return self.xyallout diff --git a/diffpy/pdfmorph/morphs/morphstretch.py b/diffpy/pdfmorph/morphs/morphstretch.py index eec7b8ab..5f3148cf 100644 --- a/diffpy/pdfmorph/morphs/morphstretch.py +++ b/diffpy/pdfmorph/morphs/morphstretch.py @@ -14,7 +14,7 @@ ############################################################################## -"""class MorphStretch -- stretch the objective. +"""class MorphStretch -- stretch the morph. """ @@ -23,33 +23,33 @@ class MorphStretch(Morph): - '''Smear the objective function. + '''Smear the morph function. - This stretches (broadens) the objective. + This stretches (broadens) the morph. Configuration variables: - stretch -- The stretch factor to apply to yobjin. This is applied such + stretch -- The stretch factor to apply to y_morph_in. This is applied such that a feature at r is moved to r * (1 + stretch). ''' # Define input output types - summary = 'Stretch objective by desired amount' + summary = 'Stretch morph by desired amount' xinlabel = LABEL_RA yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_GR parnames = ["stretch"] - def morph(self, xobj, yobj, xref, yref): + def morph(self, x_morph, y_morph, x_target, y_target): """Resample arrays onto specified grid.""" - Morph.morph(self, xobj, yobj, xref, yref) + Morph.morph(self, x_morph, y_morph, x_target, y_target) if self.stretch == 0: return self.xyallout - r = self.xobjin / (1.0 + self.stretch) - self.yobjout = numpy.interp(r, self.xobjin, self.yobjin) + r = self.x_morph_in / (1.0 + self.stretch) + self.y_morph_out = numpy.interp(r, self.x_morph_in, self.y_morph_in) return self.xyallout diff --git a/diffpy/pdfmorph/pdfmorph_api.py b/diffpy/pdfmorph/pdfmorph_api.py index c0c934a8..6a660ba9 100644 --- a/diffpy/pdfmorph/pdfmorph_api.py +++ b/diffpy/pdfmorph/pdfmorph_api.py @@ -69,10 +69,10 @@ def morph_default_config(**kwargs): def pdfmorph( - xobj, - yobj, - xref, - yref, + x_morph, + y_morph, + x_target, + y_target, rmin=None, rmax=None, rstep=None, @@ -87,17 +87,17 @@ def pdfmorph( Parameters ---------- - xobj : numpy.array - An array of objective x values, i.e., those will be manipulated by + x_morph : numpy.array + An array of morphed 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 + y_morph : numpy.array + An array of morphed 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 + x_target : numpy.array + An array of target 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 + y_morph : numpy.array + An array of target y values, i.e., those will be kept constant by morphing. rmin : float, optional A value to specify lower r-limit of morph operations. @@ -138,7 +138,7 @@ def pdfmorph( - morph_chain : diffpy.pdfmorph.morphs.morphchain.MorphChain The instance of processed morph chain. - Calling ``xobj, yobj, xref, yref = morph_chain.xyallout`` + Calling ``x_morph, y_morph, x_target, y_target = morph_chain.xyallout`` will conviniently retrun morphed data and reference data - morphed_cfg : dict A dictionary of refined morphing parameters @@ -151,11 +151,11 @@ def pdfmorph( Examples -------- - # morphing (xobj, yobj) pair to (xref, yref) pair with scaling + # morphing (x_morph, y_morph) pair to (x_target, y_target) pair with scaling from diffpy.pdfmorph.pdfmorph_api 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) + morph_rv_dict = pdfmorph(x_morph, y_morph, x_target, y_target, **morph_cfg) # plot morhing result plot_morph(morph_rv_dict['morph_chain']) @@ -199,7 +199,7 @@ def pdfmorph( for opt in fixed_operations: refpars.remove(opt) # define refiner - refiner = ref.Refiner(chain, xobj, yobj, xref, yref) + refiner = ref.Refiner(chain, x_morph, y_morph, x_target, y_target) if pearson: refiner.residual = refiner._pearson if add_pearson: @@ -216,14 +216,14 @@ def pdfmorph( refiner.refine(*refpars) else: # no operation if refine=False or refpars is empty list - chain(xobj, yobj, xref, yref) + chain(x_morph, y_morph, x_target, y_target) # summary rw = tools.getRw(chain) pcc = tools.get_pearson(chain) # restore rgrid chain[0] = morphs.Morph() - chain(xobj, yobj, xref, yref) + chain(x_morph, y_morph, x_target, y_target) # print output if verbose: if fixed_operations: @@ -266,10 +266,10 @@ def plot_morph(chain, ax=None, **kwargs): """ if ax is None: fig, ax = plt.subplots() - rfit, grfit = chain.xyobjout - rdat, grdat = chain.xyrefout - l_list = ax.plot(rfit, grfit, label='objective', **kwargs) - l_list += ax.plot(rdat, grdat, label='reference', **kwargs) + rfit, grfit = chain.xy_morph_out + rdat, grdat = chain.xy_target_out + l_list = ax.plot(rfit, grfit, label='***MORPH***', **kwargs) + l_list += ax.plot(rdat, grdat, label='***TARGET***', **kwargs) ax.set_xlim([chain.config['rmin'], chain.config['rmax']]) ax.legend() ax.set_xlabel(r'r ($\mathrm{\AA}$)') diff --git a/diffpy/pdfmorph/pdfmorphapp.py b/diffpy/pdfmorph/pdfmorphapp.py index 7eece397..073484fb 100755 --- a/diffpy/pdfmorph/pdfmorphapp.py +++ b/diffpy/pdfmorph/pdfmorphapp.py @@ -213,8 +213,8 @@ def main(): parser.error("You must supply FILE1 and FILE2") # Get the PDFs - xobj, yobj = getPDFFromFile(pargs[0]) - xref, yref = getPDFFromFile(pargs[1]) + x_morph, y_morph = getPDFFromFile(pargs[0]) + x_target, y_target = getPDFFromFile(pargs[1]) # Get configuration values scale_in = 'None' @@ -298,7 +298,7 @@ def main(): refpars = list(refpars) # Refine or execute the morph - refiner = refine.Refiner(chain, xobj, yobj, xref, yref) + refiner = refine.Refiner(chain, x_morph, y_morph, x_target, y_target) if opts.pearson: refiner.residual = refiner._pearson if opts.addpearson: @@ -320,14 +320,14 @@ def main(): except ValueError as e: parser.custom_error(str(e)) else: - chain(xobj, yobj, xref, yref) + chain(x_morph, y_morph, x_target, y_target) # Get Rw for the morph range rw = tools.getRw(chain) pcc = tools.get_pearson(chain) # Replace the MorphRGrid with Morph identity chain[0] = morphs.Morph() - chain(xobj, yobj, xref, yref) + chain(x_morph, y_morph, x_target, y_target) morphs_in = "\n# Input morphing parameters:" morphs_in += f"\n# scale = {scale_in}" @@ -354,7 +354,7 @@ def main(): if opts.savefile == "-": outfile = sys.stdout print(header, file=outfile) - numpy.savetxt(outfile, numpy.transpose([chain.xobjout, chain.yobjout])) + numpy.savetxt(outfile, numpy.transpose([chain.x_morph_out, chain.y_morph_out])) # Do not close stdout # Save to file @@ -362,7 +362,7 @@ def main(): try: with open(opts.savefile, 'w') as outfile: print(header, file=outfile) - numpy.savetxt(outfile, numpy.transpose([chain.xobjout, chain.yobjout])) + numpy.savetxt(outfile, numpy.transpose([chain.x_morph_out, chain.y_morph_out])) outfile.close() # Close written file path_name = Path(outfile.name).absolute() @@ -374,8 +374,8 @@ def main(): parser.custom_error(str(e)) if opts.plot: - pairlist = [chain.xyobjout, chain.xyrefout] - labels = ["objective", "reference"] + pairlist = [chain.xy_morph_out, chain.xy_target_out] + labels = ["***MORPH***", "***TARGET***"] # 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 diff --git a/diffpy/pdfmorph/refine.py b/diffpy/pdfmorph/refine.py index 94df60fa..486aa8a2 100644 --- a/diffpy/pdfmorph/refine.py +++ b/diffpy/pdfmorph/refine.py @@ -32,26 +32,26 @@ class Refiner(object): Attributes: chain -- The Morph or MorphChain to refine - xobj, yobj -- Objective arrays. - xref, yref -- Reference arrays. + x_morph, y_morph -- Morphed arrays. + x_target, y_target -- Target arrays. pars -- List of names of parameters to be refined. residual -- The residual function to optimize. Default _residual. Can be assigned to other functions. """ - def __init__(self, chain, xobj, yobj, xref, yref): + def __init__(self, chain, x_morph, y_morph, x_target, y_target): """Initialize the arrays. chain -- The Morph or MorphChain to refine - xobj, yobj -- Objective arrays. - xref, yref -- Reference arrays. + x_morph, y_morph -- Morphed arrays. + x_target, y_target -- Target arrays. """ self.chain = chain - self.xobj = xobj - self.yobj = yobj - self.xref = xref - self.yref = yref + self.x_morph = x_morph + self.y_morph = y_morph + self.x_target = x_target + self.y_target = y_target self.pars = [] self.residual = self._residual return @@ -65,10 +65,10 @@ def _update_chain(self, pvals): def _residual(self, pvals): """Standard vector residual.""" self._update_chain(pvals) - _xobj, _yobj, _xref, _yref = self.chain( - self.xobj, self.yobj, self.xref, self.yref + _x_morph, _y_morph, _x_target, _y_target = self.chain( + self.x_morph, self.y_morph, self.x_target, self.y_target ) - rvec = _yref - _yobj + rvec = _y_target - _y_morph return rvec def _pearson(self, pvals): @@ -79,11 +79,11 @@ def _pearson(self, pvals): largest. """ self._update_chain(pvals) - _xobj, _yobj, _xref, _yref = self.chain( - self.xobj, self.yobj, self.xref, self.yref + _x_morph, _y_morph, _x_target, _y_target = self.chain( + self.x_morph, self.y_morph, self.x_target, self.y_target ) - pcc, pval = pearsonr(_yobj, _yref) - return ones_like(_xobj) * exp(-pcc) + pcc, pval = pearsonr(_y_morph, _y_target) + return ones_like(_x_morph) * exp(-pcc) def _add_pearson(self, pvals): """Refine both the pearson and residual.""" diff --git a/diffpy/pdfmorph/tests/test_morph_func.py b/diffpy/pdfmorph/tests/test_morph_func.py index 97096c10..ff011192 100644 --- a/diffpy/pdfmorph/tests/test_morph_func.py +++ b/diffpy/pdfmorph/tests/test_morph_func.py @@ -8,42 +8,42 @@ def test_morphfunc_verbose(): lb, ub = 1, 2 - xref = np.arange(0.01, 5, 0.01) - yref = heaviside(xref, lb, ub) + x_target = np.arange(0.01, 5, 0.01) + y_target = heaviside(x_target, lb, ub) # expand 30% stretch = 0.3 - xobj = xref.copy() - yobj = heaviside(xref, lb * (1 + stretch), ub * (1 + stretch)) + x_morph = x_target.copy() + y_morph = heaviside(x_target, lb * (1 + stretch), ub * (1 + stretch)) cfg = morph_default_config(stretch=0.1) # off init - morph_rv = pdfmorph(xobj, yobj, xref, yref, verbose=True, **cfg) + morph_rv = pdfmorph(x_morph, y_morph, x_target, y_target, verbose=True, **cfg) def test_fixed_morph_with_morphfunc(): lb, ub = 1, 2 - xref = np.arange(0.01, 5, 0.01) - yref = heaviside(xref, lb, ub) + x_target = np.arange(0.01, 5, 0.01) + y_target = heaviside(x_target, lb, ub) # expand 30% stretch = 0.3 - xobj = xref.copy() - yobj = heaviside(xref, lb * (1 + stretch), ub * (1 + stretch)) + x_morph = x_target.copy() + y_morph = heaviside(x_target, lb * (1 + stretch), ub * (1 + stretch)) cfg = morph_default_config(stretch=0.1) # off init cfg['scale'] = 30 morph_rv = pdfmorph( - xobj, yobj, xref, yref, verbose=True, fixed_operations=['scale'], **cfg + x_morph, y_morph, x_target, y_target, verbose=True, fixed_operations=['scale'], **cfg ) def test_stretch_with_morphfunc(): # use the same setup as test_moprhchain lb, ub = 1, 2 - xref = np.arange(0.01, 5, 0.01) - yref = heaviside(xref, lb, ub) + x_target = np.arange(0.01, 5, 0.01) + y_target = heaviside(x_target, lb, ub) # expand 30% stretch = 0.3 - xobj = xref.copy() - yobj = heaviside(xref, lb * (1 + stretch), ub * (1 + stretch)) + x_morph = x_target.copy() + y_morph = heaviside(x_target, lb * (1 + stretch), ub * (1 + stretch)) cfg = morph_default_config(stretch=0.1) # off init - morph_rv = pdfmorph(xobj, yobj, xref, yref, **cfg) + morph_rv = pdfmorph(x_morph, y_morph, x_target, y_target, **cfg) morphed_cfg = morph_rv['morphed_config'] # verified they are morphable x1, y1, x0, y0 = morph_rv['morph_chain'].xyallout @@ -57,15 +57,15 @@ def test_stretch_with_morphfunc(): def test_scale_with_morphfunc(): lb, ub = 1, 2 - xref = np.arange(0.01, 5, 0.01) - yref = heaviside(xref, lb, ub) + x_target = np.arange(0.01, 5, 0.01) + y_target = heaviside(x_target, lb, ub) # scale 300% scale = 3 - xobj = xref.copy() - yobj = yref.copy() - yobj *= scale + x_morph = x_target.copy() + y_morph = y_target.copy() + y_morph *= scale cfg = morph_default_config(scale=1.5) # off init - morph_rv = pdfmorph(xobj, yobj, xref, yref, **cfg) + morph_rv = pdfmorph(x_morph, y_morph, x_target, y_target, **cfg) morphed_cfg = morph_rv['morphed_config'] # verified they are morphable x1, y1, x0, y0 = morph_rv['morph_chain'].xyallout @@ -81,12 +81,12 @@ def test_smear_with_morph_func(): smear = 0.15 sigbroad = (sigma0**2 + smear**2) ** 0.5 r0 = 7 * np.pi / 22.0 * 2 - xref = np.arange(0.01, 5, 0.01) - yref = np.exp(-0.5 * ((xref - r0) / sigbroad) ** 2) - xobj = xref.copy() - yobj = np.exp(-0.5 * ((xobj - r0) / sigma0) ** 2) + x_target = np.arange(0.01, 5, 0.01) + y_target = np.exp(-0.5 * ((x_target - r0) / sigbroad) ** 2) + x_morph = x_target.copy() + y_morph = np.exp(-0.5 * ((x_morph - r0) / sigma0) ** 2) cfg = morph_default_config(smear=0.1, scale=1.1, stretch=0.1) # off init - morph_rv = pdfmorph(xobj, yobj, xref, yref, **cfg) + morph_rv = pdfmorph(x_morph, y_morph, x_target, y_target, **cfg) morphed_cfg = morph_rv['morphed_config'] # verified they are morphable x1, y1, x0, y0 = morph_rv['morph_chain'].xyallout diff --git a/diffpy/pdfmorph/tests/test_morphchain.py b/diffpy/pdfmorph/tests/test_morphchain.py index 20ba2fb0..045e6c6e 100644 --- a/diffpy/pdfmorph/tests/test_morphchain.py +++ b/diffpy/pdfmorph/tests/test_morphchain.py @@ -18,10 +18,10 @@ class TestMorphChain(unittest.TestCase): def setUp(self): - self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.ones_like(self.xobj) - self.xref = numpy.arange(0.01, 5, 0.01) - self.yref = 3 * numpy.ones_like(self.xref) + self.x_morph = numpy.arange(0.01, 5, 0.01) + self.y_morph = numpy.ones_like(self.x_morph) + self.x_target = numpy.arange(0.01, 5, 0.01) + self.y_target = 3 * numpy.ones_like(self.x_target) return @@ -39,16 +39,16 @@ def test_morph(self): mscale = MorphScale() chain = MorphChain(config, mgrid, mscale) - xobj, yobj, xref, yref = chain(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = chain(self.x_morph, self.y_morph, self.x_target, self.y_target) - self.assertTrue((xobj == xref).all()) - self.assertAlmostEqual(xobj[0], 1.0) - self.assertAlmostEqual(xobj[-1], 4.9) - self.assertAlmostEqual(xobj[1] - xobj[0], 0.1) - self.assertAlmostEqual(xobj[0], mgrid.rmin) - self.assertAlmostEqual(xobj[-1], mgrid.rmax - mgrid.rstep) - self.assertAlmostEqual(xobj[1] - xobj[0], mgrid.rstep) - self.assertTrue(numpy.allclose(yobj, yref)) + self.assertTrue((x_morph == x_target).all()) + self.assertAlmostEqual(x_morph[0], 1.0) + self.assertAlmostEqual(x_morph[-1], 4.9) + self.assertAlmostEqual(x_morph[1] - x_morph[0], 0.1) + self.assertAlmostEqual(x_morph[0], mgrid.rmin) + self.assertAlmostEqual(x_morph[-1], mgrid.rmax - mgrid.rstep) + self.assertAlmostEqual(x_morph[1] - x_morph[0], mgrid.rstep) + self.assertTrue(numpy.allclose(y_morph, y_target)) return diff --git a/diffpy/pdfmorph/tests/test_morphpdftordf.py b/diffpy/pdfmorph/tests/test_morphpdftordf.py index 19f7cc0f..d79a5496 100644 --- a/diffpy/pdfmorph/tests/test_morphpdftordf.py +++ b/diffpy/pdfmorph/tests/test_morphpdftordf.py @@ -16,10 +16,10 @@ class TestMorphXtalPDFtoRDF(unittest.TestCase): def setUp(self): - self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.exp(-0.5 * (self.xobj - 1.0) ** 2) / self.xobj - self.xobj - self.xref = numpy.arange(0.01, 5, 0.01) - self.yref = numpy.exp(-0.5 * (self.xobj - 2.0) ** 2) / self.xobj - self.xobj + self.x_morph = numpy.arange(0.01, 5, 0.01) + self.y_morph = numpy.exp(-0.5 * (self.x_morph - 1.0) ** 2) / self.x_morph - self.x_morph + self.x_target = numpy.arange(0.01, 5, 0.01) + self.y_target = numpy.exp(-0.5 * (self.x_morph - 2.0) ** 2) / self.x_morph - self.x_morph return def test_morph(self): @@ -27,12 +27,12 @@ def test_morph(self): config = {"baselineslope": -1.0} morph = MorphXtalPDFtoRDF(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - rdf1 = numpy.exp(-0.5 * (xobj - 1.0) ** 2) - rdf2 = numpy.exp(-0.5 * (xref - 2.0) ** 2) - self.assertTrue(numpy.allclose(rdf1, yobj)) - self.assertTrue(numpy.allclose(rdf2, yref)) + rdf1 = numpy.exp(-0.5 * (x_morph - 1.0) ** 2) + rdf2 = numpy.exp(-0.5 * (x_target - 2.0) ** 2) + self.assertTrue(numpy.allclose(rdf1, y_morph)) + self.assertTrue(numpy.allclose(rdf2, y_target)) return diff --git a/diffpy/pdfmorph/tests/test_morphrdftopdf.py b/diffpy/pdfmorph/tests/test_morphrdftopdf.py index f8b4bc37..03ec7cfa 100644 --- a/diffpy/pdfmorph/tests/test_morphrdftopdf.py +++ b/diffpy/pdfmorph/tests/test_morphrdftopdf.py @@ -16,10 +16,10 @@ class TestMorphXtalRDFtoPDF(unittest.TestCase): def setUp(self): - self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.exp(-0.5 * (self.xobj - 1.0) ** 2) - self.xref = numpy.arange(0.01, 5, 0.01) - self.yref = numpy.exp(-0.5 * (self.xobj - 2.0) ** 2) + self.x_morph = numpy.arange(0.01, 5, 0.01) + self.y_morph = numpy.exp(-0.5 * (self.x_morph - 1.0) ** 2) + self.x_target = numpy.arange(0.01, 5, 0.01) + self.y_target = numpy.exp(-0.5 * (self.x_morph - 2.0) ** 2) return def test_morph(self): @@ -27,12 +27,12 @@ def test_morph(self): config = {"baselineslope": -1.0} morph = MorphXtalRDFtoPDF(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - rdf1 = numpy.exp(-0.5 * (xobj - 1.0) ** 2) / xobj - xobj - rdf2 = numpy.exp(-0.5 * (xref - 2.0) ** 2) / xref - xref - self.assertTrue(numpy.allclose(rdf1, yobj)) - self.assertTrue(numpy.allclose(rdf2, yref)) + rdf1 = numpy.exp(-0.5 * (x_morph - 1.0) ** 2) / x_morph - x_morph + rdf2 = numpy.exp(-0.5 * (x_target - 2.0) ** 2) / x_target - x_target + self.assertTrue(numpy.allclose(rdf1, y_morph)) + self.assertTrue(numpy.allclose(rdf2, y_target)) return diff --git a/diffpy/pdfmorph/tests/test_morphresolution.py b/diffpy/pdfmorph/tests/test_morphresolution.py index 670f34be..9d819f9e 100644 --- a/diffpy/pdfmorph/tests/test_morphresolution.py +++ b/diffpy/pdfmorph/tests/test_morphresolution.py @@ -16,10 +16,10 @@ class TestMorphScale(unittest.TestCase): def setUp(self): - objfile = os.path.join(testdata_dir, "ni_qmax25.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True) - reffile = os.path.join(testdata_dir, "ni_qmax25_qdamp0.01.cgr") - self.xref, self.yref = numpy.loadtxt(reffile, unpack=True) + morph_file = os.path.join(testdata_dir, "ni_qmax25.cgr") + self.x_morph, self.y_morph = numpy.loadtxt(morph_file, unpack=True) + target_file = os.path.join(testdata_dir, "ni_qmax25_qdamp0.01.cgr") + self.x_target, self.y_target = numpy.loadtxt(target_file, unpack=True) return def test_morph(self): @@ -27,10 +27,10 @@ def test_morph(self): config = {"qdamp": 0.01} morph = MorphResolutionDamping(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - self.assertTrue(numpy.allclose(self.yref, yref)) - self.assertTrue(numpy.allclose(yobj, yref)) + self.assertTrue(numpy.allclose(self.y_target, y_target)) + self.assertTrue(numpy.allclose(y_morph, y_target)) return diff --git a/diffpy/pdfmorph/tests/test_morphrgrid.py b/diffpy/pdfmorph/tests/test_morphrgrid.py index bf485121..27adbf13 100644 --- a/diffpy/pdfmorph/tests/test_morphrgrid.py +++ b/diffpy/pdfmorph/tests/test_morphrgrid.py @@ -17,19 +17,19 @@ ############################################################################## class TestMorphRGrid(unittest.TestCase): def setUp(self): - self.xobj = numpy.arange(0, 10, 0.01) - self.yobj = self.xobj.copy() - self.xref = numpy.arange(1, 5, 0.01) - self.yref = self.xref**2 + self.x_morph = numpy.arange(0, 10, 0.01) + self.y_morph = self.x_morph.copy() + self.x_target = numpy.arange(1, 5, 0.01) + self.y_target = self.x_target ** 2 return def _runTests(self, xyallout, morph): - xobj, yobj, xref, yref = xyallout - self.assertTrue((xobj == xref).all()) - self.assertAlmostEqual(xobj[0], morph.rmin) - self.assertAlmostEqual(xobj[-1], morph.rmax - morph.rstep) - self.assertAlmostEqual(xobj[1] - xobj[0], morph.rstep) - self.assertEqual(len(yobj), len(yref)) + x_morph, y_morph, x_target, y_target = xyallout + self.assertTrue((x_morph == x_target).all()) + self.assertAlmostEqual(x_morph[0], morph.rmin) + self.assertAlmostEqual(x_morph[-1], morph.rmax - morph.rstep) + self.assertAlmostEqual(x_morph[1] - x_morph[0], morph.rstep) + self.assertEqual(len(y_morph), len(y_target)) return def testRangeInBounds(self): @@ -41,7 +41,7 @@ def testRangeInBounds(self): "rstep": 0.1, } morph = MorphRGrid(config) - xyallout = morph(self.xobj, self.yobj, self.xref, self.yref) + xyallout = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) self.assertAlmostEqual(config["rmin"], morph.rmin) self.assertAlmostEqual(config["rmax"], morph.rmax) self.assertAlmostEqual(config["rstep"], morph.rstep) @@ -57,7 +57,7 @@ def testRmaxOut(self): "rstep": 0.1, } morph = MorphRGrid(config) - xyallout = morph(self.xobj, self.yobj, self.xref, self.yref) + xyallout = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) self.assertAlmostEqual(config["rmin"], morph.rmin) self.assertAlmostEqual(5, morph.rmax) self.assertAlmostEqual(config["rstep"], morph.rstep) @@ -73,7 +73,7 @@ def testRminOut(self): "rstep": 0.01, } morph = MorphRGrid(config) - xyallout = morph(self.xobj, self.yobj, self.xref, self.yref) + xyallout = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) self.assertAlmostEqual(1.0, morph.rmin) self.assertAlmostEqual(config["rmax"], morph.rmax) self.assertAlmostEqual(config["rstep"], morph.rstep) @@ -89,7 +89,7 @@ def testRstepOut(self): "rstep": 0.001, } morph = MorphRGrid(config) - xyallout = morph(self.xobj, self.yobj, self.xref, self.yref) + xyallout = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) self.assertAlmostEqual(config["rmin"], morph.rmin) self.assertAlmostEqual(config["rmax"], morph.rmax) self.assertAlmostEqual(0.01, morph.rstep) diff --git a/diffpy/pdfmorph/tests/test_morphscale.py b/diffpy/pdfmorph/tests/test_morphscale.py index de8cd20b..1c5809a4 100644 --- a/diffpy/pdfmorph/tests/test_morphscale.py +++ b/diffpy/pdfmorph/tests/test_morphscale.py @@ -16,10 +16,10 @@ class TestMorphScale(unittest.TestCase): def setUp(self): - self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.ones_like(self.xobj) - self.xref = numpy.arange(0.01, 5, 0.01) - self.yref = 3 * numpy.ones_like(self.xref) + self.x_morph = numpy.arange(0.01, 5, 0.01) + self.y_morph = numpy.ones_like(self.x_morph) + self.x_target = numpy.arange(0.01, 5, 0.01) + self.y_target = 3 * numpy.ones_like(self.x_target) return def test_morph(self): @@ -27,10 +27,10 @@ def test_morph(self): config = {"scale": 2.0} morph = MorphScale(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - self.assertTrue(numpy.allclose(2 * self.yobj, yobj)) - self.assertTrue(numpy.allclose(self.yref, yref)) + self.assertTrue(numpy.allclose(2 * self.y_morph, y_morph)) + self.assertTrue(numpy.allclose(self.y_target, y_target)) return diff --git a/diffpy/pdfmorph/tests/test_morphshape.py b/diffpy/pdfmorph/tests/test_morphshape.py index e9077d0f..8693b9ed 100644 --- a/diffpy/pdfmorph/tests/test_morphshape.py +++ b/diffpy/pdfmorph/tests/test_morphshape.py @@ -16,10 +16,10 @@ class TestMorphSphere(unittest.TestCase): def setUp(self): - objfile = os.path.join(testdata_dir, "ni_qmax25.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True) - reffile = os.path.join(testdata_dir, "ni_qmax25_psize30.cgr") - self.xref, self.yref = numpy.loadtxt(reffile, unpack=True) + morph_file = os.path.join(testdata_dir, "ni_qmax25.cgr") + self.x_morph, self.y_morph = numpy.loadtxt(morph_file, unpack=True) + target_file = os.path.join(testdata_dir, "ni_qmax25_psize30.cgr") + self.x_target, self.y_target = numpy.loadtxt(target_file, unpack=True) return def test_morph(self): @@ -27,10 +27,10 @@ def test_morph(self): config = {"radius": 17.5} morph = MorphSphere(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - self.assertTrue(numpy.allclose(self.yref, yref)) - self.assertTrue(numpy.allclose(yobj, yref)) + self.assertTrue(numpy.allclose(self.y_target, y_target)) + self.assertTrue(numpy.allclose(y_morph, y_target)) return @@ -39,10 +39,10 @@ def test_morph(self): class TestMorphSpheroid(unittest.TestCase): def setUp(self): - objfile = os.path.join(testdata_dir, "ni_qmax25.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True) - reffile = os.path.join(testdata_dir, "ni_qmax25_e17.5_p5.0.cgr") - self.xref, self.yref = numpy.loadtxt(reffile, unpack=True) + morph_file = os.path.join(testdata_dir, "ni_qmax25.cgr") + self.x_morph, self.y_morph = numpy.loadtxt(morph_file, unpack=True) + target_file = os.path.join(testdata_dir, "ni_qmax25_e17.5_p5.0.cgr") + self.x_target, self.y_target = numpy.loadtxt(target_file, unpack=True) return def test_morph(self): @@ -53,10 +53,10 @@ def test_morph(self): } morph = MorphSpheroid(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - self.assertTrue(numpy.allclose(self.yref, yref)) - self.assertTrue(numpy.allclose(yobj, yref)) + self.assertTrue(numpy.allclose(self.y_target, y_target)) + self.assertTrue(numpy.allclose(y_morph, y_target)) return diff --git a/diffpy/pdfmorph/tests/test_morphsmear.py b/diffpy/pdfmorph/tests/test_morphsmear.py index 2d74e237..b2d86b1c 100644 --- a/diffpy/pdfmorph/tests/test_morphsmear.py +++ b/diffpy/pdfmorph/tests/test_morphsmear.py @@ -18,10 +18,10 @@ class TestMorphSmear(unittest.TestCase): def setUp(self): self.smear = 0.1 self.r0 = 7 * numpy.pi / 22.0 * 2 - self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.exp(-0.5 * ((self.xobj - self.r0) / self.smear) ** 2) - self.xref = self.xobj.copy() - self.yref = self.xref.copy() + self.x_morph = numpy.arange(0.01, 5, 0.01) + self.y_morph = numpy.exp(-0.5 * ((self.x_morph - self.r0) / self.smear) ** 2) + self.x_target = self.x_morph.copy() + self.y_target = self.x_target.copy() return def test_morph(self): @@ -29,17 +29,17 @@ def test_morph(self): morph = MorphSmear() morph.smear = 0.15 - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - # Reference should be unchanged - self.assertTrue(numpy.allclose(self.yref, yref)) + # Target should be unchanged + self.assertTrue(numpy.allclose(self.y_target, y_target)) # Compare to broadened Gaussian sigbroad = (self.smear**2 + morph.smear**2) ** 0.5 - ysmear = numpy.exp(-0.5 * ((self.xobj - self.r0) / sigbroad) ** 2) + ysmear = numpy.exp(-0.5 * ((self.x_morph - self.r0) / sigbroad) ** 2) ysmear *= self.smear / sigbroad - self.assertTrue(numpy.allclose(ysmear, yobj)) + self.assertTrue(numpy.allclose(ysmear, y_morph)) return diff --git a/diffpy/pdfmorph/tests/test_morphstretch.py b/diffpy/pdfmorph/tests/test_morphstretch.py index e2d4812a..bffb3a22 100644 --- a/diffpy/pdfmorph/tests/test_morphstretch.py +++ b/diffpy/pdfmorph/tests/test_morphstretch.py @@ -16,11 +16,11 @@ class TestMorphStretch(unittest.TestCase): def setUp(self): - self.xobj = numpy.arange(0.01, 5, 0.01) + self.x_morph = numpy.arange(0.01, 5, 0.01) # A step function between 2 and 3 - self.yobj = heaviside(self.xobj, 1, 2) - self.xref = self.xobj.copy() - self.yref = self.xref.copy() + self.y_morph = heaviside(self.x_morph, 1, 2) + self.x_target = self.x_morph.copy() + self.y_target = self.x_target.copy() return def test_morph(self): @@ -29,32 +29,32 @@ def test_morph(self): # Stretch by 50% morph.stretch = 0.5 - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - # Reference should be unchanged - self.assertTrue(numpy.allclose(self.yref, yref)) + # Target should be unchanged + self.assertTrue(numpy.allclose(self.y_target, y_target)) # Compare to new function. Note that due to interpolation, there will # be issues at the boundary of the step function. This will distort up # to two points in the interpolated function, and those points should # be off by at most 0.5. - newstep = heaviside(xobj, 1.5, 3) - res = sum(numpy.fabs(newstep - yobj)) + newstep = heaviside(x_morph, 1.5, 3) + res = sum(numpy.fabs(newstep - y_morph)) self.assertTrue(res < 1) # Stretch by -10% morph.stretch = -0.1 - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) + x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target) - # Reference should be unchanged - self.assertTrue(numpy.allclose(self.yref, yref)) + # Target should be unchanged + self.assertTrue(numpy.allclose(self.y_target, y_target)) # Compare to new function. Note that due to interpolation, there will # be issues at the boundary of the step function. This will distort up # to two points in the interpolated function, and those points should # be off by at most 0.5. - newstep = heaviside(xobj, 0.9, 1.8) - res = sum(numpy.fabs(newstep - yobj)) + newstep = heaviside(x_morph, 0.9, 1.8) + res = sum(numpy.fabs(newstep - y_morph)) self.assertTrue(res < 1) return diff --git a/diffpy/pdfmorph/tests/test_plot_morph.py b/diffpy/pdfmorph/tests/test_plot_morph.py index b39d1927..eebf3a0c 100644 --- a/diffpy/pdfmorph/tests/test_plot_morph.py +++ b/diffpy/pdfmorph/tests/test_plot_morph.py @@ -11,14 +11,14 @@ # smoke test def test_plot_morph(): lb, ub = 1, 2 - xref = np.arange(0.01, 5, 0.01) - yref = heaviside(xref, lb, ub) + x_target = np.arange(0.01, 5, 0.01) + y_target = heaviside(x_target, lb, ub) # expand 30% stretch = 0.3 - xobj = xref.copy() - yobj = heaviside(xref, lb * (1 + stretch), ub * (1 + stretch)) + x_morph = x_target.copy() + y_morph = heaviside(x_target, lb * (1 + stretch), ub * (1 + stretch)) cfg = morph_default_config(stretch=0.1) # off init - morph_rv = pdfmorph(xobj, yobj, xref, yref, verbose=True, **cfg) + morph_rv = pdfmorph(x_morph, y_morph, x_target, y_target, verbose=True, **cfg) chain = morph_rv['morph_chain'] fig, ax = plt.subplots() l_list = plot_morph(chain, ax) diff --git a/diffpy/pdfmorph/tests/test_refine.py b/diffpy/pdfmorph/tests/test_refine.py index ece635c1..eb989e03 100644 --- a/diffpy/pdfmorph/tests/test_refine.py +++ b/diffpy/pdfmorph/tests/test_refine.py @@ -22,10 +22,10 @@ class TestRefine(unittest.TestCase): def setUp(self): - self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.ones_like(self.xobj) - self.xref = numpy.arange(0.01, 5, 0.01) - self.yref = 3 * numpy.ones_like(self.xref) + self.x_morph = numpy.arange(0.01, 5, 0.01) + self.y_morph = numpy.ones_like(self.x_morph) + self.x_target = numpy.arange(0.01, 5, 0.01) + self.y_target = 3 * numpy.ones_like(self.x_target) return def test_refine_morph(self): @@ -36,21 +36,21 @@ def test_refine_morph(self): } mscale = MorphScale(config) - refiner = Refiner(mscale, self.xobj, self.yobj, self.xref, self.yref) + refiner = Refiner(mscale, self.x_morph, self.y_morph, self.x_target, self.y_target) refiner.refine() - xobj, yobj, xref, yref = mscale.xyallout + x_morph, y_morph, x_target, y_target = mscale.xyallout - self.assertTrue((xobj == xref).all()) - self.assertTrue(numpy.allclose(yobj, yref)) + self.assertTrue((x_morph == x_target).all()) + self.assertTrue(numpy.allclose(y_morph, y_target)) self.assertAlmostEqual(config["scale"], 3.0) return def test_refine_chain(self): """refine a chain""" # Give this some texture - self.yobj[30:] = 5 - self.yref[33:] = 15 + self.y_morph[30:] = 5 + self.y_target[33:] = 15 # Define the morphs config = {"scale": 1.0, "stretch": 0.0} @@ -59,15 +59,15 @@ def test_refine_chain(self): mstretch = MorphStretch(config) chain = MorphChain(config, mscale, mstretch) - refiner = Refiner(chain, self.xobj, self.yobj, self.xref, self.yref) + refiner = Refiner(chain, self.x_morph, self.y_morph, self.x_target, self.y_target) res = refiner.refine() - # Compare the objective to the reference. Note that due to + # Compare the morph to the target. Note that due to # interpolation, there will be issues at the boundary of the step # function. - xobj, yobj, xref, yref = chain.xyallout + x_morph, y_morph, x_target, y_target = chain.xyallout err = 15.0 * 2 - res = sum(numpy.fabs(yref - yobj)) + res = sum(numpy.fabs(y_target - y_morph)) self.assertTrue(res < err) self.assertAlmostEqual(chain.scale, 3, 2) self.assertAlmostEqual(chain.stretch, 0.1, 2) @@ -79,11 +79,11 @@ def test_refine_chain(self): class TestRefineUC(unittest.TestCase): def setUp(self): - objfile = os.path.join(testdata_dir, "nickel_ss0.01.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True, skiprows=8) - reffile = os.path.join(testdata_dir, "nickel_ss0.02_eps0.002.cgr") - self.xref, self.yref = numpy.loadtxt(reffile, unpack=True, skiprows=8) - self.yref *= 1.5 + morph_file = os.path.join(testdata_dir, "nickel_ss0.01.cgr") + self.x_morph, self.y_morph = numpy.loadtxt(morph_file, unpack=True, skiprows=8) + target_file = os.path.join(testdata_dir, "nickel_ss0.02_eps0.002.cgr") + self.x_target, self.y_target = numpy.loadtxt(target_file, unpack=True, skiprows=8) + self.y_target *= 1.5 return def test_refine(self): @@ -103,19 +103,19 @@ def test_refine(self): chain.append(MorphSmear()) chain.append(MorphXtalRDFtoPDF()) - refiner = Refiner(chain, self.xobj, self.yobj, self.xref, self.yref) + refiner = Refiner(chain, self.x_morph, self.y_morph, self.x_target, self.y_target) # Do this as two-stage fit. First refine amplitude parameters, and then # position parameters. refiner.refine("scale", "smear") refiner.refine("scale", "stretch", "smear") - xobj, yobj, xref, yref = chain.xyallout + x_morph, y_morph, x_target, y_target = chain.xyallout # We want the fit good to 1%. We will disregard the last bit of the # fit, since we know we have unavoidable edge effects there. - sel = xobj < 9.5 - yrsel = yref[sel] - diff = yrsel - yobj[sel] + sel = x_morph < 9.5 + yrsel = y_target[sel] + diff = yrsel - y_morph[sel] rw = (numpy.dot(diff, diff) / numpy.dot(yrsel, yrsel)) ** 0.5 self.assertTrue(rw < 0.01) return diff --git a/diffpy/pdfmorph/tests/test_tools.py b/diffpy/pdfmorph/tests/test_tools.py index 77cddc34..024f0f0d 100644 --- a/diffpy/pdfmorph/tests/test_tools.py +++ b/diffpy/pdfmorph/tests/test_tools.py @@ -19,14 +19,14 @@ ############################################################################## class TestTools(unittest.TestCase): def setUp(self): - objfile = os.path.join(testdata_dir, "nickel_ss0.01.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True) + morph_file = os.path.join(testdata_dir, "nickel_ss0.01.cgr") + self.x_morph, self.y_morph = numpy.loadtxt(morph_file, unpack=True) self.rho0 = 0.0917132 return def test_estimateBaselineSlope(self): """check estimateBaselineSlope() using calculated data""" - slope = tools.estimateBaselineSlope(self.xobj, self.yobj) + slope = tools.estimateBaselineSlope(self.x_morph, self.y_morph) slopecalc = -4 * numpy.pi * self.rho0 self.assertTrue(numpy.allclose(slopecalc, slope, 1e-2)) return @@ -36,7 +36,7 @@ def test_estimateScale(self): import random x = random.random() - scale = tools.estimateScale(self.yobj, x * self.yobj) + scale = tools.estimateScale(self.y_morph, x * self.y_morph) self.assertAlmostEqual(x, scale) return diff --git a/diffpy/pdfmorph/tools.py b/diffpy/pdfmorph/tools.py index 208e7916..9f343fb1 100644 --- a/diffpy/pdfmorph/tools.py +++ b/diffpy/pdfmorph/tools.py @@ -21,10 +21,10 @@ import numpy -def estimateScale(yobjin, yrefin): - """Set the scale that best matches the objective to the reference.""" +def estimateScale(y_morph_in, y_target_in): + """Set the scale that best matches the morph to the target.""" dot = numpy.dot - scale = dot(yobjin, yrefin) / dot(yobjin, yobjin) + scale = dot(y_morph_in, y_target_in) / dot(y_morph_in, y_morph_in) return scale @@ -80,10 +80,10 @@ def chiv(pars): def getRw(chain): """Get Rw from the outputs of a morph or chain.""" # Make sure we put these on the proper grid - xobj, yobj, xref, yref = chain.xyallout - diff = yref - yobj + x_morph, y_morph, x_target, y_target = chain.xyallout + diff = y_target - y_morph rw = numpy.dot(diff, diff) - rw /= numpy.dot(yref, yref) + rw /= numpy.dot(y_target, y_target) rw = rw**0.5 return rw @@ -91,8 +91,8 @@ def getRw(chain): def get_pearson(chain): from scipy.stats import pearsonr - xobj, yobj, xref, yref = chain.xyallout - pcc, pval = pearsonr(yobj, yref) + x_morph, y_morph, x_target, y_target = chain.xyallout + pcc, pval = pearsonr(y_morph, y_target) return pcc diff --git a/doc/source/quickstart.rst b/doc/source/quickstart.rst index 6bf4a728..29383c0c 100644 --- a/doc/source/quickstart.rst +++ b/doc/source/quickstart.rst @@ -77,8 +77,8 @@ Basic PDFmorph Workflow will get morphed, while the second PDF file argument you provide (here, ``darkSub_rh20_C_44.gr``) is the PDF which acts as the model and does not get morphed. Hereinafter, - we will refer to the first PDF argument as the "objective" - and the second as the "reference", as the PDFmorph display + we will refer to the first PDF argument as the "morph" + and the second as the "target", as the PDFmorph display does. 6. Now, we will start the morphing process, which requires us to From fb534efb95451147d9866ad77b0c336cde67b75b Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Sat, 17 Jun 2023 23:44:57 -0400 Subject: [PATCH 4/4] Add options to change label names on plot --- diffpy/pdfmorph/morphs/morph.py | 12 ++++++------ diffpy/pdfmorph/pdfmorph_api.py | 4 ++-- diffpy/pdfmorph/pdfmorphapp.py | 27 ++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/diffpy/pdfmorph/morphs/morph.py b/diffpy/pdfmorph/morphs/morph.py index 324fce38..8f86a6c9 100644 --- a/diffpy/pdfmorph/morphs/morph.py +++ b/diffpy/pdfmorph/morphs/morph.py @@ -163,14 +163,14 @@ def checkConfig(self): def plotInputs(self, xylabels=True): '''Plot input arrays using matplotlib.pyplot - xylabels -- flag for updating x and y axis labels + xylabels -- flag for updating x and y axes labels Return a list of matplotlib line objects. ''' from matplotlib.pyplot import plot, xlabel, ylabel - rv = plot(self.x_target_in, self.y_target_in, label="***TARGET***") - rv = plot(self.x_morph_in, self.y_morph_in, label="***MORPH***") + rv = plot(self.x_target_in, self.y_target_in, label="target") + rv = plot(self.x_morph_in, self.y_morph_in, label="morph") if xylabels: xlabel(self.xinlabel) ylabel(self.yinlabel) @@ -179,7 +179,7 @@ def plotInputs(self, xylabels=True): def plotOutputs(self, xylabels=True, **plotargs): '''Plot output arrays using matplotlib.pyplot - xylabels -- flag for updating x and y axis labels + xylabels -- flag for updating x and y axes labels plotargs -- arguments passed to the pylab plot function. Note that "label" will be ignored. @@ -189,8 +189,8 @@ def plotOutputs(self, xylabels=True, **plotargs): pargs = dict(plotargs) pargs.pop("label", None) - rv = plot(self.x_target_out, self.y_target_out, label="***TARGET***", **pargs) - rv = plot(self.x_morph_out, self.y_morph_out, label="***MORPH***", **pargs) + rv = plot(self.x_target_out, self.y_target_out, label="target", **pargs) + rv = plot(self.x_morph_out, self.y_morph_out, label="morph", **pargs) if xylabels: xlabel(self.xoutlabel) ylabel(self.youtlabel) diff --git a/diffpy/pdfmorph/pdfmorph_api.py b/diffpy/pdfmorph/pdfmorph_api.py index 6a660ba9..a9467c44 100644 --- a/diffpy/pdfmorph/pdfmorph_api.py +++ b/diffpy/pdfmorph/pdfmorph_api.py @@ -268,8 +268,8 @@ def plot_morph(chain, ax=None, **kwargs): fig, ax = plt.subplots() rfit, grfit = chain.xy_morph_out rdat, grdat = chain.xy_target_out - l_list = ax.plot(rfit, grfit, label='***MORPH***', **kwargs) - l_list += ax.plot(rdat, grdat, label='***TARGET***', **kwargs) + l_list = ax.plot(rfit, grfit, label='morph', **kwargs) + l_list += ax.plot(rdat, grdat, label='target', **kwargs) ax.set_xlim([chain.config['rmin'], chain.config['rmax']]) ax.legend() ax.set_xlabel(r'r ($\mathrm{\AA}$)') diff --git a/diffpy/pdfmorph/pdfmorphapp.py b/diffpy/pdfmorph/pdfmorphapp.py index 073484fb..ef3fc8ca 100755 --- a/diffpy/pdfmorph/pdfmorphapp.py +++ b/diffpy/pdfmorph/pdfmorphapp.py @@ -178,6 +178,24 @@ def custom_error(self, msg): dest="plot", help="Do not show the plot.", ) + group.add_option( + '--usefilenames', + action="store_true", + dest="usefilenames", + help="Use the file names as labels on plot." + ) + group.add_option( + '--mlabel', + metavar="MLABEL", + dest="mlabel", + help="Set label for morphed data to MLABEL on plot. Ignored if using file names as labels.", + ) + group.add_option( + '--tlabel', + metavar="TLABEL", + dest="tlabel", + help="Set label for target data to TLABEL on plot. Ignored if using file names as labels.", + ) group.add_option( '--pmin', type="float", help="Minimum r-value to plot. Defaults to RMIN." ) @@ -375,7 +393,14 @@ def main(): if opts.plot: pairlist = [chain.xy_morph_out, chain.xy_target_out] - labels = ["***MORPH***", "***TARGET***"] + labels = ["morph", "target"] # Default label names + if opts.usefilenames: + labels = [pargs[0], pargs[1]] + else: + if opts.mlabel is not None: + labels[0] = opts.mlabel + if opts.tlabel is not None: + labels[1] = opts.tlabel # 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