Skip to content

Commit e3ec644

Browse files
authored
Merge pull request #673 from SasView/fix-magnetic-angle-limits
Fix limits on angles and angular dispersity
2 parents 592f978 + 350fda1 commit e3ec644

24 files changed

Lines changed: 72 additions & 41 deletions

doc/guide/orientation/orientation.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ to understand the 2d patterns fully. A number of different shapes of
103103
distribution are available, as described for size dispersity, see
104104
:ref:`polydispersityhelp`.
105105

106+
The parameter limits for the orientation parameters are generous, with
107+
$\theta \in [-180, 180]$ and $\phi, \Psi \in [-360, 360]$. Although
108+
there will be multiple equivalent solutions in the space, these limits
109+
allow you to set bounds around the solution even when it is near a pole.
110+
For example, if the solution is within 4 degrees of $\phi = 179 \pm 4$,
111+
having strict bounds would force you to search both in $[175, 180]$ and
112+
in $[-180, -177]$ instead of searching within $[175, 183]$.
113+
106114
Given that the angular dispersion distribution is defined in cartesian space,
107115
over a cube defined by
108116

@@ -130,9 +138,9 @@ will be the case for $\theta=90$ and $\Psi=90$) the scattering pattern
130138
should be circularly symmetric, but it will go to zero at $q_x = 0$ due to the
131139
$\sin(\Delta\theta)$ correction. This problem does not appear for a shape
132140
that is tumbling freely around the $a$ axis, with $\Delta\phi$ uniform in
133-
$[-180, 180]$, so swap the $a$ and $b$ axes so $\Delta\theta < \Delta\phi$
134-
and adjust $\Psi$ by 90. This works with the current sasmodels shapes due to
135-
symmetry.
141+
$[-180, 180]$. For shapes such as parallelepiped or triaxial ellipsoid where
142+
the choice of a, b and c is arbitrary, you can minimize the problem by
143+
relabelling the axes and adjusting the orientation.
136144

137145
Alternative projections were considered.
138146
The `sinusoidal projection <https://en.wikipedia.org/wiki/Sinusoidal_projection>`_

sasmodels/bumps_model.py

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@
1616

1717
import numpy as np # type: ignore
1818

19+
try:
20+
# Optional import. This allows the doc builder and tests to run even
21+
# when bumps is not on the path.
22+
from bumps.parameter import Parameter as BumpsParameter # type: ignore
23+
from bumps.parameter import Reference
24+
except ImportError:
25+
class BumpsParameter:
26+
"""See parameter.Parameter in the bumps documentation."""
27+
class Reference:
28+
"""See parameter.Reference in the bumps documentation."""
29+
1930
from .data import plot_theory
2031
from .direct_model import DataMixin
2132

