source: sasmodels/sasmodels/convert.py @ fa1582e

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

remove constraint which set n_stacking=1 on stacked disk model in compare

  • Property mode set to 100644
File size: 6.9 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 == 'stacked_disks':
140            _remove_pd(oldpars, 'n_stacking', name)
141        elif name == 'pearl_necklace':
142            _remove_pd(oldpars, 'num_pearls', name)
143            _remove_pd(oldpars, 'thick_string', name)
144        elif name == 'core_shell_parallelepiped':
145            _remove_pd(oldpars, 'rimA', name)
146            _remove_pd(oldpars, 'rimB', name)
147            _remove_pd(oldpars, 'rimC', name)
148        elif name == 'rpa':
149            # convert scattering lengths from femtometers to centimeters
150            for p in "La", "Lb", "Lc", "Ld":
151                if p in oldpars: oldpars[p] *= 1e-13
152        elif name == 'core_shell_parallelepiped':
153            _remove_pd(oldpars, 'rimA', name)
154        elif name in ['mono_gauss_coil','poly_gauss_coil']:
155            del oldpars['i_zero']
156        elif name == 'fractal':
157            del oldpars['volfraction']
158        elif name == 'vesicle':
159            del oldpars['volfraction']
160        elif name == 'multilayer_vesicle':
161            del oldpars['volfraction']
162
163    return oldpars
164
165def constrain_new_to_old(model_info, pars):
166    """
167    Restrict parameter values to those that will match sasview.
168    """
169    name = model_info['id']
170    # Note: update convert.revert_model to match
171    if name in MODELS_WITHOUT_SCALE or model_info['structure_factor']:
172        pars['scale'] = 1
173    if name in MODELS_WITHOUT_BACKGROUND or model_info['structure_factor']:
174        pars['background'] = 0
175    # sasview multiplies background by structure factor
176    if '*' in name:
177        pars['background'] = 0
178
179    # If it is a product model P*S, then check the individual forms for special
180    # cases.  Note: despite the structure factor alone not having scale or
181    # background, the product model does, so this is below the test for
182    # models without scale or background.
183    namelist = name.split('*') if '*' in name else [name]
184    for name in namelist:
185        #if name == 'stacked_disks':
186        #    pars['n_stacking'] = 1
187        if name == 'pearl_necklace':
188            pars['string_thickness_pd_n'] = 0
189            pars['number_of_pearls_pd_n'] = 0
190        elif name == 'line':
191            pars['scale'] = 1
192            pars['background'] = 0
193        elif name == 'rpa':
194            pars['case_num'] = int(pars['case_num'])
195        elif name == 'mono_gauss_coil':
196            pars['i_zero'] = 1
197        elif name == 'poly_gauss_coil':
198            pars['i_zero'] = 1
199        elif name == 'fractal':
200            pars['volfraction'] = 1
201        elif name == 'vesicle':
202            pars['volfraction'] = 1
203        elif name == 'multilayer_vesicle':
204            pars['volfraction'] = 1
205           
Note: See TracBrowser for help on using the repository browser.