Index: sasmodels/compare.py
===================================================================
--- sasmodels/compare.py	(revision 109d963450953bccdef815502f58134590b1078c)
+++ sasmodels/compare.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -270,4 +270,7 @@
     Randomize a single parameter.
     """
+    # Set the amount of polydispersity/angular dispersion, but by default pd_n
+    # is zero so there is no polydispersity.  This allows us to turn on/off
+    # pd by setting pd_n, and still have randomly generated values
     if name.endswith('_pd'):
         par = model_info.parameters[name[:-3]]
@@ -279,39 +282,56 @@
             return np.random.beta(1.5, 7)
 
+    # pd is selected globally rather than per parameter, so set to 0 for no pd
+    # In particular, when multiple pd dimensions, want to decrease the number
+    # of points per dimension for faster computation
     if name.endswith('_pd_n'):
-        # let pd be selected globally rather than per parameter
         return 0
 
+    # Don't mess with distribution type for now
     if name.endswith('_pd_type'):
-        # Don't mess with distribution type for now
         return 'gaussian'
 
+    # type-dependent value of number of sigmas; for gaussian use 3.
     if name.endswith('_pd_nsigma'):
-        # type-dependent value; for gaussian use 3.
         return 3.
 
+    # background in the range [0.01, 1]
     if name == 'background':
-        return np.random.uniform(0, 1)
-
+        return 10**np.random.uniform(-2, 0)
+
+    # scale defaults to 0.1% to 30% volume fraction
     if name == 'scale':
-        return 10**np.random.uniform(-5,0)
-
+        return 10**np.random.uniform(-3, -0.5)
+
+    # If it is a list of choices, pick one at random with equal probability
+    # In practice, the model specific random generator will override.
     par = model_info.parameters[name]
     if len(par.limits) > 2:  # choice list
         return np.random.randint(len(par.limits))
 
+    # If it is a fixed range, pick from it with equal probability.
+    # For logarithmic ranges, the model will have to override.
     if np.isfinite(par.limits).all():
         return np.random.uniform(*par.limits)
 
+    # If the paramter is marked as an sld use the range of neutron slds
+    # Should be doing something with randomly selected contrast matching
+    # but for now use random contrasts.  Since real data is contrast-matched,
+    # this will favour selection of hollow models when they exist.
     if par.type == 'sld':
         # Range of neutron SLDs
         return np.random.uniform(-0.5, 12)
 
+    # Guess at the random length/radius/thickness.  In practice, all models
+    # are going to set their own reasonable ranges.
     if par.type == 'volume':
         if ('length' in par.name or
                 'radius' in par.name or
                 'thick' in par.name):
-            return 10**np.random.uniform(2,4)
-
+            return 10**np.random.uniform(2, 4)
+
+    # In the absence of any other info, select a value in [0, 2v], or
+    # [-2|v|, 2|v|] if v is negative, or [0, 1] if v is zero.  Mostly the
+    # model random parameter generators will override this default.
     low, high = parameter_range(par.name, value)
     limits = (max(par.limits[0], low), min(par.limits[1], high))
Index: sasmodels/models/barbell.py
===================================================================
--- sasmodels/models/barbell.py	(revision a151caa16f645cbb8ff93c008adabc6d6a7f5136)
+++ sasmodels/models/barbell.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -117,13 +117,21 @@
 def random():
     import numpy as np
+    # TODO: increase volume range once problem with bell radius is fixed
+    # The issue is that bell radii of more than about 200 fail at high q
+    V = 10**np.random.uniform(7, 9)
+    bar_volume = 10**np.random.uniform(-4, -1)*V
+    bell_volume = V - bar_volume
+    bell_radius = (bell_volume/6)**0.3333  # approximate
+    min_bar = bar_volume/np.pi/bell_radius**2
+    bar_length = 10**np.random.uniform(0, 3)*min_bar
+    bar_radius = np.sqrt(bar_volume/bar_length/np.pi)
+    if bar_radius > bell_radius:
+        bell_radius, bar_radius = bar_radius, bell_radius
     pars = dict(
-        scale=10**np.random.uniform(-4,-1),
-        radius_bell=10**np.random.uniform(1.3,3),
-        length=10**np.random.uniform(0,3),
+        #background=0,
+        radius_bell=bell_radius,
+        radius=bar_radius,
+        length=bar_length,
     )
-    pars['radius'] = pars['radius_bell']*np.random.uniform(0,1)
-    if pars['radius_bell'] < 100:
-        pars['length'] *= 10
-        pars['scale'] *= 100
     return pars
 
Index: sasmodels/models/capped_cylinder.py
===================================================================
--- sasmodels/models/capped_cylinder.py	(revision 9802ab3945a154b871264715dcb463d4ec644afa)
+++ sasmodels/models/capped_cylinder.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -80,5 +80,5 @@
 
 .. [#] H Kaya, *J. Appl. Cryst.*, 37 (2004) 223-230
-.. [#] H Kaya and N-R deSouza, *J. Appl. Cryst.*, 37 (2004) 508-509 (addenda 
+.. [#] H Kaya and N-R deSouza, *J. Appl. Cryst.*, 37 (2004) 508-509 (addenda
    and errata)
 
@@ -136,4 +136,26 @@
 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "capped_cylinder.c"]
 
+def random():
+    import numpy as np
+    # TODO: increase volume range once problem with bell radius is fixed
+    # The issue is that bell radii of more than about 200 fail at high q
+    V = 10**np.random.uniform(7, 9)
+    bar_volume = 10**np.random.uniform(-4, -1)*V
+    bell_volume = V - bar_volume
+    bell_radius = (bell_volume/6)**0.3333  # approximate
+    min_bar = bar_volume/np.pi/bell_radius**2
+    bar_length = 10**np.random.uniform(0, 3)*min_bar
+    bar_radius = np.sqrt(bar_volume/bar_length/np.pi)
+    if bar_radius > bell_radius:
+        bell_radius, bar_radius = bar_radius, bell_radius
+    pars = dict(
+        #background=0,
+        radius_cap=bell_radius,
+        radius=bar_radius,
+        length=bar_length,
+    )
+    return pars
+
+
 demo = dict(scale=1, background=0,
             sld=6, sld_solvent=1,
Index: sasmodels/models/core_shell_ellipsoid.py
===================================================================
--- sasmodels/models/core_shell_ellipsoid.py	(revision 9802ab3945a154b871264715dcb463d4ec644afa)
+++ sasmodels/models/core_shell_ellipsoid.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -25,6 +25,6 @@
 ellipsoid. This may have some undesirable effects if the aspect ratio of the
 ellipsoid is large (ie, if $X << 1$ or $X >> 1$ ), when the $S(q)$
-- which assumes spheres - will not in any case be valid.  Generating a 
-custom product model will enable separate effective volume fraction and effective 
+- which assumes spheres - will not in any case be valid.  Generating a
+custom product model will enable separate effective volume fraction and effective
 radius in the $S(q)$.
 
@@ -44,11 +44,11 @@
 
 .. math::
-    \begin{align}    
+    \begin{align}
     F(q,\alpha) = &f(q,radius\_equat\_core,radius\_equat\_core.x\_core,\alpha) \\
     &+ f(q,radius\_equat\_core + thick\_shell,radius\_equat\_core.x\_core + thick\_shell.x\_polar\_shell,\alpha)
-    \end{align} 
+    \end{align}
 
 where
- 
+
 .. math::
 
@@ -77,5 +77,5 @@
    F^2(q)=\int_{0}^{\pi/2}{F^2(q,\alpha)\sin(\alpha)d\alpha}
 
-For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data, 
+For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data,
 see the :ref:`elliptical-cylinder` model for further information.
 
@@ -151,15 +151,23 @@
     return ellipsoid_ER(polar_outer, equat_outer)
 
-
-demo = dict(scale=0.05, background=0.001,
-            radius_equat_core=20.0,
-            x_core=3.0,
-            thick_shell=30.0,
-            x_polar_shell=1.0,
-            sld_core=2.0,
-            sld_shell=1.0,
-            sld_solvent=6.3,
-            theta=0,
-            phi=0)
+def random():
+    import numpy as np
+    V = 10**np.random.uniform(5, 12)
+    radius_polar = 10**np.random.uniform(1.3, 4)
+    radius_equatorial = np.sqrt(V/radius_polar) # ignore 4/3 pi
+    thickness_polar = np.random.uniform(0.01, 1)*radius_polar
+    thickness_equatorial = np.random.uniform(0.01, 1)*radius_equatorial
+    radius_polar -= thickness_polar
+    radius_equatorial -= thickness_equatorial
+    x_core = radius_polar/radius_equatorial
+    x_polar_shell = thickness_polar/thickness_equatorial
+    pars = dict(
+        #background=0, sld=0, sld_solvent=1,
+        radius_equat_core=radius_equatorial,
+        x_core=x_core,
+        thick_shell=thickness_equatorial,
+        x_polar_shell=x_polar_shell,
+    )
+    return pars
 
 q = 0.1
Index: sasmodels/models/core_shell_sphere.py
===================================================================
--- sasmodels/models/core_shell_sphere.py	(revision d49ca5c49995cd41a411c9f9b953a07347f34db1)
+++ sasmodels/models/core_shell_sphere.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -104,7 +104,5 @@
     radius = np.random.uniform(0, 1)*total_radius
     thickness = total_radius - radius
-    Vf = 10**np.random.uniform(4, 6)/total_radius**3
     pars = dict(
-        scale=Vf,
         radius=radius,
         thickness=thickness,
Index: sasmodels/models/cylinder.py
===================================================================
--- sasmodels/models/cylinder.py	(revision 9802ab3945a154b871264715dcb463d4ec644afa)
+++ sasmodels/models/cylinder.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -63,7 +63,7 @@
 .. figure:: img/cylinder_angle_definition.png
 
-    Definition of the $\theta$ and $\phi$ orientation angles for a cylinder relative 
-    to the beam line coordinates, plus an indication of their orientation distributions 
-    which are described as rotations about each of the perpendicular axes $\delta_1$ and $\delta_2$ 
+    Definition of the $\theta$ and $\phi$ orientation angles for a cylinder relative
+    to the beam line coordinates, plus an indication of their orientation distributions
+    which are described as rotations about each of the perpendicular axes $\delta_1$ and $\delta_2$
     in the frame of the cylinder itself, which when $\theta = \phi = 0$ are parallel to the $Y$ and $X$ axes.
 
@@ -72,10 +72,10 @@
     Examples for oriented cylinders.
 
-The $\theta$ and $\phi$ parameters to orient the cylinder only appear in the model when fitting 2d data. 
+The $\theta$ and $\phi$ parameters to orient the cylinder only appear in the model when fitting 2d data.
 On introducing "Orientational Distribution" in the angles, "distribution of theta" and "distribution of phi" parameters will
-appear. These are actually rotations about the axes $\delta_1$ and $\delta_2$ of the cylinder, which when $\theta = \phi = 0$ are parallel 
+appear. These are actually rotations about the axes $\delta_1$ and $\delta_2$ of the cylinder, which when $\theta = \phi = 0$ are parallel
 to the $Y$ and $X$ axes of the instrument respectively. Some experimentation may be required to understand the 2d patterns fully.
-(Earlier implementations had numerical integration issues in some circumstances when orientation distributions passed through 90 degrees, such 
-situations, with very broad distributions, should still be approached with care.) 
+(Earlier implementations had numerical integration issues in some circumstances when orientation distributions passed through 90 degrees, such
+situations, with very broad distributions, should still be approached with care.)
 
 Validation
@@ -150,4 +150,18 @@
     return 0.5 * (ddd) ** (1. / 3.)
 
+def random():
+    import numpy as np
+    V = 10**np.random.uniform(5, 12)
+    length = 10**np.random.uniform(-2, 2)*V**0.333
+    radius = np.sqrt(V/length/np.pi)
+    pars = dict(
+        #scale=1,
+        #background=0,
+        length=length,
+        radius=radius,
+    )
+    return pars
+
+
 # parameters for demo
 demo = dict(scale=1, background=0,
Index: sasmodels/models/ellipsoid.py
===================================================================
--- sasmodels/models/ellipsoid.py	(revision 404ebbd7d77c5752ee99a8b39bf8172dd0c0e551)
+++ sasmodels/models/ellipsoid.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -184,11 +184,9 @@
 def random():
     import numpy as np
-    V = 10**np.random.uniform(4, 12)
+    V = 10**np.random.uniform(5, 12)
     radius_polar = 10**np.random.uniform(1.3, 4)
     radius_equatorial = np.sqrt(V/radius_polar) # ignore 4/3 pi
-    Vf = 10**np.random.uniform(-4, -2)
     pars = dict(
         #background=0, sld=0, sld_solvent=1,
-        scale=1e9*Vf/V,
         radius_polar=radius_polar,
         radius_equatorial=radius_equatorial,
Index: sasmodels/models/flexible_cylinder.py
===================================================================
--- sasmodels/models/flexible_cylinder.py	(revision 42356c8890c04b71169941b12a36fc0e07e2034b)
+++ sasmodels/models/flexible_cylinder.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -86,10 +86,15 @@
 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/wrc_cyl.c", "flexible_cylinder.c"]
 
-demo = dict(scale=1.0, background=0.0001,
-            length=1000.0,
-            kuhn_length=100.0,
-            radius=20.0,
-            sld=1.0,
-            sld_solvent=6.3)
+def random():
+    import numpy as np
+    length = 10**np.random.uniform(2, 6)
+    radius = 10**np.random.uniform(1, 3)
+    kuhn_length = 10**np.random.uniform(-2, -0.7)*length  # at least 10 segments
+    pars = dict(
+        length=length,
+        radius=radius,
+        kuhn_length=kuhn_length,
+    )
+    return pars
 
 tests = [
Index: sasmodels/models/flexible_cylinder_elliptical.py
===================================================================
--- sasmodels/models/flexible_cylinder_elliptical.py	(revision 40a87fa5096610e24c3ead10299f609e99f093f2)
+++ sasmodels/models/flexible_cylinder_elliptical.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -112,11 +112,17 @@
           "flexible_cylinder_elliptical.c"]
 
-demo = dict(scale=1.0, background=0.0001,
-            length=1000.0,
-            kuhn_length=100.0,
-            radius=20.0,
-            axis_ratio=1.5,
-            sld=1.0,
-            sld_solvent=6.3)
+def random():
+    import numpy as np
+    length = 10**np.random.uniform(2, 6)
+    radius = 10**np.random.uniform(1, 3)
+    axis_ratio = 10**np.random.uniform(-1, 1)
+    kuhn_length = 10**np.random.uniform(-2, -0.7)*length  # at least 10 segments
+    pars = dict(
+        length=length,
+        radius=radius,
+        axis_ratio=axis_ratio,
+        kuhn_length=kuhn_length,
+    )
+    return pars
 
 tests = [
Index: sasmodels/models/fuzzy_sphere.py
===================================================================
--- sasmodels/models/fuzzy_sphere.py	(revision 925ad6edca2969db8fb763eb02beee2c5a5f2872)
+++ sasmodels/models/fuzzy_sphere.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -105,4 +105,14 @@
 # VR defaults to 1.0
 
+def random():
+    import numpy as np
+    radius = 10**np.random.uniform(1, 4.7)
+    fuzziness = 10**np.random.uniform(-2, -0.5)*radius  # 1% to 31% fuzziness
+    pars = dict(
+        radius=radius,
+        fuzziness=fuzziness,
+    )
+    return pars
+
 demo = dict(scale=1, background=0.001,
             sld=1, sld_solvent=3,
Index: sasmodels/models/hollow_cylinder.py
===================================================================
--- sasmodels/models/hollow_cylinder.py	(revision f102a968fd7dd1402f915b8638cd66eaf4375710)
+++ sasmodels/models/hollow_cylinder.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -54,5 +54,5 @@
 
 * **Author:** NIST IGOR/DANSE **Date:** pre 2010
-* **Last Modified by:** Richard Heenan **Date:** October 06, 2016 
+* **Last Modified by:** Richard Heenan **Date:** October 06, 2016
    (reparametrised to use thickness, not outer radius)
 * **Last Reviewed by:** Richard Heenan **Date:** October 06, 2016
@@ -121,12 +121,16 @@
     return vol_shell, vol_total
 
-# parameters for demo
-demo = dict(scale=1.0, background=0.0, length=400.0, radius=20.0,
-            thickness=10, sld=6.3, sld_solvent=1, theta=90, phi=0,
-            thickness_pd=0.2, thickness_pd_n=9,
-            length_pd=.2, length_pd_n=10,
-            radius_pd=.2, radius_pd_n=9,
-            theta_pd=10, theta_pd_n=5,
-           )
+def random():
+    import numpy as np
+    length = 10**np.random.uniform(2, 6)
+    radius = 10**np.random.uniform(1, 3)
+    kuhn_length = 10**np.random.uniform(-2, -0.7)*length  # at least 10 segments
+    pars = dict(
+        length=length,
+        radius=radius,
+        kuhn_length=kuhn_length,
+    )
+    return pars
+
 q = 0.1
 # april 6 2017, rkh added a 2d unit test, assume correct!
Index: sasmodels/models/hollow_rectangular_prism.py
===================================================================
--- sasmodels/models/hollow_rectangular_prism.py	(revision ab2aea81f7fb392e5f24f1c76dd989914d8f7022)
+++ sasmodels/models/hollow_rectangular_prism.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -146,4 +146,17 @@
 
 
+def random():
+    import numpy as np
+    a, b, c = 10**np.random.uniform(1, 4.7, size=3)
+    thickness = np.random.uniform(0.01, 0.49) * min(a, b, c)
+    pars = dict(
+        length_a=a,
+        b2a_ratio=b/a,
+        c2a_ratio=c/a,
+        thickness=thickness,
+    )
+    return pars
+
+
 # parameters for demo
 demo = dict(scale=1, background=0,
Index: sasmodels/models/hollow_rectangular_prism_thin_walls.py
===================================================================
--- sasmodels/models/hollow_rectangular_prism_thin_walls.py	(revision ab2aea81f7fb392e5f24f1c76dd989914d8f7022)
+++ sasmodels/models/hollow_rectangular_prism_thin_walls.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -127,4 +127,15 @@
 
 
+def random():
+    import numpy as np
+    a, b, c = 10**np.random.uniform(1, 4.7, size=3)
+    pars = dict(
+        length_a=a,
+        b2a_ratio=b/a,
+        c2a_ratio=c/a,
+    )
+    return pars
+
+
 # parameters for demo
 demo = dict(scale=1, background=0,
Index: sasmodels/models/parallelepiped.py
===================================================================
--- sasmodels/models/parallelepiped.py	(revision 34a9e4eed11f1952a0e9680cbfbdbfa79e7cffe3)
+++ sasmodels/models/parallelepiped.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -22,8 +22,8 @@
 .. note::
 
-The three dimensions of the parallelepiped (strictly here a cuboid) may be given in 
+The three dimensions of the parallelepiped (strictly here a cuboid) may be given in
 $any$ size order. To avoid multiple fit solutions, especially
-with Monte-Carlo fit methods, it may be advisable to restrict their ranges. There may 
-be a number of closely similar "best fits", so some trial and error, or fixing of some 
+with Monte-Carlo fit methods, it may be advisable to restrict their ranges. There may
+be a number of closely similar "best fits", so some trial and error, or fixing of some
 dimensions at expected values, may help.
 
@@ -115,11 +115,11 @@
 
 On introducing "Orientational Distribution" in the angles, "distribution of theta" and "distribution of phi" parameters will
-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. 
-(When $\theta = \phi = 0$ these are parallel to the $Y$ and $X$ axes of the instrument.) The third orientation distribution, in $\psi$, is 
-about the $c$ axis of the particle, perpendicular to the $a$ x $b$ face. Some experimentation may be required to 
-understand the 2d patterns fully. (Earlier implementations had numerical integration issues in some circumstances when orientation 
-distributions passed through 90 degrees, such situations, with very broad distributions, should still be approached with care.) 
-
-    
+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.
+(When $\theta = \phi = 0$ these are parallel to the $Y$ and $X$ axes of the instrument.) The third orientation distribution, in $\psi$, is
+about the $c$ axis of the particle, perpendicular to the $a$ x $b$ face. Some experimentation may be required to
+understand the 2d patterns fully. (Earlier implementations had numerical integration issues in some circumstances when orientation
+distributions passed through 90 degrees, such situations, with very broad distributions, should still be approached with care.)
+
+
 For a given orientation of the parallelepiped, the 2D form factor is
 calculated as
@@ -241,4 +241,16 @@
 
 # VR defaults to 1.0
+
+
+def random():
+    import numpy as np
+    a, b, c = 10**np.random.uniform(1, 4.7, size=3)
+    pars = dict(
+        length_a=a,
+        length_b=b,
+        length_c=c,
+    )
+    return pars
+
 
 # parameters for demo
Index: sasmodels/models/rectangular_prism.py
===================================================================
--- sasmodels/models/rectangular_prism.py	(revision ab2aea81f7fb392e5f24f1c76dd989914d8f7022)
+++ sasmodels/models/rectangular_prism.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -104,7 +104,7 @@
               ["length_a", "Ang", 35, [0, inf], "volume",
                "Shorter side of the parallelepiped"],
-              ["b2a_ratio", "Ang", 1, [0, inf], "volume",
+              ["b2a_ratio", "", 1, [0, inf], "volume",
                "Ratio sides b/a"],
-              ["c2a_ratio", "Ang", 1, [0, inf], "volume",
+              ["c2a_ratio", "", 1, [0, inf], "volume",
                "Ratio sides c/a"],
              ]
@@ -125,4 +125,13 @@
     return 0.5 * (ddd) ** (1. / 3.)
 
+def random():
+    import numpy as np
+    a, b, c = 10**np.random.uniform(1, 4.7, size=3)
+    pars = dict(
+        length_a=a,
+        b2a_ratio=b/a,
+        c2a_ratio=c/a,
+    )
+    return pars
 
 # parameters for demo
Index: sasmodels/models/sphere.py
===================================================================
--- sasmodels/models/sphere.py	(revision 404ebbd7d77c5752ee99a8b39bf8172dd0c0e551)
+++ sasmodels/models/sphere.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -86,10 +86,6 @@
 def random():
     import numpy as np
-    Vf = 10**np.random.uniform(-4, -2)
     radius = 10**np.random.uniform(1.3, 4)
-    V = radius**3
     pars = dict(
-        #background=0, sld=1, sld_solvent=0,
-        scale=1e10*Vf/V,
         radius=radius,
     )
Index: sasmodels/models/triaxial_ellipsoid.py
===================================================================
--- sasmodels/models/triaxial_ellipsoid.py	(revision 34a9e4eed11f1952a0e9680cbfbdbfa79e7cffe3)
+++ sasmodels/models/triaxial_ellipsoid.py	(revision 31df0c91cf57174acd8e9cbe5f9caadffdc880ba)
@@ -71,5 +71,5 @@
 small angle diffraction situations there may be a number of closely similar "best fits",
 so some trial and error, or fixing of some radii at expected values, may help.
-    
+
 To provide easy access to the orientation of the triaxial ellipsoid,
 we define the axis of the cylinder using the angles $\theta$, $\phi$
@@ -79,8 +79,8 @@
 .. figure:: img/elliptical_cylinder_angle_definition.png
 
-    Definition of angles for oriented triaxial ellipsoid, where radii are for illustration here 
+    Definition of angles for oriented triaxial ellipsoid, where radii are for illustration here
     $a < b << c$ and angle $\Psi$ is a rotation around the axis of the particle.
 
-For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data, 
+For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data,
 see the :ref:`elliptical-cylinder` model for further information.
 
@@ -173,4 +173,15 @@
     return ellipsoid_ER(polar, equatorial)
 
+def random():
+    import numpy as np
+    a, b, c = 10**np.random.uniform(1, 4.7, size=3)
+    pars = dict(
+        radius_equat_minor=a,
+        radius_equat_major=b,
+        radius_polar=c,
+    )
+    return pars
+
+
 demo = dict(scale=1, background=0,
             sld=6, sld_solvent=1,
