# Changeset b3f4831 in sasmodels

Ignore:
Timestamp:
Oct 30, 2018 11:07:41 AM (11 months ago)
Branches:
ticket_1156
Children:
cc8b183
Parents:
5778279 (diff), c6084f1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ticket_1156

Files:
22 edited

Unmodified
Removed
• ## doc/guide/magnetism/magnetism.rst

 rbefe905 ===========   ================================================================ M0:sld       $D_M M_0$ mtheta:sld   $\theta_M$ mphi:sld     $\phi_M$ up:angle     $\theta_\mathrm{up}$ up:frac_i    $u_i$ = (spin up)/(spin up + spin down) *before* the sample up:frac_f    $u_f$ = (spin up)/(spin up + spin down) *after* the sample sld_M0       $D_M M_0$ sld_mtheta   $\theta_M$ sld_mphi     $\phi_M$ up_frac_i    $u_i$ = (spin up)/(spin up + spin down) *before* the sample up_frac_f    $u_f$ = (spin up)/(spin up + spin down) *after* the sample up_angle     $\theta_\mathrm{up}$ ===========   ================================================================ .. note:: The values of the 'up:frac_i' and 'up:frac_f' must be in the range 0 to 1. The values of the 'up_frac_i' and 'up_frac_f' must be in the range 0 to 1. *Document History*
• ## doc/guide/plugin.rst

 rf796469 calculations, but instead rely on numerical integration to compute the appropriately smeared pattern. Each .py file also contains a function:: def random(): ... This function provides a model-specific random parameter set which shows model features in the USANS to SANS range.  For example, core-shell sphere sets the outer radius of the sphere logarithmically in [20, 20,000], which sets the Q value for the transition from flat to falling.  It then uses a beta distribution to set the percentage of the shape which is shell, giving a preference for very thin or very thick shells (but never 0% or 100%).  Using -sets=10 in sascomp should show a reasonable variety of curves over the default sascomp q range. The parameter set is returned as a dictionary of {parameter: value, ...}. Any model parameters not included in the dictionary will default according to the code in the _randomize_one() function from sasmodels/compare.py. Python Models erf, erfc, tgamma, lgamma:  **do not use** Special functions that should be part of the standard, but are missing or inaccurate on some platforms. Use sas_erf, sas_erfc and sas_gamma instead (see below). Note: lgamma(x) has not yet been tested. or inaccurate on some platforms. Use sas_erf, sas_erfc, sas_gamma and sas_lgamma instead (see below). Some non-standard constants and functions are also provided: Gamma function sas_gamma\ $(x) = \Gamma(x)$. The standard math function, tgamma(x) is unstable for $x < 1$ The standard math function, tgamma(x), is unstable for $x < 1$ on some platforms. :code:source = ["lib/sas_gamma.c", ...] (sas_gamma.c _) sas_gammaln(x): log gamma function sas_gammaln\ $(x) = \log \Gamma(|x|)$. The standard math function, lgamma(x), is incorrect for single precision on some platforms. :code:source = ["lib/sas_gammainc.c", ...] (sas_gammainc.c _) sas_gammainc(a, x), sas_gammaincc(a, x): Incomplete gamma function sas_gammainc\ $(a, x) = \int_0^x t^{a-1}e^{-t}\,dt / \Gamma(a)$ and complementary incomplete gamma function sas_gammaincc\ $(a, x) = \int_x^\infty t^{a-1}e^{-t}\,dt / \Gamma(a)$ :code:source = ["lib/sas_gammainc.c", ...] (sas_gammainc.c _) sas_erf(x), sas_erfc(x): If $n$ = 0 or 1, it uses sas_J0($x$) or sas_J1($x$), respectively. Warning: JN(n,x) can be very inaccurate (0.1%) for x not in [0.1, 100]. The standard math function jn(n, x) is not available on all platforms. Sine integral Si\ $(x) = \int_0^x \tfrac{\sin t}{t}\,dt$. Warning: Si(x) can be very inaccurate (0.1%) for x in [0.1, 100]. This function uses Taylor series for small and large arguments: For large arguments, For large arguments use the following Taylor series, .. math:: - \frac{\sin(x)}{x}\left(\frac{1}{x} - \frac{3!}{x^3} + \frac{5!}{x^5} - \frac{7!}{x^7}\right) For small arguments, For small arguments , .. math::

