source: sasmodels/sasmodels/convert.py @ ce896fd

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

improved handling of vector parameters; remove compile errors from onion.c

  • 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    print "pars",pars
76    return dict((p, (v*1e-6 if p.startswith('sld') or p.endswith('sld')
77                     else v*1e15 if 'ndensity' in p
78                     else v))
79                for p, v in pars.items())
80
81def _remove_pd(pars, key, name):
82    """
83    Remove polydispersity from the parameter list.
84
85    Note: operates in place
86    """
87    # Bumps style parameter names
88    pd = pars.pop(key+".width", 0.0)
89    pd_n = pars.pop(key+".npts", 0)
90    if pd != 0.0 and pd_n != 0:
91        warnings.warn("parameter %s not polydisperse in sasview %s"%(key, name))
92    pars.pop(key+".nsigmas", None)
93    pars.pop(key+".type", None)
94    return pars
95
96def _revert_pars(pars, mapping):
97    """
98    Rename the parameters and any associated polydispersity attributes.
99    """
100    newpars = pars.copy()
101
102    for new, old in mapping.items():
103        for pd, dot in PD_DOT:
104            if old and old+pd == new+dot:
105                continue
106            if new+pd in newpars:
107                if old is not None:
108                    newpars[old+dot] = pars[new+pd]
109                del newpars[new+pd]
110    for k in list(newpars.keys()):
111        for pd, dot in PD_DOT[1:]:  # skip "" => ""
112            if k.endswith(pd):
113                newpars[k[:-len(pd)]+dot] = newpars[k]
114                del newpars[k]
115    return newpars
116
117def revert_pars(model_info, pars):
118    """
119    Convert model from new style parameter names to old style.
120    """
121    mapping = model_info['oldpars']
122    oldpars = _revert_pars(_unscale_sld(pars), mapping)
123
124    # Note: update compare.constrain_pars to match
125    name = model_info['id']
126    if name in MODELS_WITHOUT_SCALE or model_info['structure_factor']:
127        if oldpars.pop('scale', 1.0) != 1.0:
128            warnings.warn("parameter scale not used in sasview %s"%name)
129    if name in MODELS_WITHOUT_BACKGROUND or model_info['structure_factor']:
130        if oldpars.pop('background', 0.0) != 0.0:
131            warnings.warn("parameter background not used in sasview %s"%name)
132
133
134    # If it is a product model P*S, then check the individual forms for special
135    # cases.  Note: despite the structure factor alone not having scale or
136    # background, the product model does, so this is below the test for
137    # models without scale or background.
138    namelist = name.split('*') if '*' in name else [name]
139    for name in namelist:
140        if name == 'pearl_necklace':
141            _remove_pd(oldpars, 'num_pearls', name)
142            _remove_pd(oldpars, 'thick_string', name)
143        elif name == 'core_shell_parallelepiped':
144            _remove_pd(oldpars, 'rimA', name)
145            _remove_pd(oldpars, 'rimB', name)
146            _remove_pd(oldpars, 'rimC', name)
147        elif name == 'rpa':
148            # convert scattering lengths from femtometers to centimeters
149            for p in "La", "Lb", "Lc", "Ld":
150                if p in oldpars: oldpars[p] *= 1e-13
151        elif name == 'core_shell_parallelepiped':
152            _remove_pd(oldpars, 'rimA', name)
153        elif name in ['mono_gauss_coil','poly_gauss_coil']:
154            del oldpars['i_zero']
155        elif name == 'fractal':
156            del oldpars['volfraction']
157        elif name == 'vesicle':
158            del oldpars['volfraction']
159        elif name == 'multilayer_vesicle':
160            del oldpars['volfraction']
161
162    return oldpars
163
164def constrain_new_to_old(model_info, pars):
165    """
166    Restrict parameter values to those that will match sasview.
167    """
168    name = model_info['id']
169    # Note: update convert.revert_model to match
170    if name in MODELS_WITHOUT_SCALE or model_info['structure_factor']:
171        pars['scale'] = 1
172    if name in MODELS_WITHOUT_BACKGROUND or model_info['structure_factor']:
173        pars['background'] = 0
174    # sasview multiplies background by structure factor
175    if '*' in name:
176        pars['background'] = 0
177
178    # If it is a product model P*S, then check the individual forms for special
179    # cases.  Note: despite the structure factor alone not having scale or
180    # background, the product model does, so this is below the test for
181    # models without scale or background.
182    namelist = name.split('*') if '*' in name else [name]
183    for name in namelist:
184        if name == 'pearl_necklace':
185            pars['string_thickness_pd_n'] = 0
186            pars['number_of_pearls_pd_n'] = 0
187        elif name == 'line':
188            pars['scale'] = 1
189            pars['background'] = 0
190        elif name == 'rpa':
191            pars['case_num'] = int(pars['case_num'])
192        elif name == 'mono_gauss_coil':
193            pars['i_zero'] = 1
194        elif name == 'poly_gauss_coil':
195            pars['i_zero'] = 1
196        elif name == 'fractal':
197            pars['volfraction'] = 1
198        elif name == 'vesicle':
199            pars['volfraction'] = 1
200        elif name == 'multilayer_vesicle':
201            pars['volfraction'] = 1
202           
Note: See TracBrowser for help on using the repository browser.