Changeset 31df0c9 in sasmodels


Ignore:
Timestamp:
Aug 1, 2017 2:38:47 PM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
1511c37c
Parents:
d49ca5c
Message:

tuned random model generation for more models

Location:
sasmodels
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/compare.py

    r109d963 r31df0c9  
    270270    Randomize a single parameter. 
    271271    """ 
     272    # Set the amount of polydispersity/angular dispersion, but by default pd_n 
     273    # is zero so there is no polydispersity.  This allows us to turn on/off 
     274    # pd by setting pd_n, and still have randomly generated values 
    272275    if name.endswith('_pd'): 
    273276        par = model_info.parameters[name[:-3]] 
     
    279282            return np.random.beta(1.5, 7) 
    280283 
     284    # pd is selected globally rather than per parameter, so set to 0 for no pd 
     285    # In particular, when multiple pd dimensions, want to decrease the number 
     286    # of points per dimension for faster computation 
    281287    if name.endswith('_pd_n'): 
    282         # let pd be selected globally rather than per parameter 
    283288        return 0 
    284289 
     290    # Don't mess with distribution type for now 
    285291    if name.endswith('_pd_type'): 
    286         # Don't mess with distribution type for now 
    287292        return 'gaussian' 
    288293 
     294    # type-dependent value of number of sigmas; for gaussian use 3. 
    289295    if name.endswith('_pd_nsigma'): 
    290         # type-dependent value; for gaussian use 3. 
    291296        return 3. 
    292297 
     298    # background in the range [0.01, 1] 
    293299    if name == 'background': 
    294         return np.random.uniform(0, 1) 
    295  
     300        return 10**np.random.uniform(-2, 0) 
     301 
     302    # scale defaults to 0.1% to 30% volume fraction 
    296303    if name == 'scale': 
    297         return 10**np.random.uniform(-5,0) 
    298  
     304        return 10**np.random.uniform(-3, -0.5) 
     305 
     306    # If it is a list of choices, pick one at random with equal probability 
     307    # In practice, the model specific random generator will override. 
    299308    par = model_info.parameters[name] 
    300309    if len(par.limits) > 2:  # choice list 
    301310        return np.random.randint(len(par.limits)) 
    302311 
     312    # If it is a fixed range, pick from it with equal probability. 
     313    # For logarithmic ranges, the model will have to override. 
    303314    if np.isfinite(par.limits).all(): 
    304315        return np.random.uniform(*par.limits) 
    305316 
     317    # If the paramter is marked as an sld use the range of neutron slds 
     318    # Should be doing something with randomly selected contrast matching 
     319    # but for now use random contrasts.  Since real data is contrast-matched, 
     320    # this will favour selection of hollow models when they exist. 
    306321    if par.type == 'sld': 
    307322        # Range of neutron SLDs 
    308323        return np.random.uniform(-0.5, 12) 
    309324 
     325    # Guess at the random length/radius/thickness.  In practice, all models 
     326    # are going to set their own reasonable ranges. 
    310327    if par.type == 'volume': 
    311328        if ('length' in par.name or 
    312329                'radius' in par.name or 
    313330                'thick' in par.name): 
    314             return 10**np.random.uniform(2,4) 
    315  
     331            return 10**np.random.uniform(2, 4) 
     332 
     333    # In the absence of any other info, select a value in [0, 2v], or 
     334    # [-2|v|, 2|v|] if v is negative, or [0, 1] if v is zero.  Mostly the 
     335    # model random parameter generators will override this default. 
    316336    low, high = parameter_range(par.name, value) 
    317337    limits = (max(par.limits[0], low), min(par.limits[1], high)) 
  • sasmodels/models/barbell.py

    ra151caa r31df0c9  
    117117def random(): 
    118118    import numpy as np 
     119    # TODO: increase volume range once problem with bell radius is fixed 
     120    # The issue is that bell radii of more than about 200 fail at high q 
     121    V = 10**np.random.uniform(7, 9) 
     122    bar_volume = 10**np.random.uniform(-4, -1)*V 
     123    bell_volume = V - bar_volume 
     124    bell_radius = (bell_volume/6)**0.3333  # approximate 
     125    min_bar = bar_volume/np.pi/bell_radius**2 
     126    bar_length = 10**np.random.uniform(0, 3)*min_bar 
     127    bar_radius = np.sqrt(bar_volume/bar_length/np.pi) 
     128    if bar_radius > bell_radius: 
     129        bell_radius, bar_radius = bar_radius, bell_radius 
    119130    pars = dict( 
    120         scale=10**np.random.uniform(-4,-1), 
    121         radius_bell=10**np.random.uniform(1.3,3), 
    122         length=10**np.random.uniform(0,3), 
     131        #background=0, 
     132        radius_bell=bell_radius, 
     133        radius=bar_radius, 
     134        length=bar_length, 
    123135    ) 
    124     pars['radius'] = pars['radius_bell']*np.random.uniform(0,1) 
    125     if pars['radius_bell'] < 100: 
    126         pars['length'] *= 10 
    127         pars['scale'] *= 100 
    128136    return pars 
    129137 
  • sasmodels/models/capped_cylinder.py

    r9802ab3 r31df0c9  
    8080 
    8181.. [#] H Kaya, *J. Appl. Cryst.*, 37 (2004) 223-230 
    82 .. [#] H Kaya and N-R deSouza, *J. Appl. Cryst.*, 37 (2004) 508-509 (addenda  
     82.. [#] H Kaya and N-R deSouza, *J. Appl. Cryst.*, 37 (2004) 508-509 (addenda 
    8383   and errata) 
    8484 
     
    136136source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "capped_cylinder.c"] 
    137137 
     138def random(): 
     139    import numpy as np 
     140    # TODO: increase volume range once problem with bell radius is fixed 
     141    # The issue is that bell radii of more than about 200 fail at high q 
     142    V = 10**np.random.uniform(7, 9) 
     143    bar_volume = 10**np.random.uniform(-4, -1)*V 
     144    bell_volume = V - bar_volume 
     145    bell_radius = (bell_volume/6)**0.3333  # approximate 
     146    min_bar = bar_volume/np.pi/bell_radius**2 
     147    bar_length = 10**np.random.uniform(0, 3)*min_bar 
     148    bar_radius = np.sqrt(bar_volume/bar_length/np.pi) 
     149    if bar_radius > bell_radius: 
     150        bell_radius, bar_radius = bar_radius, bell_radius 
     151    pars = dict( 
     152        #background=0, 
     153        radius_cap=bell_radius, 
     154        radius=bar_radius, 
     155        length=bar_length, 
     156    ) 
     157    return pars 
     158 
     159 
    138160demo = dict(scale=1, background=0, 
    139161            sld=6, sld_solvent=1, 
  • sasmodels/models/core_shell_ellipsoid.py

    r9802ab3 r31df0c9  
    2525ellipsoid. This may have some undesirable effects if the aspect ratio of the 
    2626ellipsoid is large (ie, if $X << 1$ or $X >> 1$ ), when the $S(q)$ 
    27 - which assumes spheres - will not in any case be valid.  Generating a  
    28 custom product model will enable separate effective volume fraction and effective  
     27- which assumes spheres - will not in any case be valid.  Generating a 
     28custom product model will enable separate effective volume fraction and effective 
    2929radius in the $S(q)$. 
    3030 
     
    4444 
    4545.. math:: 
    46     \begin{align}     
     46    \begin{align} 
    4747    F(q,\alpha) = &f(q,radius\_equat\_core,radius\_equat\_core.x\_core,\alpha) \\ 
    4848    &+ f(q,radius\_equat\_core + thick\_shell,radius\_equat\_core.x\_core + thick\_shell.x\_polar\_shell,\alpha) 
    49     \end{align}  
     49    \end{align} 
    5050 
    5151where 
    52   
     52 
    5353.. math:: 
    5454 
     
    7777   F^2(q)=\int_{0}^{\pi/2}{F^2(q,\alpha)\sin(\alpha)d\alpha} 
    7878 
    79 For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data,  
     79For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data, 
    8080see the :ref:`elliptical-cylinder` model for further information. 
    8181 
     
    151151    return ellipsoid_ER(polar_outer, equat_outer) 
    152152 
    153  
    154 demo = dict(scale=0.05, background=0.001, 
    155             radius_equat_core=20.0, 
    156             x_core=3.0, 
    157             thick_shell=30.0, 
    158             x_polar_shell=1.0, 
    159             sld_core=2.0, 
    160             sld_shell=1.0, 
    161             sld_solvent=6.3, 
    162             theta=0, 
    163             phi=0) 
     153def random(): 
     154    import numpy as np 
     155    V = 10**np.random.uniform(5, 12) 
     156    radius_polar = 10**np.random.uniform(1.3, 4) 
     157    radius_equatorial = np.sqrt(V/radius_polar) # ignore 4/3 pi 
     158    thickness_polar = np.random.uniform(0.01, 1)*radius_polar 
     159    thickness_equatorial = np.random.uniform(0.01, 1)*radius_equatorial 
     160    radius_polar -= thickness_polar 
     161    radius_equatorial -= thickness_equatorial 
     162    x_core = radius_polar/radius_equatorial 
     163    x_polar_shell = thickness_polar/thickness_equatorial 
     164    pars = dict( 
     165        #background=0, sld=0, sld_solvent=1, 
     166        radius_equat_core=radius_equatorial, 
     167        x_core=x_core, 
     168        thick_shell=thickness_equatorial, 
     169        x_polar_shell=x_polar_shell, 
     170    ) 
     171    return pars 
    164172 
    165173q = 0.1 
  • sasmodels/models/core_shell_sphere.py

    rd49ca5c r31df0c9  
    104104    radius = np.random.uniform(0, 1)*total_radius 
    105105    thickness = total_radius - radius 
    106     Vf = 10**np.random.uniform(4, 6)/total_radius**3 
    107106    pars = dict( 
    108         scale=Vf, 
    109107        radius=radius, 
    110108        thickness=thickness, 
  • sasmodels/models/cylinder.py

    r9802ab3 r31df0c9  
    6363.. figure:: img/cylinder_angle_definition.png 
    6464 
    65     Definition of the $\theta$ and $\phi$ orientation angles for a cylinder relative  
    66     to the beam line coordinates, plus an indication of their orientation distributions  
    67     which are described as rotations about each of the perpendicular axes $\delta_1$ and $\delta_2$  
     65    Definition of the $\theta$ and $\phi$ orientation angles for a cylinder relative 
     66    to the beam line coordinates, plus an indication of their orientation distributions 
     67    which are described as rotations about each of the perpendicular axes $\delta_1$ and $\delta_2$ 
    6868    in the frame of the cylinder itself, which when $\theta = \phi = 0$ are parallel to the $Y$ and $X$ axes. 
    6969 
     
    7272    Examples for oriented cylinders. 
    7373 
    74 The $\theta$ and $\phi$ parameters to orient the cylinder only appear in the model when fitting 2d data.  
     74The $\theta$ and $\phi$ parameters to orient the cylinder only appear in the model when fitting 2d data. 
    7575On introducing "Orientational Distribution" in the angles, "distribution of theta" and "distribution of phi" parameters will 
    76 appear. These are actually rotations about the axes $\delta_1$ and $\delta_2$ of the cylinder, which when $\theta = \phi = 0$ are parallel  
     76appear. These are actually rotations about the axes $\delta_1$ and $\delta_2$ of the cylinder, which when $\theta = \phi = 0$ are parallel 
    7777to the $Y$ and $X$ axes of the instrument respectively. Some experimentation may be required to understand the 2d patterns fully. 
    78 (Earlier implementations had numerical integration issues in some circumstances when orientation distributions passed through 90 degrees, such  
    79 situations, with very broad distributions, should still be approached with care.)  
     78(Earlier implementations had numerical integration issues in some circumstances when orientation distributions passed through 90 degrees, such 
     79situations, with very broad distributions, should still be approached with care.) 
    8080 
    8181Validation 
     
    150150    return 0.5 * (ddd) ** (1. / 3.) 
    151151 
     152def random(): 
     153    import numpy as np 
     154    V = 10**np.random.uniform(5, 12) 
     155    length = 10**np.random.uniform(-2, 2)*V**0.333 
     156    radius = np.sqrt(V/length/np.pi) 
     157    pars = dict( 
     158        #scale=1, 
     159        #background=0, 
     160        length=length, 
     161        radius=radius, 
     162    ) 
     163    return pars 
     164 
     165 
    152166# parameters for demo 
    153167demo = dict(scale=1, background=0, 
  • sasmodels/models/ellipsoid.py

    r404ebbd r31df0c9  
    184184def random(): 
    185185    import numpy as np 
    186     V = 10**np.random.uniform(4, 12) 
     186    V = 10**np.random.uniform(5, 12) 
    187187    radius_polar = 10**np.random.uniform(1.3, 4) 
    188188    radius_equatorial = np.sqrt(V/radius_polar) # ignore 4/3 pi 
    189     Vf = 10**np.random.uniform(-4, -2) 
    190189    pars = dict( 
    191190        #background=0, sld=0, sld_solvent=1, 
    192         scale=1e9*Vf/V, 
    193191        radius_polar=radius_polar, 
    194192        radius_equatorial=radius_equatorial, 
  • sasmodels/models/flexible_cylinder.py

    r42356c8 r31df0c9  
    8686source = ["lib/polevl.c", "lib/sas_J1.c", "lib/wrc_cyl.c", "flexible_cylinder.c"] 
    8787 
    88 demo = dict(scale=1.0, background=0.0001, 
    89             length=1000.0, 
    90             kuhn_length=100.0, 
    91             radius=20.0, 
    92             sld=1.0, 
    93             sld_solvent=6.3) 
     88def random(): 
     89    import numpy as np 
     90    length = 10**np.random.uniform(2, 6) 
     91    radius = 10**np.random.uniform(1, 3) 
     92    kuhn_length = 10**np.random.uniform(-2, -0.7)*length  # at least 10 segments 
     93    pars = dict( 
     94        length=length, 
     95        radius=radius, 
     96        kuhn_length=kuhn_length, 
     97    ) 
     98    return pars 
    9499 
    95100tests = [ 
  • sasmodels/models/flexible_cylinder_elliptical.py

    r40a87fa r31df0c9  
    112112          "flexible_cylinder_elliptical.c"] 
    113113 
    114 demo = dict(scale=1.0, background=0.0001, 
    115             length=1000.0, 
    116             kuhn_length=100.0, 
    117             radius=20.0, 
    118             axis_ratio=1.5, 
    119             sld=1.0, 
    120             sld_solvent=6.3) 
     114def random(): 
     115    import numpy as np 
     116    length = 10**np.random.uniform(2, 6) 
     117    radius = 10**np.random.uniform(1, 3) 
     118    axis_ratio = 10**np.random.uniform(-1, 1) 
     119    kuhn_length = 10**np.random.uniform(-2, -0.7)*length  # at least 10 segments 
     120    pars = dict( 
     121        length=length, 
     122        radius=radius, 
     123        axis_ratio=axis_ratio, 
     124        kuhn_length=kuhn_length, 
     125    ) 
     126    return pars 
    121127 
    122128tests = [ 
  • sasmodels/models/fuzzy_sphere.py

    r925ad6e r31df0c9  
    105105# VR defaults to 1.0 
    106106 
     107def random(): 
     108    import numpy as np 
     109    radius = 10**np.random.uniform(1, 4.7) 
     110    fuzziness = 10**np.random.uniform(-2, -0.5)*radius  # 1% to 31% fuzziness 
     111    pars = dict( 
     112        radius=radius, 
     113        fuzziness=fuzziness, 
     114    ) 
     115    return pars 
     116 
    107117demo = dict(scale=1, background=0.001, 
    108118            sld=1, sld_solvent=3, 
  • sasmodels/models/hollow_cylinder.py

    rf102a96 r31df0c9  
    5454 
    5555* **Author:** NIST IGOR/DANSE **Date:** pre 2010 
    56 * **Last Modified by:** Richard Heenan **Date:** October 06, 2016  
     56* **Last Modified by:** Richard Heenan **Date:** October 06, 2016 
    5757   (reparametrised to use thickness, not outer radius) 
    5858* **Last Reviewed by:** Richard Heenan **Date:** October 06, 2016 
     
    121121    return vol_shell, vol_total 
    122122 
    123 # parameters for demo 
    124 demo = dict(scale=1.0, background=0.0, length=400.0, radius=20.0, 
    125             thickness=10, sld=6.3, sld_solvent=1, theta=90, phi=0, 
    126             thickness_pd=0.2, thickness_pd_n=9, 
    127             length_pd=.2, length_pd_n=10, 
    128             radius_pd=.2, radius_pd_n=9, 
    129             theta_pd=10, theta_pd_n=5, 
    130            ) 
     123def random(): 
     124    import numpy as np 
     125    length = 10**np.random.uniform(2, 6) 
     126    radius = 10**np.random.uniform(1, 3) 
     127    kuhn_length = 10**np.random.uniform(-2, -0.7)*length  # at least 10 segments 
     128    pars = dict( 
     129        length=length, 
     130        radius=radius, 
     131        kuhn_length=kuhn_length, 
     132    ) 
     133    return pars 
     134 
    131135q = 0.1 
    132136# april 6 2017, rkh added a 2d unit test, assume correct! 
  • sasmodels/models/hollow_rectangular_prism.py

    rab2aea8 r31df0c9  
    146146 
    147147 
     148def random(): 
     149    import numpy as np 
     150    a, b, c = 10**np.random.uniform(1, 4.7, size=3) 
     151    thickness = np.random.uniform(0.01, 0.49) * min(a, b, c) 
     152    pars = dict( 
     153        length_a=a, 
     154        b2a_ratio=b/a, 
     155        c2a_ratio=c/a, 
     156        thickness=thickness, 
     157    ) 
     158    return pars 
     159 
     160 
    148161# parameters for demo 
    149162demo = dict(scale=1, background=0, 
  • sasmodels/models/hollow_rectangular_prism_thin_walls.py

    rab2aea8 r31df0c9  
    127127 
    128128 
     129def random(): 
     130    import numpy as np 
     131    a, b, c = 10**np.random.uniform(1, 4.7, size=3) 
     132    pars = dict( 
     133        length_a=a, 
     134        b2a_ratio=b/a, 
     135        c2a_ratio=c/a, 
     136    ) 
     137    return pars 
     138 
     139 
    129140# parameters for demo 
    130141demo = dict(scale=1, background=0, 
  • sasmodels/models/parallelepiped.py

    r34a9e4e r31df0c9  
    2222.. note:: 
    2323 
    24 The three dimensions of the parallelepiped (strictly here a cuboid) may be given in  
     24The three dimensions of the parallelepiped (strictly here a cuboid) may be given in 
    2525$any$ size order. To avoid multiple fit solutions, especially 
    26 with Monte-Carlo fit methods, it may be advisable to restrict their ranges. There may  
    27 be a number of closely similar "best fits", so some trial and error, or fixing of some  
     26with Monte-Carlo fit methods, it may be advisable to restrict their ranges. There may 
     27be a number of closely similar "best fits", so some trial and error, or fixing of some 
    2828dimensions at expected values, may help. 
    2929 
     
    115115 
    116116On introducing "Orientational Distribution" in the angles, "distribution of theta" and "distribution of phi" parameters will 
    117 appear. These are actually rotations about axes $\delta_1$ and $\delta_2$ of the parallelepiped, perpendicular to the $a$ x $c$ and $b$ x $c$ faces.  
    118 (When $\theta = \phi = 0$ these are parallel to the $Y$ and $X$ axes of the instrument.) The third orientation distribution, in $\psi$, is  
    119 about the $c$ axis of the particle, perpendicular to the $a$ x $b$ face. Some experimentation may be required to  
    120 understand the 2d patterns fully. (Earlier implementations had numerical integration issues in some circumstances when orientation  
    121 distributions passed through 90 degrees, such situations, with very broad distributions, should still be approached with care.)  
    122  
    123      
     117appear. These are actually rotations about axes $\delta_1$ and $\delta_2$ of the parallelepiped, perpendicular to the $a$ x $c$ and $b$ x $c$ faces. 
     118(When $\theta = \phi = 0$ these are parallel to the $Y$ and $X$ axes of the instrument.) The third orientation distribution, in $\psi$, is 
     119about the $c$ axis of the particle, perpendicular to the $a$ x $b$ face. Some experimentation may be required to 
     120understand the 2d patterns fully. (Earlier implementations had numerical integration issues in some circumstances when orientation 
     121distributions passed through 90 degrees, such situations, with very broad distributions, should still be approached with care.) 
     122 
     123 
    124124For a given orientation of the parallelepiped, the 2D form factor is 
    125125calculated as 
     
    241241 
    242242# VR defaults to 1.0 
     243 
     244 
     245def random(): 
     246    import numpy as np 
     247    a, b, c = 10**np.random.uniform(1, 4.7, size=3) 
     248    pars = dict( 
     249        length_a=a, 
     250        length_b=b, 
     251        length_c=c, 
     252    ) 
     253    return pars 
     254 
    243255 
    244256# parameters for demo 
  • sasmodels/models/rectangular_prism.py

    rab2aea8 r31df0c9  
    104104              ["length_a", "Ang", 35, [0, inf], "volume", 
    105105               "Shorter side of the parallelepiped"], 
    106               ["b2a_ratio", "Ang", 1, [0, inf], "volume", 
     106              ["b2a_ratio", "", 1, [0, inf], "volume", 
    107107               "Ratio sides b/a"], 
    108               ["c2a_ratio", "Ang", 1, [0, inf], "volume", 
     108              ["c2a_ratio", "", 1, [0, inf], "volume", 
    109109               "Ratio sides c/a"], 
    110110             ] 
     
    125125    return 0.5 * (ddd) ** (1. / 3.) 
    126126 
     127def random(): 
     128    import numpy as np 
     129    a, b, c = 10**np.random.uniform(1, 4.7, size=3) 
     130    pars = dict( 
     131        length_a=a, 
     132        b2a_ratio=b/a, 
     133        c2a_ratio=c/a, 
     134    ) 
     135    return pars 
    127136 
    128137# parameters for demo 
  • sasmodels/models/sphere.py

    r404ebbd r31df0c9  
    8686def random(): 
    8787    import numpy as np 
    88     Vf = 10**np.random.uniform(-4, -2) 
    8988    radius = 10**np.random.uniform(1.3, 4) 
    90     V = radius**3 
    9189    pars = dict( 
    92         #background=0, sld=1, sld_solvent=0, 
    93         scale=1e10*Vf/V, 
    9490        radius=radius, 
    9591    ) 
  • sasmodels/models/triaxial_ellipsoid.py

    r34a9e4e r31df0c9  
    7171small angle diffraction situations there may be a number of closely similar "best fits", 
    7272so some trial and error, or fixing of some radii at expected values, may help. 
    73      
     73 
    7474To provide easy access to the orientation of the triaxial ellipsoid, 
    7575we define the axis of the cylinder using the angles $\theta$, $\phi$ 
     
    7979.. figure:: img/elliptical_cylinder_angle_definition.png 
    8080 
    81     Definition of angles for oriented triaxial ellipsoid, where radii are for illustration here  
     81    Definition of angles for oriented triaxial ellipsoid, where radii are for illustration here 
    8282    $a < b << c$ and angle $\Psi$ is a rotation around the axis of the particle. 
    8383 
    84 For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data,  
     84For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data, 
    8585see the :ref:`elliptical-cylinder` model for further information. 
    8686 
     
    173173    return ellipsoid_ER(polar, equatorial) 
    174174 
     175def random(): 
     176    import numpy as np 
     177    a, b, c = 10**np.random.uniform(1, 4.7, size=3) 
     178    pars = dict( 
     179        radius_equat_minor=a, 
     180        radius_equat_major=b, 
     181        radius_polar=c, 
     182    ) 
     183    return pars 
     184 
     185 
    175186demo = dict(scale=1, background=0, 
    176187            sld=6, sld_solvent=1, 
Note: See TracChangeset for help on using the changeset viewer.