• ## sasmodels/__init__.py

 re65c3ba defining new models. """ __version__ = "0.97" __version__ = "0.98" def data_files():
• ## sasmodels/compare.py

 rbd7630d # Limit magnetic SLDs to a smaller range, from zero to iron=5/A^2 if par.name.startswith('M0:'): if par.name.endswith('_M0'): return np.random.uniform(0, 5) magnetic_pars = [] for p in parameters.user_parameters(pars, is2d): if any(p.id.startswith(x) for x in ('M0:', 'mtheta:', 'mphi:')): if any(p.id.endswith(x) for x in ('_M0', '_mtheta', '_mphi')): continue if p.id.startswith('up:'): pdtype=pars.get(p.id+"_pd_type", 'gaussian'), relative_pd=p.relative_pd, M0=pars.get('M0:'+p.id, 0.), mphi=pars.get('mphi:'+p.id, 0.), mtheta=pars.get('mtheta:'+p.id, 0.), M0=pars.get(p.id+'_M0', 0.), mphi=pars.get(p.id+'_mphi', 0.), mtheta=pars.get(p.id+'_mtheta', 0.), ) lines.append(_format_par(p.name, **fields)) if suppress: for p in pars: if p.startswith("M0:"): if p.endswith("_M0"): pars[p] = 0 else: first_mag = None for p in pars: if p.startswith("M0:"): if p.endswith("_M0"): any_mag |= (pars[p] != 0) if first_mag is None:
• ## sasmodels/convert.py

 r78f8308 if version < (4, 2, 0): oldpars = _hand_convert_4_1_to_4_2(name, oldpars) oldpars = _rename_magnetic_pars(oldpars) return oldpars oldpars['lattice_distortion'] = oldpars.pop('d_factor') return oldpars def _rename_magnetic_pars(pars): """ Change from M0:par to par_M0, etc. """ keys = list(pars.items()) for k in keys: if k.startswith('M0:'): pars[k[3:]+'_M0'] = pars.pop(k) elif k.startswith('mtheta:'): pars[k[7:]+'_mtheta'] = pars.pop(k) elif k.startswith('mphi:'): pars[k[5:]+'_mphi'] = pars.pop(k) elif k.startswith('up:'): pars['up_'+k[3:]] = pars.pop(k) return pars def _hand_convert_3_1_2_to_4_1(name, oldpars):

• ## sasmodels/kernelpy.py

 r108e70e self.info = model_info self.dtype = np.dtype('d') logger.info("load python model " + self.info.name) logger.info("make python model " + self.info.name) def make_kernel(self, q_vectors):

• ## sasmodels/modelinfo.py

 r7b9e4dd self.is_asymmetric = any(p.name == 'psi' for p in self.kernel_parameters) self.magnetism_index = [k for k, p in enumerate(self.call_parameters) if p.id.startswith('M0:')] if p.id.endswith('_M0')] self.pd_1d = set(p.name for p in self.call_parameters if self.nmagnetic > 0: full_list.extend([ Parameter('up:frac_i', '', 0., [0., 1.], Parameter('up_frac_i', '', 0., [0., 1.], 'magnetic', 'fraction of spin up incident'), Parameter('up:frac_f', '', 0., [0., 1.], Parameter('up_frac_f', '', 0., [0., 1.], 'magnetic', 'fraction of spin up final'), Parameter('up:angle', 'degrees', 0., [0., 360.], Parameter('up_angle', 'degrees', 0., [0., 360.], 'magnetic', 'spin up angle'), ]) for p in slds: full_list.extend([ Parameter('M0:'+p.id, '1e-6/Ang^2', 0., [-np.inf, np.inf], Parameter(p.id+'_M0', '1e-6/Ang^2', 0., [-np.inf, np.inf], 'magnetic', 'magnetic amplitude for '+p.description), Parameter('mtheta:'+p.id, 'degrees', 0., [-90., 90.], Parameter(p.id+'_mtheta', 'degrees', 0., [-90., 90.], 'magnetic', 'magnetic latitude for '+p.description), Parameter('mphi:'+p.id, 'degrees', 0., [-180., 180.], Parameter(p.id+'_mphi', 'degrees', 0., [-180., 180.], 'magnetic', 'magnetic longitude for '+p.description), ]) Parameters marked as sld will automatically have a set of associated magnetic parameters (m0:p, mtheta:p, mphi:p), as well as polarization information (up:theta, up:frac_i, up:frac_f). magnetic parameters (p_M0, p_mtheta, p_mphi), as well as polarization information (up_theta, up_frac_i, up_frac_f). """ # control parameters go first result.append(expanded_pars[name]) if is2d: for tag in 'M0:', 'mtheta:', 'mphi:': if tag+name in expanded_pars: result.append(expanded_pars[tag+name]) for tag in '_M0', '_mtheta', '_mphi': if name+tag in expanded_pars: result.append(expanded_pars[name+tag]) # Gather the user parameters in order append_group(p.id) if is2d and 'up:angle' in expanded_pars: if is2d and 'up_angle' in expanded_pars: result.extend([ expanded_pars['up:frac_i'], expanded_pars['up:frac_f'], expanded_pars['up:angle'], expanded_pars['up_frac_i'], expanded_pars['up_frac_f'], expanded_pars['up_angle'], ]) info.structure_factor = getattr(kernel_module, 'structure_factor', False) info.profile_axes = getattr(kernel_module, 'profile_axes', ['x', 'y']) # Note: custom.load_custom_kernel_module assumes the C sources are defined # by this attribute. info.source = getattr(kernel_module, 'source', []) info.c_code = getattr(kernel_module, 'c_code', None) for k in range(control+1, p.length+1) if p.length > 1) for p in self.parameters.kernel_parameters: if p.length > 1 and p.type == "sld": for k in range(control+1, p.length+1): base = p.id+str(k) hidden.update((base+"_M0", base+"_mtheta", base+"_mphi")) return hidden
