Skip to content

Add shifting morph #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions news/morphshift.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* Shifting morph for vertical and horizontal shifts.

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
13 changes: 11 additions & 2 deletions src/diffpy/pdfmorph/morphs/morphshift.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,19 @@ class MorphShift(Morph):

def morph(self, x_morph, y_morph, x_target, y_target):
"""Apply the shifts."""
try:
hshift = self.hshift
except AttributeError:
hshift = 0
try:
vshift = self.vshift
except AttributeError:
vshift = 0

Comment on lines +50 to +58
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code ensures that the vertical/horizontal shifts can be done independent of each other. We can also create two classes: MorphHShift and MorphVShift, but I feel that is overkill.

Morph.morph(self, x_morph, y_morph, x_target, y_target)
r = self.x_morph_in - self.hshift
r = self.x_morph_in - hshift
self.y_morph_out = numpy.interp(r, self.x_morph_in, self.y_morph_in)
self.y_morph_out += self.vshift
self.y_morph_out += vshift
return self.xyallout


Expand Down
47 changes: 40 additions & 7 deletions src/diffpy/pdfmorph/pdfmorphapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,26 +121,43 @@ def custom_error(self, msg):
help="""Exclude a manipulation from refinement by name. This can
appear multiple times.""",
)
group.add_option("--scale", type="float", metavar="SCALE", help="Apply scale factor SCALE.")
group.add_option(
"--smear",
"--scale",
type="float",
metavar="SMEAR",
help="Smear peaks with a Gaussian of width SMEAR.",
metavar="SCALE",
help="Apply scale factor SCALE.",
)
group.add_option(
"--stretch",
type="float",
metavar="STRETCH",
help="Stretch PDF by a fraction STRETCH.",
)
group.add_option(
"--smear",
type="float",
metavar="SMEAR",
help="Smear peaks with a Gaussian of width SMEAR.",
)
group.add_option(
"--slope",
type="float",
dest="baselineslope",
help="""Slope of the baseline. This is used when applying the smear
factor. It will be estimated if not provided.""",
)
group.add_option(
"--hshift",
type="float",
metavar="HSHIFT",
help="Shift the PDF horizontally by HSHIFT to the right.",
)
group.add_option(
"--vshift",
type="float",
metavar="VSHIFT",
help="Shift the PDF vertically by VSHIFT upward.",
)
group.add_option(
"--qdamp",
type="float",
Expand Down Expand Up @@ -318,6 +335,8 @@ def single_morph(parser, opts, pargs, stdout_flag=True):
scale_in = "None"
stretch_in = "None"
smear_in = "None"
hshift_in = "None"
vshift_in = "None"
config = {}
config["rmin"] = opts.rmin
config["rmax"] = opts.rmax
Expand All @@ -336,22 +355,33 @@ def single_morph(parser, opts, pargs, stdout_flag=True):
if opts.scale is not None:
scale_in = opts.scale
chain.append(morphs.MorphScale())
config["scale"] = opts.scale
config["scale"] = scale_in
refpars.append("scale")
# Stretch
if opts.stretch is not None:
stretch_in = opts.stretch
chain.append(morphs.MorphStretch())
config["stretch"] = opts.stretch
config["stretch"] = stretch_in
refpars.append("stretch")
# Shift
if opts.hshift is not None or opts.vshift is not None:
chain.append(morphs.MorphShift())
if opts.hshift is not None:
hshift_in = opts.hshift
config["hshift"] = hshift_in
refpars.append("hshift")
if opts.vshift is not None:
vshift_in = opts.vshift
config["vshift"] = vshift_in
refpars.append("vshift")
# Smear
if opts.smear is not None:
smear_in = opts.smear
chain.append(helpers.TransformXtalPDFtoRDF())
chain.append(morphs.MorphSmear())
chain.append(helpers.TransformXtalRDFtoPDF())
refpars.append("smear")
config["smear"] = opts.smear
config["smear"] = smear_in
# Set baselineslope if not given
config["baselineslope"] = opts.baselineslope
if opts.baselineslope is None:
Expand Down Expand Up @@ -432,6 +462,7 @@ def single_morph(parser, opts, pargs, stdout_flag=True):

# Input morph parameters
morph_inputs = {"scale": scale_in, "stretch": stretch_in, "smear": smear_in}
morph_inputs.update({"hshift": hshift_in, "vshift": vshift_in})

# Output morph parameters
morph_results = dict(config.items())
Expand Down Expand Up @@ -580,6 +611,7 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True):
target_file_names.append(key)

