source: sasmodels/sasmodels/convert.py @ 78d3341

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 78d3341 was 78d3341, checked in by Paul Kienzle <pkienzle@…>, 8 years ago

allow the sld on the start or end, or as an sld type

  • Property mode set to 100644
File size: 6.3 KB
Line 
1"""
2Convert models to and from sasview.
3"""
4import warnings
5
6# List of models which SasView versions don't contain the explicit 'scale' argument.
7# When converting such a model, please update this list.
8MODELS_WITHOUT_SCALE = [
9    'teubner_strey',
10    'broad_peak',
11    'two_lorentzian',
12    "two_power_law",
13    'gel_fit',
14    'gauss_lorentz_gel',
15    'be_polyelectrolyte',
16    'correlation_length',
17    'fractal_core_shell'
18    'binary_hard_sphere',
19]
20
21# List of models which SasView versions don't contain the explicit 'background' argument.
22# When converting such a model, please update this list.
23MODELS_WITHOUT_BACKGROUND = [
24    'guinier',
25]
26
27PD_DOT = [
28    ("", ""),
29    ("_pd", ".width"),
30    ("_pd_n", ".npts"),
31    ("_pd_nsigma", ".nsigmas"),
32    ("_pd_type", ".type"),
33    ]
34def _convert_pars(pars, mapping):
35    """
36    Rename the parameters and any associated polydispersity attributes.
37    """
38    newpars = pars.copy()
39    for new, old in mapping.items():
40        if old == new: continue
41        for pd, dot in PD_DOT:
42            if old+dot in newpars:
43                if new is not None:
44                    newpars[new+pd] = pars[old+dot]
45                del newpars[old+dot]
46    return newpars
47
48def _rescale_sld(pars):
49    """
50    rescale all sld parameters in the new model definition by 1e6 so the
51    numbers are nicer.  Relies on the fact that all sld parameters in the
52    new model definition end with sld.
53    """
54    return dict((p, (v*1e6 if p.endswith('sld')
55                     else v*1e-15 if 'ndensity' in p
56                     else v))
57                for p, v in pars.items())
58
59def convert_model(name, pars):
60    """
61    Convert model from old style parameter names to new style.
62    """
63    _, _ = name, pars # lint
64    raise NotImplementedError
65    # need to load all new models in order to determine old=>new
66    # model name mapping
67
68def _unscale_sld(pars):
69    """
70    rescale all sld parameters in the new model definition by 1e6 so the
71    numbers are nicer.  Relies on the fact that all sld parameters in the
72    new model definition end with sld.
73    """
74    return dict((p, (v*1e-6 if p.startswith('sld') or p.endswith('sld')
75                     else v*1e15 if 'ndensity' in p
76                     else v))
77                for p, v in pars.items())
78
79def _remove_pd(pars, key, name):
80    """
81    Remove polydispersity from the parameter list.
82
83    Note: operates in place
84    """
85    # Bumps style parameter names
86    pd = pars.pop(key+".width", 0.0)
87    pd_n = pars.pop(key+".npts", 0)
88    if pd != 0.0 and pd_n != 0:
89        warnings.warn("parameter %s not polydisperse in sasview %s"%(key, name))
90    pars.pop(key+".nsigmas", None)
91    pars.pop(key+".type", None)
92    return pars
93
94def _revert_pars(pars, mapping):
95    """
96    Rename the parameters and any associated polydispersity attributes.
97    """
98    newpars = pars.copy()
99
100    for new, old in mapping.items():
101        for pd, dot in PD_DOT:
102            if old and old+pd == new+dot:
103                continue
104            if new+pd in newpars:
105                if old is not None:
106                    newpars[old+dot] = pars[new+pd]
107                del newpars[new+pd]
108    for k in list(newpars.keys()):
109        for pd, dot in PD_DOT[1:]:  # skip "" => ""
110            if k.endswith(pd):
111                newpars[k[:-len(pd)]+dot] = newpars[k]
112                del newpars[k]
113    return newpars
114
115def revert_pars(model_info, pars):
116    """
117    Convert model from new style parameter names to old style.
118    """
119    mapping = model_info['oldpars']
120    oldpars = _revert_pars(_unscale_sld(pars), mapping)
121
122    # Note: update compare.constrain_pars to match
123    name = model_info['id']
124    if name in MODELS_WITHOUT_SCALE or model_info['structure_factor']:
125        if oldpars.pop('scale', 1.0) != 1.0:
126            warnings.warn("parameter scale not used in sasview %s"%name)
127    if name in MODELS_WITHOUT_BACKGROUND or model_info['structure_factor']:
128        if oldpars.pop('background', 0.0) != 0.0:
129            warnings.warn("parameter background not used in sasview %s"%name)
130
131
132    # If it is a product model P*S, then check the individual forms for special
133    # cases.  Note: despite the structure factor alone not having scale or
134    # background, the product model does, so this is below the test for
135    # models without scale or background.
136    namelist = name.split('*') if '*' in name else [name]
137    for name in namelist:
138        if name == 'pearl_necklace':
139            _remove_pd(oldpars, 'num_pearls', name)
140            _remove_pd(oldpars, 'thick_string', name)
141        elif name == 'core_shell_parallelepiped':
142            _remove_pd(oldpars, 'rimA', name)
143            _remove_pd(oldpars, 'rimB', name)
144            _remove_pd(oldpars, 'rimC', name)
145        elif name == 'rpa':
146            # convert scattering lengths from femtometers to centimeters
147            for p in "La", "Lb", "Lc", "Ld":
148                if p in oldpars: oldpars[p] *= 1e-13
149        elif name == 'core_shell_parallelepiped':
150            _remove_pd(oldpars, 'rimA', name)
151        elif name in ['mono_gauss_coil','poly_gauss_coil']:
152            del oldpars['i_zero']
153
154    return oldpars
155
156def constrain_new_to_old(model_info, pars):
157    """
158    Restrict parameter values to those that will match sasview.
159    """
160    name = model_info['id']
161    # Note: update convert.revert_model to match
162    if name in MODELS_WITHOUT_SCALE or model_info['structure_factor']:
163        pars['scale'] = 1
164    if name in MODELS_WITHOUT_BACKGROUND or model_info['structure_factor']:
165        pars['background'] = 0
166    # sasview multiplies background by structure factor
167    if '*' in name:
168        pars['background'] = 0
169
170    # If it is a product model P*S, then check the individual forms for special
171    # cases.  Note: despite the structure factor alone not having scale or
172    # background, the product model does, so this is below the test for
173    # models without scale or background.
174    namelist = name.split('*') if '*' in name else [name]
175    for name in namelist:
176        if name == 'pearl_necklace':
177            pars['string_thickness_pd_n'] = 0
178            pars['number_of_pearls_pd_n'] = 0
179        elif name == 'line':
180            pars['scale'] = 1
181            pars['background'] = 0
182        elif name == 'rpa':
183            pars['case_num'] = int(pars['case_num'])
184        elif name == 'mono_gauss_coil':
185            pars['i_zero'] = 1
186        elif name == 'poly_gauss_coil':
187            pars['i_zero'] = 1
188           
Note: See TracBrowser for help on using the repository browser.