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
20 changes: 10 additions & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ci:
submodules: false
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v6.0.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
Expand All @@ -21,45 +21,45 @@ repos:
- id: check-toml
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 24.4.2
rev: 26.5.1
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 7.0.0
rev: 7.3.0
hooks:
- id: flake8
- repo: https://github.com/pycqa/isort
rev: 5.13.2
rev: 9.0.0b2
hooks:
- id: isort
args: ["--profile", "black"]
- repo: https://github.com/kynan/nbstripout
rev: 0.7.1
rev: 0.9.1
hooks:
- id: nbstripout
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v6.0.0
hooks:
- id: no-commit-to-branch
name: Prevent Commit to Main Branch
args: ["--branch", "main"]
stages: [pre-commit]
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
rev: v2.4.3
hooks:
- id: codespell
additional_dependencies:
- tomli
# prettier - multi formatter for .json, .yml, and .md files
- repo: https://github.com/pre-commit/mirrors-prettier
rev: f12edd9c7be1c20cfa42420fd0e6df71e42b51ea # frozen: v4.0.0-alpha.8
rev: v4.0.0-alpha.8
hooks:
- id: prettier
additional_dependencies:
- "prettier@^3.2.4"
# docformatter - PEP 257 compliant docstring formatter
- repo: https://github.com/s-weigand/docformatter
rev: 5757c5190d95e5449f102ace83df92e7d3b06c6c
- repo: https://github.com/PyCQA/docformatter
rev: v1.7.8
hooks:
- id: docformatter
additional_dependencies: [tomli]
Expand Down
39 changes: 20 additions & 19 deletions docs/examples/core/debye-waller/debyemodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

import numpy