• ## sasmodels/models/bcc_paracrystal.py

 re7e9231 r""" .. warning:: This model and this model description are under review following concerns raised by SasView users. If you need to use this model, please email help@sasview.org for the latest situation. *The SasView Developers. September 2018.* Definition ---------- I(q) = \frac{\text{scale}}{V_p} V_\text{lattice} P(q) Z(q) where *scale* is the volume fraction of spheres, $V_p$ is the volume of the Authorship and Verification ---------------------------- --------------------------- * **Author:** NIST IGOR/DANSE **Date:** pre 2010
• ## sasmodels/models/be_polyelectrolyte.py

 ref07e95 r""" .. note:: Please read the Validation section below. Definition ---------- I(q) = K\frac{q^2+k^2}{4\pi L_b\alpha ^2} \frac{1}{1+r_{0}^2(q^2+k^2)(q^2-12hC_a/b^2)} + background \frac{1}{1+r_{0}^4(q^2+k^2)(q^2-12hC_a/b^2)} + background k^2 = 4\pi L_b(2C_s + \alpha C_a) r_{0}^2 = \frac{1}{\alpha \sqrt{C_a} \left( b/\sqrt{48\pi L_b}\right)} r_{0}^2 = \frac{b}{\alpha \sqrt{C_a 48\pi L_b}} where $K$ is the contrast factor for the polymer which is defined differently than in other models and is given in barns where $1 barn = 10^{-24} cm^2$.  $K$ is other models and is given in barns where 1 $barn = 10^{-24}$ $cm^2$.  $K$ is defined as: a = b_p - (v_p/v_s) b_s where $b_p$ and $b_s$ are sum of the scattering lengths of the atoms constituting the monomer of the polymer and the sum of the scattering lengths of the atoms constituting the solvent molecules respectively, and $v_p$ and $v_s$ are the partial molar volume of the polymer and the solvent respectively $L_b$ is the Bjerrum length(|Ang|) - **Note:** This parameter needs to be kept constant for a given solvent and temperature! $h$ is the virial parameter (|Ang^3|/mol) - **Note:** See [#Borue]_ for the correct interpretation of this parameter.  It incorporates second and third virial coefficients and can be Negative. $b$ is the monomer length(|Ang|), $C_s$ is the concentration of monovalent salt(mol/L), $\alpha$ is the ionization degree (ionization degree : ratio of charged monomers  to total number of monomers), $C_a$ is the polymer molar concentration(mol/L), and $background$ is the incoherent background. where: - $b_p$ and $b_s$ are **sum of the scattering lengths of the atoms** constituting the polymer monomer and the solvent molecules, respectively. - $v_p$ and $v_s$ are the partial molar volume of the polymer and the solvent, respectively. - $L_b$ is the Bjerrum length (|Ang|) - **Note:** This parameter needs to be kept constant for a given solvent and temperature! - $h$ is the virial parameter (|Ang^3|) - **Note:** See [#Borue]_ for the correct interpretation of this parameter.  It incorporates second and third virial coefficients and can be *negative*. - $b$ is the monomer length (|Ang|). - $C_s$ is the concentration of monovalent salt(1/|Ang^3| - internally converted from mol/L). - $\alpha$ is the degree of ionization (the ratio of charged monomers to the total number of monomers) - $C_a$ is the polymer molar concentration (1/|Ang^3| - internally converted from mol/L) - $background$ is the incoherent background. For 2D data the scattering intensity is calculated in the same way as 1D, q = \sqrt{q_x^2 + q_y^2} Validation ---------- As of the last revision, this code is believed to be correct.  However it needs further validation and should be used with caution at this time.  The history of this code goes back to a 1998 implementation. It was recently noted that in that implementation, while both the polymer concentration and salt concentration were converted from experimental units of mol/L to more dimensionally useful units of 1/|Ang^3|, only the converted version of the polymer concentration was actually being used in the calculation while the unconverted salt concentration (still in apparent units of mol/L) was being used.  This was carried through to Sasmodels as used for SasView 4.1 (though the line of code converting the salt concentration to the new units was removed somewhere along the line). Simple dimensional analysis of the calculation shows that the converted salt concentration should be used, which the original code suggests was the intention, so this has now been corrected (for SasView 4.2). Once better validation has been performed this note will be removed. References * **Author:** NIST IGOR/DANSE **Date:** pre 2010 * **Last Modified by:** Paul Kienzle **Date:** July 24, 2016 * **Last Reviewed by:** Paul Butler and Richard Heenan **Date:** October 07, 2016 * **Last Modified by:** Paul Butler **Date:** September 25, 2018 * **Last Reviewed by:** Paul Butler **Date:** September 25, 2018 """ ["contrast_factor",       "barns",   10.0,  [-inf, inf], "", "Contrast factor of the polymer"], ["bjerrum_length",        "Ang",      7.1,  [0, inf],    "", "Bjerrum length"], ["virial_param",          "Ang^3/mol", 12.0,  [-inf, inf], "", "Virial parameter"], ["virial_param",          "Ang^3", 12.0,  [-inf, inf], "", "Virial parameter"], ["monomer_length",        "Ang",     10.0,  [0, inf],    "", "Monomer length"], ["salt_concentration",    "mol/L",    0.0,  [-inf, inf], "", "Concentration of monovalent salt"], def Iq(q, contrast_factor=10.0, bjerrum_length=7.1, virial_param=12.0, monomer_length=10.0, salt_concentration=0.0, ionization_degree=0.05, polymer_concentration=0.7): contrast_factor, bjerrum_length, virial_param, monomer_length, salt_concentration, ionization_degree, polymer_concentration): """ :param q:                     Input q-value :param contrast_factor:       Contrast factor of the polymer :param bjerrum_length:        Bjerrum length :param virial_param:          Virial parameter :param monomer_length:        Monomer length :param salt_concentration:    Concentration of monovalent salt :param ionization_degree:     Degree of ionization :param polymer_concentration: Polymer molar concentration :return:                      1-D intensity :params: see parameter table :return: 1-D form factor for polyelectrolytes in low salt parameter names, units, default values, and behavior (volume, sld etc) are defined in the parameter table.  The concentrations are converted from experimental mol/L to dimensionaly useful 1/A3 in first two lines """ concentration = polymer_concentration * 6.022136e-4 k_square = 4.0 * pi * bjerrum_length * (2*salt_concentration + ionization_degree * concentration) r0_square = 1.0/ionization_degree/sqrt(concentration) * \ concentration_pol = polymer_concentration * 6.022136e-4 concentration_salt = salt_concentration * 6.022136e-4 k_square = 4.0 * pi * bjerrum_length * (2*concentration_salt + ionization_degree * concentration_pol) r0_square = 1.0/ionization_degree/sqrt(concentration_pol) * \ (monomer_length/sqrt((48.0*pi*bjerrum_length))) term2 = 1.0 + r0_square**2 * (q**2 + k_square) * \ (q**2 - (12.0 * virial_param * concentration/(monomer_length**2))) (q**2 - (12.0 * virial_param * concentration_pol/(monomer_length**2))) return term1/term2 # Accuracy tests based on content in test/utest_other_models.py # Note that these should some day be validated beyond this self validation # (circular reasoning). -- i.e. the "good value," at least for those with # non zero salt concentrations, were obtained by running the current # model in SasView and copying the appropriate result here. #    PDB -- Sep 26, 2018 [{'contrast_factor':       10.0, 'bjerrum_length':         7.1, }, 0.001, 0.0948379], # Additional tests with larger range of parameters [{'contrast_factor':       10.0, 'bjerrum_length':       100.0, 'virial_param':           3.0, 'monomer_length':         1.0, 'salt_concentration':    10.0, 'ionization_degree':      2.0, 'polymer_concentration': 10.0, 'monomer_length':         5.0, 'salt_concentration':     1.0, 'ionization_degree':      0.1, 'polymer_concentration':  1.0, 'background':             0.0, }, 0.1, -3.75693800588], }, 0.1, 0.253469484], [{'contrast_factor':       10.0, 'bjerrum_length':       100.0, 'virial_param':           3.0, 'monomer_length':         1.0, 'salt_concentration':    10.0, 'ionization_degree':      2.0, 'polymer_concentration': 10.0, 'background':           100.0 }, 5.0, 100.029142149], 'monomer_length':         5.0, 'salt_concentration':     1.0, 'ionization_degree':      0.1, 'polymer_concentration':  1.0, 'background':             1.0, }, 0.05, 1.738358122], [{'contrast_factor':     100.0, 'bjerrum_length':       10.0, 'virial_param':        180.0, 'monomer_length':        1.0, 'virial_param':         12.0, 'monomer_length':       10.0, 'salt_concentration':    0.1, 'ionization_degree':     0.5, 'polymer_concentration': 0.1, 'background':             0.0, }, 200., 1.80664667511e-06], 'background':           0.01, }, 0.5, 0.012881893], ]
• ## sasmodels/models/fcc_paracrystal.py

 re7e9231 #note - calculation requires double precision r""" .. warning:: This model and this model description are under review following concerns raised by SasView users. If you need to use this model, please email help@sasview.org for the latest situation. *The SasView Developers. September 2018.* Definition ---------- negligible, and the size of the paracrystal is infinitely large. Paracrystalline distortion is assumed to be isotropic and characterized by a Gaussian distribution. a Gaussian distribution. The scattering intensity $I(q)$ is calculated as
• ## sasmodels/models/sc_paracrystal.py

 r0b906ea r""" .. warning:: This model and this model description are under review following concerns raised by SasView users. If you need to use this model, please email help@sasview.org for the latest situation. *The SasView Developers. September 2018.* Definition ---------- by a Gaussian distribution. he scattering intensity $I(q)$ is calculated as The scattering intensity $I(q)$ is calculated as .. math:: Equation (16) of the 1987 reference\ [#CIT1987]_ is used to calculate $Z(q)$, using equations (13)-(15) from the 1987 paper\ [#CIT1987]_ for Z1, Z2, and Z3. using equations (13)-(15) from the 1987 paper\ [#CIT1987]_ for $Z1$, $Z2$, and $Z3$. The lattice correction (the occupied volume of the lattice) for a simple cubic
• ## sasmodels/models/spinodal.py

 r475ff58 where $x=q/q_0$, $q_0$ is the peak position, $I_{max}$ is the intensity at $q_0$ (parameterised as the $scale$ parameter), and $B$ is a flat background. The spinodal wavelength is given by $2\pi/q_0$. background. The spinodal wavelength, $\Lambda$, is given by $2\pi/q_0$. The definition of $I_{max}$ in the literature varies. Hashimoto *et al* (1991) define it as .. math:: I_{max} = \Lambda^3\Delta\rho^2 whereas Meier & Strobl (1987) give .. math:: I_{max} = V_z\Delta\rho^2 where $V_z$ is the volume per monomer unit. The exponent $\gamma$ is equal to $d+1$ for off-critical concentration H. Furukawa. Dynamics-scaling theory for phase-separating unmixing mixtures: Growth rates of droplets and scaling properties of autocorrelation functions. Physica A 123,497 (1984). Growth rates of droplets and scaling properties of autocorrelation functions. Physica A 123, 497 (1984). H. Meier & G. Strobl. Small-Angle X-ray Scattering Study of Spinodal Decomposition in Polystyrene/Poly(styrene-co-bromostyrene) Blends. Macromolecules 20, 649-654 (1987). T. Hashimoto, M. Takenaka & H. Jinnai. Scattering Studies of Self-Assembling Processes of Polymer Blends in Spinodal Decomposition. J. Appl. Cryst. 24, 457-466 (1991). Revision History * **Author:**  Dirk Honecker **Date:** Oct 7, 2016 * **Revised:** Steve King    **Date:** Sep 7, 2018 * **Revised:** Steve King    **Date:** Oct 25, 2018 """

• ## sasmodels/special.py

 rdf69efa The standard math function, tgamma(x) is unstable for $x < 1$ on some platforms. sas_gammaln(x): log gamma function sas_gammaln\ $(x) = \log \Gamma(|x|)$. The standard math function, lgamma(x), is incorrect for single precision on some platforms. sas_gammainc(a, x), sas_gammaincc(a, x): Incomplete gamma function sas_gammainc\ $(a, x) = \int_0^x t^{a-1}e^{-t}\,dt / \Gamma(a)$ and complementary incomplete gamma function sas_gammaincc\ $(a, x) = \int_x^\infty t^{a-1}e^{-t}\,dt / \Gamma(a)$ sas_erf(x), sas_erfc(x): from numpy import pi, nan, inf from scipy.special import gamma as sas_gamma from scipy.special import gammaln as sas_gammaln from scipy.special import gammainc as sas_gammainc from scipy.special import gammaincc as sas_gammaincc from scipy.special import erf as sas_erf from scipy.special import erfc as sas_erfc
• ## setup.py

 r1f991d6 return version[1:-1] raise RuntimeError("Could not read version from %s/__init__.py"%package) install_requires = ['numpy', 'scipy'] if sys.platform=='win32' or sys.platform=='cygwin': install_requires.append('tinycc') setup( 'sasmodels': ['*.c', '*.cl'], }, install_requires=[ ], install_requires=install_requires, extras_require={ 'full': ['docutils', 'bumps', 'matplotlib'], 'server': ['bumps'], 'OpenCL': ["pyopencl"], 'Bumps': ["bumps"], 'TinyCC': ["tinycc"], }, build_requires=['setuptools'],