-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathellipsoidsas.py
More file actions
130 lines (102 loc) · 4.06 KB
/
ellipsoidsas.py
File metadata and controls
130 lines (102 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python
########################################################################
#
# diffpy.srfit by DANSE Diffraction group
# Simon J. L. Billinge
# (c) 2010 The Trustees of Columbia University
# in the City of New York. All rights reserved.
#
# File coded by: Chris Farrow
#
# See AUTHORS.txt for a list of people who contributed.
# See LICENSE_DANSE.txt for license information.
#
########################################################################
"""Example of a refinement of SAS I(Q) data to an ellipsoidal model."""
from gaussianrecipe import scipyOptimize
from diffpy.srfit.fitbase import (
FitContribution,
FitRecipe,
FitResults,
Profile,
)
from diffpy.srfit.sas import SASGenerator, SASParser
######
# Example Code
def makeRecipe(datname):
"""Create a fitting recipe for ellipsoidal SAS data."""
# The Profile
# This will be used to store the observed and calculated I(Q) data.
profile = Profile()
# Load data and add it to the Profile. We use a SASParser to load the data
# properly and pass the metadata along.
parser = SASParser()
parser.parseFile(datname)
profile.loadParsedData(parser)
# The ProfileGenerator
# The SASGenerator is for configuring and calculating a SAS profile. We use
# a sas model to configure and serve as the calculation engine of the
# generator. This allows us to use the full sas model creation
# capabilities, and tie this into SrFit when we want to fit a model to
# data. The documentation for the various sas models can be found at
# http://www.sasview.org.
from sas.models.EllipsoidModel import EllipsoidModel
model = EllipsoidModel()
generator = SASGenerator("generator", model)
# The FitContribution
# Here we associate the Profile and ProfileGenerator, as has been done
# before.
contribution = FitContribution("ellipsoid")
contribution.add_profile_generator(generator)
contribution.set_profile(profile, xname="q")
# We want to fit the log of the signal to the log of the data so that the
# higher-Q information remains significant. There are no I(Q) uncertainty
# values with the data, so we do not need to worry about the effect this
# will have on the estimated parameter uncertainties.
contribution.set_residual_equation("log(eq) - log(y)")
# Make the FitRecipe and add the FitContribution.
recipe = FitRecipe()
recipe.addContribution(contribution)
# Configure the fit variables
# The SASGenerator uses the parameters from the params and dispersion
# attributes of the model. These vary from model to model, but are adopted
# as SrFit Parameters within the generator. Whereas the dispersion
# parameters are accessible as, e.g. "radius.width", within the
# SASGenerator these are named like "radius_width".
#
# We want to fit the scale factor, radii and background factors.
recipe.addVar(generator.scale, 1)
recipe.addVar(generator.radius_a, 50)
recipe.addVar(generator.radius_b, 500)
recipe.addVar(generator.background, 0)
# Give the recipe away so it can be used!
return recipe
def plotResults(recipe):
"""Plot the results contained within a refined FitRecipe."""
# All this should be pretty familiar by now.
r = recipe.ellipsoid.profile.x
y = recipe.ellipsoid.profile.y
ycalc = recipe.ellipsoid.profile.ycalc
diff = y - ycalc + min(y)
import pylab
pylab.loglog(r, y, "bo", label="I(Q) Data")
pylab.loglog(r, ycalc, "r-", label="I(Q) Fit")
pylab.loglog(r, diff, "g-", label="I(Q) diff")
pylab.xlabel(r"$Q (\AA^{-1})$")
pylab.ylabel("$I (arb. units)$")
pylab.legend(loc=1)
pylab.show()
return
if __name__ == "__main__":
# Make the data and the recipe
data = "data/sas_ellipsoid_testdata.txt"
# Make the recipe
recipe = makeRecipe(data)
# Optimize
scipyOptimize(recipe)
# Generate and print the FitResults
res = FitResults(recipe)
res.printResults()
# Plot!
plotResults(recipe)
# End of file