Skip to content

Commit 6d7e1d9

Browse files
author
Paul Kienzle
committed
don't include magnetism parameters in pure python models
1 parent 116e43a commit 6d7e1d9

2 files changed

Lines changed: 43 additions & 29 deletions

File tree

sasmodels/compare.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,10 +539,6 @@ def constrain_pars(model_info, pars):
539539
if '*' in name:
540540
name = name.split('*')[0]
541541

542-
# Suppress magnetism for python models (not yet implemented)
543-
if not model_info.compiled:
544-
pars.update(suppress_magnetism(pars))
545-
546542
if name == 'barbell':
547543
if pars['radius_bell'] < pars['radius']:
548544
_swap_pars(pars, 'radius_bell', 'radius')

sasmodels/modelinfo.py

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@
5959
and COMMON_PARAMETERS[1][0] == "background"), "don't change common parameters"
6060

6161

62-
def make_parameter_table(pars):
63-
# type: (list[ParameterDef]) -> ParameterTable
62+
def make_parameter_table(pars, allow_magnetic=True):
63+
# type: (list[ParameterDef], bool) -> ParameterTable
6464
"""
6565
Construct a parameter table from a list of parameter definitions.
6666
@@ -73,7 +73,7 @@ def make_parameter_table(pars):
7373
raise ValueError("Parameter should be [name, units, default, limits, type, desc], but got %r"
7474
%str(p))
7575
processed.append(parse_parameter(*p))
76-
partable = ParameterTable(processed)
76+
partable = ParameterTable(processed, allow_magnetic=allow_magnetic)
7777
partable.check_angles(strict=True)
7878
return partable
7979

@@ -141,6 +141,15 @@ def parse_parameter(name, units='', default=np.nan,
141141
else:
142142
pid, ref = name, None
143143

144+
# TODO: remove code to identify type=sld based on "sld" in the parameter name
145+
# Suppressing the following will remove magnetic parameters from models
146+
# with implicitly defined sld types. Since this will change the behaviour
147+
# on user-defined plugin models this should not happen except for during
148+
# a major version update. We may, however, generate a deprecation warning
149+
# when such a model is loaded. Note that this removes magnetism attributes
150+
# from the parameter, so it is unlikely that it is being used, but saved
151+
# models may fail when they try to set the M0 attribute on load.
152+
144153
# automatically identify sld types
145154
if ptype == '' and (pid.startswith('sld') or pid.endswith('sld')):
146155
ptype = 'sld'
@@ -434,8 +443,8 @@ class ParameterTable:
434443
the scale and background parameters that the kernel does not see. User
435444
parameters don't use vector notation, and instead use p1, p2, ...
436445
"""
437-
def __init__(self, parameters):
438-
# type: (list[Parameter]) -> None
446+
def __init__(self, parameters, allow_magnetic=True):
447+
# type: (list[Parameter], bool) -> None
439448

440449
# scale and background are implicit parameters
441450
# Need them to be unique to each model in case they have different
@@ -444,8 +453,11 @@ def __init__(self, parameters):
444453
self.kernel_parameters = parameters
445454
self._set_vector_lengths()
446455
self.npars = sum(p.length for p in self.kernel_parameters)
447-
self.nmagnetic = sum(p.length for p in self.kernel_parameters
448-
if p.type == 'sld')
456+
if allow_magnetic:
457+
self.nmagnetic = sum(
458+
p.length for p in self.kernel_parameters if p.type == 'sld')
459+
else:
460+
self.nmagnetic = 0
449461
self.nvalues = NUM_COMMON_PARS + self.npars
450462
if self.nmagnetic:
451463
self.nvalues += NUM_MAGFIELD_PARS + NUM_MAGNETIC_PARS*self.nmagnetic
@@ -913,29 +925,38 @@ def make_model_info(kernel_module):
913925
# Custom sum/multi models
914926
return kernel_module.model_info
915927

