Skip to content

Change objective and reference naming #74

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 4 commits into from
Jun 18, 2023
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
4 changes: 2 additions & 2 deletions TUTORIAL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
116 changes: 58 additions & 58 deletions diffpy/pdfmorph/morphs/morph.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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',
)

Expand All @@ -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.
Expand All @@ -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.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)
Expand All @@ -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.

Expand All @@ -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)
Expand Down
69 changes: 34 additions & 35 deletions diffpy/pdfmorph/morphs/morphchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
28 changes: 14 additions & 14 deletions diffpy/pdfmorph/morphs/morphishape.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -33,27 +33,27 @@ 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


# End of class MorphISphere


class MorphISpheroid(Morph):
'''Apply inverse spherical characteristic function to the objective
'''Apply inverse spherical characteristic function to the morph

Configuration variables:

Expand All @@ -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


Expand Down
Loading