@@ -61,22 +72,34 @@ def create_parameters(model_info, **kwargs):
6172
parameters for each model parameter, and a dictionary of
6273
*{name: str}* containing the polydispersity distribution types.
6374
"""
64-
pars = {} # type: dict[str, BumpsParameter]
65-
pd_types = {} # type: dict[str, str]
75+
def addpar(name: str, default: float, limits: tuple[float]) -> None:
76+
value = kwargs.pop(name, default)
77+
pars[name] = BumpsParameter.default(value, name=name, limits=limits)
78+
79+
pars: dict[str, BumpsParameter] = {}
80+
pd_types: dict[str, str] = {}
6681
for p in model_info.parameters.call_parameters:
67-
value = kwargs.pop(p.name, p.default)
68-
pars[p.name] = BumpsParameter.default(value, name=p.name, limits=p.limits)
82+
# To check the limits on parameters in sasmodels, the following
83+
# regex captures most (all?) parameter definition lines:
84+
# grep "^\(parameters *= *\[\)\? *\[['\"]" sasmodels/models/*.py
85+
# Skip those which have inf, 360 or 180 in the definition:
86+
# ... | grep -v inf | grep -v 360 | grep -v 180
87+
# Looking at the remaining values they all represent hard limits on
88+
# the model parameter that should not be exceeded by the fitter.
89+
90+
# Bumps respects hard limits, so make sure they are big enough. We probably don't
91+
# need to do this since the values in the models should be set right.
92+
# angular = (p.type == "orientation") or (p.type == "magnetic" and p.units == "degrees")
93+
# limits = p.limits if not angular else (-180, 180) if "theta" in p.name else (-360, 360)
94+
addpar(p.name, p.default, p.limits)
6995
if p.polydisperse:
70-
pd_limits = (-360.0, 360.0) if p.type == "orientation" else (0., 1.)
71-
for part, default, limits in [
72-
('_pd', 0., pd_limits),
73-
('_pd_n', 35., (0, 1000)),
74-
('_pd_nsigma', 3., (0, 10)),
75-
]:
76-
name = p.name + part
77-
value = kwargs.pop(name, default)
78-
pars[name] = BumpsParameter.default(value, name=name, limits=limits)
96+
addpar(f"{p.name}_pd", 0., limits=(0.0, np.inf))
97+
addpar(f"{p.name}_pd_n", 35, limits=(0, 1000))
98+
addpar(f"{p.name}_pd_nsigma", 3., limits=(0.0, 10.0))
7999
name = p.name + '_pd_type'
100+
# If angular we should be defaulting to a cyclic gaussian, but this is not
101+
# yet in sasmodels. There is an implementation in the example/weights directory.
102+
# When we do add it be sure to update orientation.rst describing how to use it.
80103
pd_types[name] = str(kwargs.pop(name, 'gaussian'))
81104

82105
if kwargs: # args not corresponding to parameters

sasmodels/modelinfo.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -641,19 +641,19 @@ def _get_call_parameters(self):
641641
'magnetic', 'fraction of spin up incident'),
642642
Parameter('up_frac_f', '', 0., [0., 1.],
643643
'magnetic', 'fraction of spin up final'),
644-
Parameter('up_theta', 'degrees', 90., [0., 360.],
644+
Parameter('up_theta', 'degrees', 90., [-180., 180.],
645645
'magnetic', 'polarization axis rotation angle'),
646-
Parameter('up_phi', 'degrees', 0., [0., 180.],
646+
Parameter('up_phi', 'degrees', 0., [-360., 360.],
647647
'magnetic', 'polarization axis inclination angle'),
648648
])
649649
slds = [p for p in full_list if p.type == 'sld']
650650
for p in slds:
651651
full_list.extend([
652652
Parameter(p.id+'_M0', '1e-6/Ang^2', 0., [-np.inf, np.inf],
653653
'magnetic', 'magnetic amplitude for '+p.description),
654-
Parameter(p.id+'_mtheta', 'degrees', 0., [-90., 90.],
654+
Parameter(p.id+'_mtheta', 'degrees', 0., [-180., 180.],
655655
'magnetic', 'magnetic latitude for '+p.description),
656-
Parameter(p.id+'_mphi', 'degrees', 0., [-180., 180.],
656+
Parameter(p.id+'_mphi', 'degrees', 0., [-360., 360.],
657657
'magnetic', 'magnetic longitude for '+p.description),
658658
])
659659
#print("call parameters", full_list)

sasmodels/models/barbell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
["radius_bell", "Ang", 40, [0, inf], "volume", "Spherical bell radius"],
113113
["radius", "Ang", 20, [0, inf], "volume", "Cylindrical bar radius"],
114114
["length", "Ang", 400, [0, inf], "volume", "Cylinder bar length"],
115-
["theta", "degrees", 60, [-360, 360], "orientation", "Barbell axis to beam angle"],
115+
["theta", "degrees", 60, [-180, 180], "orientation", "Barbell axis to beam angle"],
116116
["phi", "degrees", 60, [-360, 360], "orientation", "Rotation about beam"],
117117
]
118118
# pylint: enable=bad-whitespace, line-too-long

sasmodels/models/bcc_paracrystal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@
188188
["radius", "Ang", 40, [0, inf], "volume", "Particle radius"],
189189
["sld", "1e-6/Ang^2", 4, [-inf, inf], "sld", "Particle scattering length density"],
190190
["sld_solvent", "1e-6/Ang^2", 1, [-inf, inf], "sld", "Solvent scattering length density"],
191-
["theta", "degrees", 60, [-360, 360], "orientation", "c axis to beam angle"],
191+
["theta", "degrees", 60, [-180, 180], "orientation", "c axis to beam angle"],
192192
["phi", "degrees", 60, [-360, 360], "orientation", "rotation about beam"],
193193
["psi", "degrees", 60, [-360, 360], "orientation", "rotation about c axis"]
194194
]

sasmodels/models/capped_cylinder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
# both models, one would be a pill.
133133
["radius_cap", "Ang", 20, [0, inf], "volume", "Cap radius"],
134134
["length", "Ang", 400, [0, inf], "volume", "Cylinder length"],
135-
["theta", "degrees", 60, [-360, 360], "orientation", "cylinder axis to beam angle"],
135+
["theta", "degrees", 60, [-180, 180], "orientation", "cylinder axis to beam angle"],
136136
["phi", "degrees", 60, [-360, 360], "orientation", "rotation about beam"],
137137
]
138138
# pylint: enable=bad-whitespace, line-too-long

sasmodels/models/core_shell_bicelle.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
["sld_face", "1e-6/Ang^2", 4, [-inf, inf], "sld", "Cylinder face scattering length density"],
147147
["sld_rim", "1e-6/Ang^2", 4, [-inf, inf], "sld", "Cylinder rim scattering length density"],
148148
["sld_solvent", "1e-6/Ang^2", 1, [-inf, inf], "sld", "Solvent scattering length density"],
149-
["theta", "degrees", 90, [-360, 360], "orientation", "cylinder axis to beam angle"],
149+
["theta", "degrees", 90, [-180, 180], "orientation", "cylinder axis to beam angle"],
150150
["phi", "degrees", 0, [-360, 360], "orientation", "rotation about beam"]
151151
]
152152

sasmodels/models/core_shell_bicelle_elliptical.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
["sld_face", "1e-6/Ang^2", 7, [-inf, inf], "sld", "Cylinder face scattering length density"],
138138
["sld_rim", "1e-6/Ang^2", 1, [-inf, inf], "sld", "Cylinder rim scattering length density"],
139139
["sld_solvent", "1e-6/Ang^2", 6, [-inf, inf], "sld", "Solvent scattering length density"],
140-
["theta", "degrees", 90.0, [-360, 360], "orientation", "Cylinder axis to beam angle"],
140+
["theta", "degrees", 90.0, [-180, 180], "orientation", "Cylinder axis to beam angle"],
141141
["phi", "degrees", 0, [-360, 360], "orientation", "Rotation about beam"],
142142
["psi", "degrees", 0, [-360, 360], "orientation", "Rotation about cylinder axis"]
143143
]

sasmodels/models/core_shell_bicelle_elliptical_belt_rough.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
["sld_rim", "1e-6/Ang^2", 1, [-inf, inf], "sld", "Cylinder rim scattering length density"],
151151
["sld_solvent", "1e-6/Ang^2", 6, [-inf, inf], "sld", "Solvent scattering length density"],
152152
["sigma", "Ang", 0, [0, inf], "", "Interfacial roughness"],
153-
["theta", "degrees", 90.0, [-360, 360], "orientation", "Cylinder axis to beam angle"],
153+
["theta", "degrees", 90.0, [-180, 180], "orientation", "Cylinder axis to beam angle"],
154154
["phi", "degrees", 0, [-360, 360], "orientation", "Rotation about beam"],
155155
["psi", "degrees", 0, [-360, 360], "orientation", "Rotation about cylinder axis"],
156156
]

sasmodels/models/core_shell_cylinder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
"Cylinder shell thickness"],
128128
["length", "Ang", 400, [0, inf], "volume",
129129
"Cylinder length"],
130-
["theta", "degrees", 60, [-360, 360], "orientation",
130+
["theta", "degrees", 60, [-180, 180], "orientation",
131131
"cylinder axis to beam angle"],
132132
["phi", "degrees", 60, [-360, 360], "orientation",
133133
"rotation about beam"],

0 commit comments

Comments
 (0)