916-
info = ModelInfo()
917-
918-
# Build the parameter table
919-
#print("make parameter table", kernel_module.parameters)
920-
parameters = make_parameter_table(getattr(kernel_module, 'parameters', []))
921-
922-
# background defaults to zero for structure factor models
923-
structure_factor = getattr(kernel_module, 'structure_factor', False)
924-
if structure_factor:
925-
parameters.set_zero_background()
926-
927928
filename = abspath(kernel_module.__file__).replace('.pyc', '.py')
928929
kernel_id = splitext(basename(filename))[0]
929930
name = getattr(kernel_module, 'name', None)
930931
if name is None:
931932
name = " ".join(w.capitalize() for w in kernel_id.split('_'))
932933

934+
parameters = getattr(kernel_module, 'parameters', None)
935+
if parameters is None:
936+
raise ValueError("no parameter table specified for {filename}")
937+
938+
info = ModelInfo()
933939
info.id = kernel_id # string used to load the kernel
934-
info.basefile = info.filename = filename
935940
info.name = name
941+
info.basefile = info.filename = filename
942+
943+
info.Iq = getattr(kernel_module, 'Iq', None) # type: ignore
944+
info.Fq = getattr(kernel_module, 'Fq', None) # type: ignore
945+
info.compiled = not callable(info.Iq) and not callable(info.Fq)
946+
947+
# TODO: enable magnetism for pure python models
948+
# Build the parameter table
949+
# print("make parameter table", parameters)
950+
parameter_table = make_parameter_table(parameters, allow_magnetic=info.compiled)
951+
952+
# background defaults to zero for structure factor models
953+
structure_factor = getattr(kernel_module, 'structure_factor', False)
954+
if structure_factor:
955+
parameter_table.set_zero_background()
956+
info.base = info.parameters = parameter_table
957+
936958
info.title = getattr(kernel_module, 'title', name+" model")
937959
info.description = getattr(kernel_module, 'description', 'no description')
938-
info.base = info.parameters = parameters
939960
info.translation = None
940961
info.composition = None
941962
info.docs = kernel_module.__doc__
@@ -953,8 +974,6 @@ def make_model_info(kernel_module):
953974
info.valid = getattr(kernel_module, 'valid', '')
954975
info.form_volume = getattr(kernel_module, 'form_volume', None) # type: ignore
955976
info.shell_volume = getattr(kernel_module, 'shell_volume', None) # type: ignore
956-
info.Iq = getattr(kernel_module, 'Iq', None) # type: ignore
957-
info.Fq = getattr(kernel_module, 'Fq', None) # type: ignore
958977
# TODO: We should be able to find Fq in C code by inspection.
959978
info.have_Fq = getattr(kernel_module, 'have_Fq', (info.Fq is not None))
960979
info.Iqxy = getattr(kernel_module, 'Iqxy', None) # type: ignore
@@ -964,7 +983,6 @@ def make_model_info(kernel_module):
964983
info.profile = getattr(kernel_module, 'profile', None) # type: ignore
965984
info.sesans = getattr(kernel_module, 'sesans', None) # type: ignore
966985
# Default single and opencl to True for C models. Python models have callable Iq.
967-
info.compiled = not callable(info.Iq) and not callable(info.Fq)
968986
info.opencl = getattr(kernel_module, 'opencl', info.compiled)
969987
info.single = getattr(kernel_module, 'single', info.compiled)
970988
info.random = getattr(kernel_module, 'random', None)
@@ -973,9 +991,9 @@ def make_model_info(kernel_module):
973991
# Set control flag for explicitly set parameters, e.g., in the RPA model.
974992
control = getattr(kernel_module, 'control', None)
975993
if control is not None:
976-
parameters[control].is_control = True
994+
parameter_table[control].is_control = True
977995

978-
if not info.compiled and parameters.has_2d:
996+
if not info.compiled and parameter_table.has_2d:
979997
raise ValueError("oriented python models not supported")
980998

981999
# CRUFT: support old-style ER() for effective radius

0 commit comments

Comments
 (0)