source: sasmodels/sasmodels/convert.py @ 310ddcb

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 310ddcb was 310ddcb, checked in by richardh, 8 years ago

fix convert for new structure_factor flag in model_info

  • Property mode set to 100644
File size: 6.0 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.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    # If it is a product model P*S, then check the individual forms for special
132    # cases.  Note: despite the structure factor alone not having scale or
133    # background, the product model does, so this is below the test for
134    # models without scale or background.
135    namelist = name.split('*') if '*' in name else [name]
136    for name in namelist:
137        if name == 'pearl_necklace':
138            _remove_pd(oldpars, 'num_pearls', name)
139            _remove_pd(oldpars, 'thick_string', name)
140        elif name == 'core_shell_parallelepiped':
141            _remove_pd(oldpars, 'rimA', name)
142            _remove_pd(oldpars, 'rimB', name)
143            _remove_pd(oldpars, 'rimC', name)
144        elif name == 'rpa':
145            # convert scattering lengths from femtometers to centimeters
146            for p in "La", "Lb", "Lc", "Ld":
147                if p in oldpars: oldpars[p] *= 1e-13
148
149    return oldpars
150
151def constrain_new_to_old(model_info, pars):
152    """
153    Restrict parameter values to those that will match sasview.
154    """
155    name = model_info['id']
156    # Note: update convert.revert_model to match
157    if name in MODELS_WITHOUT_SCALE or model_info['structure_factor']:
158        pars['scale'] = 1
159    if name in MODELS_WITHOUT_BACKGROUND or model_info['structure_factor']:
160        pars['background'] = 0
161    # sasview multiplies background by structure factor
162    if '*' in name:
163        pars['background'] = 0
164
165    # If it is a product model P*S, then check the individual forms for special
166    # cases.  Note: despite the structure factor alone not having scale or
167    # background, the product model does, so this is below the test for
168    # models without scale or background.
169    namelist = name.split('*') if '*' in name else [name]
170    for name in namelist:
171        if name == 'pearl_necklace':
172            pars['string_thickness_pd_n'] = 0
173            pars['number_of_pearls_pd_n'] = 0
174        elif name == 'line':
175            pars['scale'] = 1
176            pars['background'] = 0
177        elif name == 'rpa':
178            pars['case_num'] = int(pars['case_num'])
Note: See TracBrowser for help on using the repository browser.