source: sasmodels/sasmodels/convert.py @ c6ca41e

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

fix name of old multishell model to multilayer vesicle as agreed. Also
fixed parameters to match new agreements. reran tests

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