Skip to content
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
2 changes: 1 addition & 1 deletion news/cf-non-physical-input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

**Changed:**

* Change the characteristic functions in ``diffpy.srfit.pdf.characteristicfunctions`` to emit a ``RuntimeWarning`` when a non-physical shape parameter makes them return zero, since a zero return flattens the fit residual and stalls a refinement without any other sign to the user. The warning is issued once per process for each distinct problem so a refinement loop does not repeat it.
* Change the current characteristic functions in ``diffpy.srfit.pdf.characteristicfunctions`` (``spherical_particle``, ``spheroidal_particle``, ``lognormal_spherical_particle``, ``sheet_particle`` and ``shell_particle``) to emit a ``RuntimeWarning`` when a non-physical shape parameter makes them return zero, since a zero return flattens the fit residual and stalls a refinement without any other sign to the user. The warning is issued once per process for each distinct problem so a refinement loop does not repeat it. The deprecated camel-case functions forward to these functions directly, so they emit the same warning and return the same result for non-physical input.
* Change ``lognormal_spherical_particle`` in ``diffpy.srfit.pdf.characteristicfunctions`` to return zero for a negative ``particle_diameter_sigma`` instead of silently returning ``spherical_particle``. A ``particle_diameter_sigma`` of zero is still the sphere limit.
* Change ``sheet_particle`` in ``diffpy.srfit.pdf.characteristicfunctions`` to return an array of zeros for a non-positive ``sheet_thickness`` when ``r`` is an array, instead of a scalar zero.

Expand Down
4 changes: 2 additions & 2 deletions src/diffpy/srfit/fitbase/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,13 @@ def bound_range(self, lower_bound=None, upper_bound=None):
return self

@deprecated(boundRange_dep_msg)
def boundRange(self, lower_bound=None, upper_bound=None):
def boundRange(self, lb=None, ub=None):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we lengthened these on purpose to make the code more readable. Please can we return these back to being explicit?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@sbillinge we have to have the old signature in the deprecated function or else it will error without giving a useful message if the user has lb= in their usage. I figured this out when running the example cmi scripts. The function replacing it has the new parameter names so the updated function is better

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see. that makes sense.

"""This function has been deprecated and will be removed in
version 4.0.0.

Please use diffpy.srfit.fitbase.Parameter.bound_range instead.
"""
self.bound_range(lower_bound, upper_bound)
self.bound_range(lb, ub)
return self

def bound_window(self, lower_radius=0, upper_radius=None):
Expand Down
41 changes: 19 additions & 22 deletions src/diffpy/srfit/fitbase/recipeorganizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -941,23 +941,28 @@ def register_function(self, function, name=None, argnames=None):

import inspect

# A decorator such as `deprecated` replaces the code object with
# that of its (*args, **kwargs) wrapper, so introspect the
# function it wraps while still registering the decorated one.
wrapped_function = inspect.unwrap(function)

fncode = None

# This will let us offset the argument list to eliminate 'self'
offset = 0