morph_inputs = {"scale": opts.scale, "stretch": opts.stretch, "smear": opts.smear}
morph_inputs.update({"hshift": opts.hshift, "vshift": opts.vshift})

try:
# Print summary of morphs to terminal and to file (if requested)
Expand Down Expand Up @@ -724,6 +756,7 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True):
morph_file_names.append(key)

morph_inputs = {"scale": opts.scale, "stretch": opts.stretch, "smear": opts.smear}
morph_inputs.update({"hshift": opts.hshift, "vshift": opts.vshift})

try:
# Print summary of morphs to terminal and to file (if requested)
Expand Down
52 changes: 52 additions & 0 deletions tests/test_morphshift.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python


import os

import numpy
import pytest

from diffpy.pdfmorph.morphs.morphshift import MorphShift

# useful variables
thisfile = locals().get("__file__", "file.py")
tests_dir = os.path.dirname(os.path.abspath(thisfile))
# testdata_dir = os.path.join(tests_dir, 'testdata')


class TestMorphShift:
@pytest.fixture
def setup(self):
self.hshift = 2.0
self.vshift = 3.0

# Original dataset goes from 0.1 to 5.0
self.x_morph = numpy.arange(0.01, 5 + self.hshift, 0.01)
self.y_morph = numpy.arange(0.01, 5 + self.hshift, 0.01)

# New dataset is moved to the right by 2.0 and upward by 3.0
self.x_target = numpy.arange(0.01 + self.hshift, 5 + self.hshift, 0.01)
self.y_target = numpy.arange(0.01 + self.vshift, 5 + self.vshift, 0.01)
return

def test_morph(self, setup):
"""check MorphScale.morph()"""
config = {"hshift": self.hshift, "vshift": self.vshift}
morph = MorphShift(config)

x_morph, y_morph, x_target, y_target = morph(self.x_morph, self.y_morph, self.x_target, self.y_target)

# Only care about the shifted data past the shift
# Everything to left of shift is outside our input data domain
assert numpy.allclose(y_morph[x_morph > self.hshift], y_target)
assert numpy.allclose(self.x_target, x_target)
assert numpy.allclose(self.y_target, y_target)
return


# End of class TestMorphScale

if __name__ == "__main__":
TestMorphShift()

Check warning on line 50 in tests/test_morphshift.py

View check run for this annotation

Codecov / codecov/patch

tests/test_morphshift.py#L50

Added line #L50 was not covered by tests

# End of file
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/succinct/Morph_Reference_Table.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Labels: [Target] [Temperature] [Pearson] [Rw]
f_180K.gr 180.0 0.999810 0.020141
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/verbose/Morph_Reference_Table.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Target: f_180K.gr
# Optimized morphing parameters:
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/verbose/Morphs/mwt_a.cgr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Optimized morphing parameters:
# rmin = 0.000000
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/verbose/Morphs/mwt_b.cgr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Optimized morphing parameters:
# rmin = 0.000000
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/verbose/Morphs/mwt_c.cgr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Optimized morphing parameters:
# rmin = 0.000000
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/verbose/Morphs/mwt_d.cgr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Optimized morphing parameters:
# rmin = 0.000000
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/verbose/Morphs/mwt_e.cgr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Optimized morphing parameters:
# rmin = 0.000000
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/verbose/Morphs/mwt_f.cgr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Optimized morphing parameters:
# rmin = 0.000000
Expand Down
2 changes: 2 additions & 0 deletions tests/testdata/testsaving/verbose/single_verbose_morph.cgr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# scale = None
# stretch = None
# smear = None
# hshift = None
# vshift = None

# Optimized morphing parameters:
# rmin = 0.000000
Expand Down
Loading