source: sasmodels/sasmodels/convert.py @ d1c4760

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

Merge branch 'master' into polydisp

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