# check regular functions
if inspect.isfunction(function):
fncode = function.__code__
if inspect.isfunction(wrapped_function):
fncode = wrapped_function.__code__
# check class method
elif inspect.ismethod(function):
fncode = function.__func__.__code__
offset = 1
# check functor
elif hasattr(function, "__call__") and hasattr(
function.__call__, "__func__"
elif hasattr(wrapped_function, "__call__") and hasattr(
wrapped_function.__call__, "__func__"
):
fncode = function.__call__.__func__.__code__
fncode = wrapped_function.__call__.__func__.__code__
offset = 1
else:
m = "Cannot extract name or argnames"
Expand Down Expand Up @@ -1182,15 +1187,15 @@ def add_constraint(self, parameter, constraint_eq, params={}):
return

@deprecated(constrain_deprecation_msg)
def constrain(self, parameter, constraint_eq, params={}):
def constrain(self, par, con, ns={}):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same here, please keep explicit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See my response above

"""This function has been deprecated and will be removed in
version 4.0.0.

Please use
diffpy.srfit.fitbase.recipeorganizer.RecipeOrganizer.add_constraint
instead.
"""
self.add_constraint(parameter, constraint_eq, params=params)
self.add_constraint(par, con, params=ns)
return

def is_constrained(self, parameter):
Expand All @@ -1214,15 +1219,15 @@ def is_constrained(self, parameter):
return parameter in self._constraints

@deprecated(isConstrained_deprecation_msg)
def isConstrained(self, parameter):
def isConstrained(self, par):
"""This function has been deprecated and will be removed in
version 4.0.0.

Please use
diffpy.srfit.fitbase.recipeorganizer.RecipeOrganizer.is_constrained
instead.
"""
return self.is_constrained(parameter)
return self.is_constrained(par)

def remove_constraint(self, *pars):
"""Unconstrain a Parameter.
Expand Down Expand Up @@ -1424,15 +1429,7 @@ def add_soft_bounds(
return param_or_eq

@deprecated(restrain_deprecation_msg)
def restrain(
self,
param_or_eq,
lower_bound=-inf,
upper_bound=inf,
sig=1,
scaled=False,
params={},
):
def restrain(self, res, lb=-inf, ub=inf, sig=1, scaled=False, ns={}):
"""This function has been deprecated and will be removed in
version 4.0.0.

Expand All @@ -1441,12 +1438,12 @@ def restrain(
instead.
"""
return self.add_soft_bounds(
param_or_eq,
lower_bound=lower_bound,
upper_bound=upper_bound,
res,
lower_bound=lb,
upper_bound=ub,
sig=sig,
scaled=scaled,
params=params,
params=ns,
)

def register_soft_bounds(self, res):
Expand Down
189 changes: 99 additions & 90 deletions src/diffpy/srfit/pdf/characteristicfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,53 +55,69 @@
removal_version = "4.0.0"
cf_base = "diffpy.srfit.pdf.characteristicfunctions"

sphericalCF_dep_msg = build_deprecation_message(
cf_base,

def _build_dep_msg(old_name, new_name, signature_note=None):
"""Build the deprecation message for a camel case function.

The note describing how the signature changed, when there is one, is
appended to the standard message from `build_deprecation_message`.
"""
message = build_deprecation_message(
cf_base, old_name, new_name, removal_version
)
if signature_note is None:
return message
return f"{message} {signature_note}"


sphericalCF_dep_msg = _build_dep_msg(
"sphericalCF",
"spherical_particle",
removal_version,
"Additionally, the signature has changed. Please pass the parameter "
"'psize' as 'particle_diameter'.",
)

spheroidalCF_dep_msg = build_deprecation_message(
cf_base,
spheroidalCF_dep_msg = _build_dep_msg(
"spheroidalCF",
"spheroidal_particle",
removal_version,
"Additionally, the signature has changed. Please pass the parameters "

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yes, let's not lose our previous work making hte code more readable. keep it self documenting by using full names.

"'erad' and 'prad' as 'equatorial_radius' and 'polar_radius', "
"respectively.",
)

spheroidalCF2_dep_msg = build_deprecation_message(
cf_base,
spheroidalCF2_dep_msg = _build_dep_msg(
"spheroidalCF2",
"spheroidal_particle",
removal_version,
"Additionally, the parameterization has changed. 'spheroidalCF2' took "
"the equatorial diameter 'psize' and the axis ratio 'axrat', while "
"'spheroidal_particle' takes radii. Please pass "
"equatorial_radius = psize / 2 and polar_radius = axrat * psize / 2.",
)

lognormalSphericalCF_dep_msg = build_deprecation_message(
cf_base,
lognormalSphericalCF_dep_msg = _build_dep_msg(
"lognormalSphericalCF",
"lognormal_spherical_particle",
removal_version,
"Additionally, the signature has changed. Please pass the parameters "
"'psize' and 'psig' as 'particle_diameter' and "
"'particle_diameter_sigma', respectively.",
)

sheetCF_dep_msg = build_deprecation_message(
cf_base,
sheetCF_dep_msg = _build_dep_msg(
"sheetCF",
"sheet_particle",
removal_version,
"Additionally, the signature has changed. Please pass the parameter "
"'sthick' as 'sheet_thickness'.",
)

shellCF_dep_msg = build_deprecation_message(
cf_base,
"shellCF",
"shell_particle",
removal_version,
)
shellCF_dep_msg = _build_dep_msg("shellCF", "shell_particle")

shellCF2_dep_msg = build_deprecation_message(
cf_base,
shellCF2_dep_msg = _build_dep_msg(
"shellCF2",
"shell_particle",
removal_version,
"Additionally, the parameterization has changed. 'shellCF2' took the "
"central radius 'a' and the shell thickness 'delta', while "
"'shell_particle' takes the inner radius. Please pass "
"radius = a - delta / 2 and thickness = delta.",
)


Expand Down Expand Up @@ -175,18 +191,6 @@ def spherical_particle(r, particle_diameter):
return characteristic_function


@deprecated(sphericalCF_dep_msg)
def sphericalCF(r, psize):
"""This function is deprecated and will be removed in version
4.0.0.

Please use
diffpy.srfit.pdf.characteristicfunctions.spherical_particle
instead.
"""
return spherical_particle(r, psize)


def spheroidal_particle(r, equatorial_radius, polar_radius):
"""Compute the spheroidal nanoparticle characteristic function.

Expand Down Expand Up @@ -321,32 +325,6 @@ def spheroidal_particle(r, equatorial_radius, polar_radius):
return f


@deprecated(spheroidalCF_dep_msg)
def spheroidalCF(r, erad, prad):
"""This function is deprecated and will be removed in version
4.0.0.

Please use
diffpy.srfit.pdf.characteristicfunctions.spheroidal_particle
instead.
"""
return spheroidal_particle(r, erad, prad)


@deprecated(spheroidalCF2_dep_msg)
def spheroidalCF2(r, psize, axrat):
"""This function is deprecated and will be removed in version
4.0.0.

Please use
diffpy.srfit.pdf.characteristicfunctions.spheroidal_particle
instead.
"""
equatorial_radius = 0.5 * psize
polar_radius = axrat * equatorial_radius
return spheroidal_particle(r, equatorial_radius, polar_radius)


def lognormal_spherical_particle(
r, particle_diameter, particle_diameter_sigma
):
Expand Down Expand Up @@ -443,18 +421,6 @@ def lognormal_spherical_particle(
)


@deprecated(lognormalSphericalCF_dep_msg)
def lognormalSphericalCF(r, psize, psig):
"""This function is deprecated and will be removed in version
4.0.0.

Please use
diffpy.srfit.pdf.characteristicfunctions.lognormal_spherical_particle
instead.
"""
return lognormal_spherical_particle(r, psize, psig)


def sheet_particle(r, sheet_thickness):
"""Compute the nanosheet characteristic function.

Expand Down Expand Up @@ -506,17 +472,6 @@ def sheet_particle(r, sheet_thickness):
return characteristic_function


@deprecated(sheetCF_dep_msg)
def sheetCF(r, sthick):
"""This function is deprecated and will be removed in version
4.0.0.

Please use diffpy.srfit.pdf.characteristicfunctions.sheet_particle
instead.
"""
return sheet_particle(r, sthick)


def shell_particle(r, radius, thickness):
"""Compute the spherical shell characteristic function.

Expand Down Expand Up @@ -582,9 +537,65 @@ def shell_particle(r, radius, thickness):
return f


@deprecated(sphericalCF_dep_msg)
def sphericalCF(r, psize):
"""This function has been deprecated and will be removed in version
4.0.0.

Please use diffpy.srfit.pdf.characteristicfunctions.spherical_particle
instead.
"""
return spherical_particle(r, psize)


@deprecated(spheroidalCF_dep_msg)
def spheroidalCF(r, erad, prad):
"""This function has been deprecated and will be removed in version
4.0.0.

Please use diffpy.srfit.pdf.characteristicfunctions.spheroidal_particle
instead.
"""
return spheroidal_particle(r, erad, prad)


@deprecated(spheroidalCF2_dep_msg)
def spheroidalCF2(r, psize, axrat):
"""This function has been deprecated and will be removed in version
4.0.0.

Please use diffpy.srfit.pdf.characteristicfunctions.spheroidal_particle
instead.
"""
return spheroidal_particle(r, psize / 2, axrat * psize / 2)


@deprecated(lognormalSphericalCF_dep_msg)
def lognormalSphericalCF(r, psize, psig):
"""This function has been deprecated and will be removed in version
4.0.0.

Please use
diffpy.srfit.pdf.characteristicfunctions.lognormal_spherical_particle
instead.
"""
return lognormal_spherical_particle(r, psize, psig)


@deprecated(sheetCF_dep_msg)
def sheetCF(r, sthick):
"""This function has been deprecated and will be removed in version
4.0.0.

Please use diffpy.srfit.pdf.characteristicfunctions.sheet_particle
instead.
"""
return sheet_particle(r, sthick)


@deprecated(shellCF_dep_msg)
def shellCF(r, radius, thickness):
"""This function is deprecated and will be removed in version
"""This function has been deprecated and will be removed in version
4.0.0.

Please use diffpy.srfit.pdf.characteristicfunctions.shell_particle
Expand All @@ -595,15 +606,13 @@ def shellCF(r, radius, thickness):

@deprecated(shellCF2_dep_msg)
def shellCF2(r, a, delta):
"""This function is deprecated and will be removed in version
"""This function has been deprecated and will be removed in version
4.0.0.

Please use diffpy.srfit.pdf.characteristicfunctions.shell_particle
instead.
"""
radius = a - 0.5 * delta
thickness = delta
return shell_particle(r, radius, thickness)
return shell_particle(r, a - delta / 2, delta)


class SASCF(Calculator):
Expand Down
Loading
Loading