from diffpy.cmi.fit_tools import optimize_recipe, plot_results
from diffpy.cmi.fit_tools import optimize_recipe
from diffpy.srfit.fitbase import (
FitContribution,
FitRecipe,
Expand Down Expand Up @@ -85,7 +85,6 @@ def make_recipe():
optimize for the data/equation pair. This can be modified, but we
won't do that here.
"""

# The Profile
# Create a Profile to hold the experimental and calculated signal.
profile = Profile()
Expand All @@ -94,7 +93,7 @@ def make_recipe():
# data into the profile.
xydy = numpy.array(data.split(), dtype=float).reshape(-1, 3)
x, y, dy = xydy.T
profile.setObservedProfile(x, y, dy)
profile.set_observed_profile(x, y, dy)

# The FitContribution
# The FitContribution associates the profile with the Debye function.
Expand All @@ -103,17 +102,17 @@ def make_recipe():
# independent variable (the temperature) from the data to calculate the
# theoretical signal, so give it an informative name ('T') that we can use
# later.
contribution.setProfile(profile, xname="T")
contribution.set_profile(profile, xname="T")

# We now need to create the fitting equation. We tell the FitContribution
# to use the 'debye' function defined below. The 'registerFunction' method
# to use the 'debye' function defined below. The 'register_function' method
# will let us do this. Since we haven't told it otherwise,
# 'registerFunction' will extract the name of the function ('debye') and
# 'register_function' will extract the name of the function ('debye') and
# the names of the arguments ('T', 'm', 'thetaD'). These arguments will
# become Parameters of the FitContribution. Since we named the x-variable
# 'T' above, the 'T' in the 'debye' equation will refer to this x-variable
# whenever it is used.
contribution.registerFunction(debye)
contribution.register_function(debye)

# Now we can create the fitting equation. We want to extend the 'debye'
# equation by adding a vertical offset. We could wrap 'debye' in a new
Expand All @@ -127,22 +126,22 @@ def make_recipe():
# the debye equation to be positive, so we specify the input as abs(thetaD)
# in the equation below. Furthermore, we know 'm', the mass of lead, so we
# can specify that as well.
contribution.setEquation("debye(T, 207.2, abs(thetaD)) + offset")
contribution.set_equation("debye(T, 207.2, abs(thetaD)) + offset")

# The FitRecipe
# The FitRecipe lets us define what we want to fit. It is where we can
# create variables, constraints and restraints. If we had multiple profiles
# to fit simultaneously, the contribution from each could be added to the
# recipe.
recipe = FitRecipe()
recipe.addContribution(contribution)
recipe.add_contribution(contribution)

# Specify which Parameters we want to refine.

# Vary the offset
recipe.addVar(contribution.offset, 0)
recipe.add_variable(contribution.offset, 0)
# We also vary the Debye temperature.
recipe.addVar(contribution.thetaD, 100)
recipe.add_variable(contribution.thetaD, 100)

# We would like to 'suggest' that the offset should remain positive. This
# is somethine that we know about the system that might help the refinement
Expand All @@ -152,15 +151,14 @@ def make_recipe():
# breaking the restraint by the point-average chi^2 value so that the
# restraint is roughly as significant as any other data point throughout
# the fit.
recipe.restrain(recipe.offset, lb=0, scaled=True)
recipe.add_soft_bounds(recipe.offset, lower_bound=0, scaled=True)

# We're done setting up the recipe. We can now do other things with it.
return recipe


def main():
"""The workflow of creating, running and inspecting a fit."""

# Create the recipe
recipe = make_recipe()

Expand All @@ -171,14 +169,17 @@ def main():
res = FitResults(recipe)

# Print the results
res.printResults()
res.print_results()

# Plot the results
x = recipe.pb.profile.x
yobs = recipe.pb.profile.y
ycalc = recipe.pb.profile.ycalc

plot_results(x, yobs, ycalc)
recipe.plot_recipe(
show_diff=False,
data_label=r"Pb $U_{iso}$ Data",
fit_label="Calculated",
xlabel="T (K)",
ylabel=r"$U_{iso} (\AA^2)$",
legend_loc=(0.0, 0.8),
)

return

Expand Down
75 changes: 33 additions & 42 deletions docs/examples/core/debye-waller/debyemodelII.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ def make_recipeII():
constrain the Debye temperature in each FitContribution to be the
same.
"""

# We'll throw these away. We just want the FitContributions that are
# configured within the recipes.
m1 = make_recipe()
Expand All @@ -73,66 +72,58 @@ def make_recipeII():
# Now create a fresh FitRecipe to work with and add to it the two
# FitContributions.
recipe = FitRecipe()
recipe.addContribution(lowT)
recipe.addContribution(highT)
recipe.add_contribution(lowT)
recipe.add_contribution(highT)

# Change the fit ranges of the Profiles embedded within the
# FitContributions. We want to fit one of the contributions at low
# temperature, and one at high.
lowT.profile.setCalculationRange(0, 150)
highT.profile.setCalculationRange(400, 500)
lowT.profile.set_calculation_range(0, 150)
highT.profile.set_calculation_range(400, 500)

# Vary the offset from each FitContribution separately, while keeping the
# Debye temperatures the same. We give each offset variable a different
# name in the recipe so it retains its identity.
recipe.addVar(recipe.lowT.offset, name="lowToffset")
recipe.addVar(recipe.highT.offset, name="highToffset")
recipe.add_variable(recipe.lowT.offset, name="lowToffset")
recipe.add_variable(recipe.highT.offset, name="highToffset")
# We create a new Variable and use the recipe's "constrain" method to
# associate the Debye temperature parameters with that variable.
recipe.newVar("thetaD", 100)
recipe.constrain(recipe.lowT.thetaD, "thetaD")
recipe.constrain(recipe.highT.thetaD, "thetaD")
recipe.create_new_variable("thetaD", 100)
recipe.add_constraint(recipe.lowT.thetaD, "thetaD")
recipe.add_constraint(recipe.highT.thetaD, "thetaD")
return recipe


def plot_results(recipe):
"""Display the results contained within a refined FitRecipe."""

# The variable values are returned in the order in which the variables were
# added to the FitRecipe.
lowToffset, highToffset, thetaD = recipe.getValues()
lowToffset, highToffset, thetaD = recipe.get_values()
print(
r"lowT: $T_d$=%3.1f K, offset=%1.5f $\AA^2$"
% (abs(thetaD), lowToffset)
)
print(
r"highT: $T_d$=%3.1f K, offset=%1.5f $\AA^2$"
% (abs(thetaD), highToffset)
)

# We want to extend the fitting range to its full extent so we can get a
# nice full plot.
recipe.lowT.profile.setCalculationRange(xmin="obs", xmax="obs")
recipe.highT.profile.setCalculationRange(xmin="obs", xmax="obs")
T = recipe.lowT.profile.x
U = recipe.lowT.profile.y
# We can use a FitContribution's 'evaluateEquation' method to evaluate
# expressions involving the Parameters and other aspects of the
# FitContribution. Here we evaluate the fitting equation, which is always
# accessed using the name "eq". We access it this way (rather than through
# the Profile's ycalc attribute) because we changed the calculation range
# above, and we therefore need to recalculate the profile.
lowU = recipe.lowT.evaluateEquation("eq")
highU = recipe.highT.evaluateEquation("eq")

# Now we can plot this.
import pylab

pylab.plot(T, U, "o", label="Pb $U_{iso}$ Data")
lbl1 = r"$T_d$=%3.1f K, lowToff=%1.5f $\AA^2$" % (abs(thetaD), lowToffset)
lbl2 = r"$T_d$=%3.1f K, highToff=%1.5f $\AA^2$" % (
abs(thetaD),
highToffset,
# nice full plot. Since the calculated profile is only valid for the
# calculation range that was used during the fit, we need to trigger a
# recalculation over the widened range before plotting.
recipe.lowT.profile.set_calculation_range(xmin="obs", xmax="obs")
recipe.highT.profile.set_calculation_range(xmin="obs", xmax="obs")
recipe.residual()

recipe.plot_recipe(
show_diff=False,
data_label=r"Pb $U_{iso}$ Data",
fit_label="Calculated",
xlabel="T (K)",
ylabel=r"$U_{iso} (\AA^2)$",
legend_loc=(0.0, 0.8),
)
pylab.plot(T, lowU, label=lbl1)
pylab.plot(T, highU, label=lbl2)
pylab.xlabel("T (K)")
pylab.ylabel(r"$U_{iso} (\AA^2)$")
pylab.legend()

pylab.show()
return


Expand All @@ -148,7 +139,7 @@ def main():
res = FitResults(recipe)

# Print the results
res.printResults()
res.print_results()

# Plot the results
plot_results(recipe)
Expand Down
11 changes: 5 additions & 6 deletions docs/examples/core/gaussianfit/gaussiangenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

Extensions

- Remove the amplitude from GaussianGenerator and instead use the 'setEquation'
method of the FitContribution to account for it. Note that the
- Remove the amplitude from GaussianGenerator and instead use the
'set_equation' method of the FitContribution to account for it. Note that the
GaussianGenerator will be accessible by its name, "g".
"""

Expand Down Expand Up @@ -126,7 +126,6 @@ def make_recipe():
This will create a FitContribution that uses the GaussianGenerator,
associate this with a Profile, and use this to define a FitRecipe.
"""

# The Profile
# Create a Profile to hold the experimental and calculated signal.
profile = Profile()
Expand All @@ -147,13 +146,13 @@ def make_recipe():
# attribute of the FitContribution by its name ("g"). Note that this will
# set the fitting equation to "g", which calls the GaussianGenerator.
contribution = FitContribution("g1")
contribution.addProfileGenerator(generator)
contribution.setProfile(profile)
contribution.add_profile_generator(generator)
contribution.set_profile(profile)

# The FitRecipe
# Now we create the FitRecipe and add the FitContribution.
recipe = FitRecipe()
recipe.addContribution(contribution)
recipe.add_contribution(contribution)

# Specify which Parameters we want to vary in the fit. This will add
# Variables to the FitRecipe that directly modify the Parameters of the
Expand Down
Loading
Loading