source: sasmodels/sasmodels/convert.py @ 12dbc90

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

fractal model converted and docs checked

  • Property mode set to 100644
File size: 6.5 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        elif name == 'fractal':
154            del oldpars['volfraction']
155
156    return oldpars
157
158def constrain_new_to_old(model_info, pars):
159    """
160    Restrict parameter values to those that will match sasview.
161    """
162    name = model_info['id']
163    # Note: update convert.revert_model to match
164    if name in MODELS_WITHOUT_SCALE or model_info['structure_factor']:
165        pars['scale'] = 1
166    if name in MODELS_WITHOUT_BACKGROUND or model_info['structure_factor']:
167        pars['background'] = 0
168    # sasview multiplies background by structure factor
169    if '*' in name:
170        pars['background'] = 0
171
172    # If it is a product model P*S, then check the individual forms for special
173    # cases.  Note: despite the structure factor alone not having scale or
174    # background, the product model does, so this is below the test for
175    # models without scale or background.
176    namelist = name.split('*') if '*' in name else [name]
177    for name in namelist:
178        if name == 'pearl_necklace':
179            pars['string_thickness_pd_n'] = 0
180            pars['number_of_pearls_pd_n'] = 0
181        elif name == 'line':
182            pars['scale'] = 1
183            pars['background'] = 0
184        elif name == 'rpa':
185            pars['case_num'] = int(pars['case_num'])
186        elif name == 'mono_gauss_coil':
187            pars['i_zero'] = 1
188        elif name == 'poly_gauss_coil':
189            pars['i_zero'] = 1
190        elif name == 'fractal':
191            pars['volfraction'] = 1
192           
Note: See TracBrowser for help on using the repository browser.