Index: sasmodels/models/barbell.c
===================================================================
--- sasmodels/models/barbell.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/barbell.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -62,4 +62,32 @@
 }
 
+static double
+radius_from_volume(double radius_bell, double radius, double length)
+{
+    const double vol_barbell = form_volume(radius_bell,radius,length);
+    return cbrt(0.75*vol_barbell/M_PI);
+}
+
+static double
+radius_from_totallength(double radius_bell, double radius, double length)
+{
+    const double hdist = sqrt(square(radius_bell) - square(radius));
+    return 0.5*length + hdist + radius_bell;
+}
+
+static double
+effective_radius(int mode, double radius_bell, double radius, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(radius_bell, radius , length);
+    } else if (mode == 2) {
+        return radius;
+    } else if (mode == 3) {
+        return 0.5*length;
+    } else {
+        return radius_from_totallength(radius_bell,radius,length);
+    }
+}
+
 static void
 Fq(double q,double *F1, double *F2, double sld, double solvent_sld,
Index: sasmodels/models/barbell.py
===================================================================
--- sasmodels/models/barbell.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/barbell.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -117,4 +117,5 @@
 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "barbell.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","radius","half length","half total length"]
 
 def random():
Index: sasmodels/models/capped_cylinder.c
===================================================================
--- sasmodels/models/capped_cylinder.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/capped_cylinder.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -84,4 +84,32 @@
 }
 
+static double
+radius_from_volume(double radius, double radius_cap, double length)
+{
+    const double vol_cappedcyl = form_volume(radius,radius_cap,length);
+    return cbrt(0.75*vol_cappedcyl/M_PI);
+}
+
+static double
+radius_from_totallength(double radius, double radius_cap, double length)
+{
+    const double hc = radius_cap - sqrt(radius_cap*radius_cap - radius*radius);
+    return 0.5*length + hc;
+}
+
+static double
+effective_radius(int mode, double radius, double radius_cap, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(radius, radius_cap, length);
+    } else if (mode == 2) {
+        return radius;
+    } else if (mode == 3) {
+        return 0.5*length;
+    } else {
+        return radius_from_totallength(radius, radius_cap,length);
+    }
+}
+
 static void
 Fq(double q,double *F1, double *F2, double sld, double solvent_sld,
Index: sasmodels/models/capped_cylinder.py
===================================================================
--- sasmodels/models/capped_cylinder.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/capped_cylinder.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -137,4 +137,5 @@
 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "capped_cylinder.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","radius","half length","half total length"]
 
 def random():
Index: sasmodels/models/core_multi_shell.c
===================================================================
--- sasmodels/models/core_multi_shell.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_multi_shell.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -19,4 +19,31 @@
 }
 
+static double
+outer_radius(double core_radius, double fp_n, double thickness[])
+{
+  double r = core_radius;
+  int n = (int)(fp_n+0.5);
+  for (int i=0; i < n; i++) {
+    r += thickness[i];
+  }
+  return r;
+}
+
+static double
+effective_radius(int mode, double core_radius, double fp_n, double thickness[])
+{
+    if (mode == 1) {
+        double r = core_radius;
+        int n = (int)(fp_n+0.5);
+        for (int i=0; i < n; i++) {
+            r += thickness[i];
+        }
+        return r;
+        //return outer_radius(core_radius,fp_n,thickness);
+    } else {
+        return core_radius;
+    }
+}
+
 static void
 Fq(double q, double *F1, double *F2, double core_sld, double core_radius,
Index: sasmodels/models/core_multi_shell.py
===================================================================
--- sasmodels/models/core_multi_shell.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_multi_shell.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -100,4 +100,5 @@
 source = ["lib/sas_3j1x_x.c", "core_multi_shell.c"]
 have_Fq = True
+effective_radius_type = ["outer radius", "core radius"]
 
 def random():
@@ -144,8 +145,8 @@
     return np.asarray(z), np.asarray(rho)
 
-def ER(radius, n, thickness):
-    """Effective radius"""
-    n = int(n[0]+0.5)  # n is a control parameter and is not polydisperse
-    return np.sum(thickness[:n], axis=0) + radius
+#def ER(radius, n, thickness):
+#    """Effective radius"""
+#    n = int(n[0]+0.5)  # n is a control parameter and is not polydisperse
+#    return np.sum(thickness[:n], axis=0) + radius
 
 demo = dict(sld_core=6.4,
Index: sasmodels/models/core_shell_bicelle.c
===================================================================
--- sasmodels/models/core_shell_bicelle.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_bicelle.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -34,4 +34,33 @@
 
     return t;
+}
+
+static double
+radius_from_volume(double radius, double thick_rim, double thick_face, double length)
+{
+    const double volume_bicelle = form_volume(radius,thick_rim,thick_face,length);
+    return cbrt(0.75*volume_bicelle/M_PI);
+}
+
+static double
+radius_from_diagonal(double radius, double thick_rim, double thick_face, double length)
+{
+    const double radius_tot = radius + thick_rim;
+    const double length_tot = length + 2.0*thick_face;
+    return sqrt(radius_tot*radius_tot + 0.25*length_tot*length_tot);
+}
+
+static double
+effective_radius(int mode, double radius, double thick_rim, double thick_face, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(radius, thick_rim, thick_face, length);
+    } else if (mode == 2) {
+        return radius + thick_rim;
+    } else if (mode == 3) {
+        return 0.5*length + thick_face;
+    } else {
+        return radius_from_diagonal(radius,thick_rim,thick_face,length);
+    }
 }
 
Index: sasmodels/models/core_shell_bicelle.py
===================================================================
--- sasmodels/models/core_shell_bicelle.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_bicelle.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -155,4 +155,5 @@
           "core_shell_bicelle.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","outer rim radius", "half outer thickness","half diagonal"]
 
 def random():
Index: sasmodels/models/core_shell_bicelle_elliptical.c
===================================================================
--- sasmodels/models/core_shell_bicelle_elliptical.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_bicelle_elliptical.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -8,4 +8,38 @@
 {
     return M_PI*(r_minor+thick_rim)*(r_minor*x_core+thick_rim)*(length+2.0*thick_face);
+}
+
+static double
+radius_from_volume(double r_minor, double x_core, double thick_rim, double thick_face, double length)
+{
+    const double volume_bicelle = form_volume(r_minor, x_core, thick_rim,thick_face,length);
+    return cbrt(0.75*volume_bicelle/M_PI);
+}
+
+static double
+radius_from_diagonal(double r_minor, double x_core, double thick_rim, double thick_face, double length)
+{
+    const double radius_max = (x_core < 1.0 ? r_minor : x_core*r_minor);
+    const double radius_max_tot = radius_max + thick_rim;
+    const double length_tot = length + 2.0*thick_face;
+    return sqrt(radius_max_tot*radius_max_tot + 0.25*length_tot*length_tot);
+}
+
+static double
+effective_radius(int mode, double r_minor, double x_core, double thick_rim, double thick_face, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(r_minor, x_core, thick_rim, thick_face, length);
+    } else if (mode == 2) {
+        return 0.5*r_minor*(1.0 + x_core) + thick_rim;
+    } else if (mode == 3) {
+        return (x_core < 1.0 ? x_core*r_minor+thick_rim : r_minor+thick_rim);
+    } else if (mode == 4) {
+        return (x_core > 1.0 ? x_core*r_minor+thick_rim : r_minor+thick_rim);
+    } else if (mode ==5) {
+        return 0.5*length + thick_face;
+    } else {
+        return radius_from_diagonal(r_minor,x_core,thick_rim,thick_face,length);
+    }
 }
 
Index: sasmodels/models/core_shell_bicelle_elliptical.py
===================================================================
--- sasmodels/models/core_shell_bicelle_elliptical.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_bicelle_elliptical.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -147,4 +147,6 @@
           "core_shell_bicelle_elliptical.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","outer rim average radius","outer rim min radius",
+                         "outer max radius", "half outer thickness","half diagonal"]
 
 def random():
Index: sasmodels/models/core_shell_bicelle_elliptical_belt_rough.c
===================================================================
--- sasmodels/models/core_shell_bicelle_elliptical_belt_rough.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_bicelle_elliptical_belt_rough.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -9,4 +9,38 @@
     return M_PI*(  (r_minor + thick_rim)*(r_minor*x_core + thick_rim)* length +
                  square(r_minor)*x_core*2.0*thick_face  );
+}
+
+static double
+radius_from_volume(double r_minor, double x_core, double thick_rim, double thick_face, double length)
+{
+    const double volume_bicelle = form_volume(r_minor, x_core, thick_rim,thick_face,length);
+    return cbrt(0.75*volume_bicelle/M_PI);
+}
+
+static double
+radius_from_diagonal(double r_minor, double x_core, double thick_rim, double thick_face, double length)
+{
+    const double radius_max = (x_core < 1.0 ? r_minor : x_core*r_minor);
+    const double radius_max_tot = radius_max + thick_rim;
+    const double length_tot = length + 2.0*thick_face;
+    return sqrt(radius_max_tot*radius_max_tot + 0.25*length_tot*length_tot);
+}
+
+static double
+effective_radius(int mode, double r_minor, double x_core, double thick_rim, double thick_face, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(r_minor, x_core, thick_rim, thick_face, length);
+    } else if (mode == 2) {
+        return 0.5*r_minor*(1.0 + x_core) + thick_rim;
+    } else if (mode == 3) {
+        return (x_core < 1.0 ? x_core*r_minor+thick_rim : r_minor+thick_rim);
+    } else if (mode == 4) {
+        return (x_core > 1.0 ? x_core*r_minor+thick_rim : r_minor+thick_rim);
+    } else if (mode ==5) {
+        return 0.5*length + thick_face;
+    } else {
+        return radius_from_diagonal(r_minor,x_core,thick_rim,thick_face,length);
+    }
 }
 
Index: sasmodels/models/core_shell_bicelle_elliptical_belt_rough.py
===================================================================
--- sasmodels/models/core_shell_bicelle_elliptical_belt_rough.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_bicelle_elliptical_belt_rough.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -160,4 +160,6 @@
           "core_shell_bicelle_elliptical_belt_rough.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","outer rim average radius","outer rim min radius",
+                         "outer max radius", "half outer thickness","half diagonal"]
 
 demo = dict(scale=1, background=0,
Index: sasmodels/models/core_shell_cylinder.c
===================================================================
--- sasmodels/models/core_shell_cylinder.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_cylinder.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -11,4 +11,37 @@
 {
     return M_PI*square(radius+thickness)*(length+2.0*thickness);
+}
+
+static double
+radius_from_volume(double radius, double thickness, double length)
+{
+    const double volume_outer_cyl = form_volume(radius,thickness,length);
+    return cbrt(0.75*volume_outer_cyl/M_PI);
+}
+
+static double
+radius_from_diagonal(double radius, double thickness, double length)
+{
+    const double radius_outer = radius + thickness;
+    const double length_outer = length + thickness;
+    return sqrt(radius_outer*radius_outer + 0.25*length_outer*length_outer);
+}
+
+static double
+effective_radius(int mode, double radius, double thickness, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(radius, thickness, length);
+    } else if (mode == 2) {
+        return radius + thickness;
+    } else if (mode == 3) {
+        return 0.5*length + thickness;
+    } else if (mode == 4) {
+        return (radius < 0.5*length ? radius + thickness : 0.5*length + thickness);
+    } else if (mode == 5) {
+        return (radius > 0.5*length ? radius + thickness : 0.5*length + thickness);
+    } else {
+        return radius_from_diagonal(radius,thickness,length);
+    }
 }
 
Index: sasmodels/models/core_shell_cylinder.py
===================================================================
--- sasmodels/models/core_shell_cylinder.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_cylinder.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -126,13 +126,15 @@
 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "core_shell_cylinder.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","outer radius","half outer length","half min outer dimension",
+                         "half max outer dimension","half outer diagonal"]
 
-def ER(radius, thickness, length):
-    """
-    Returns the effective radius used in the S*P calculation
-    """
-    radius = radius + thickness
-    length = length + 2 * thickness
-    ddd = 0.75 * radius * (2 * radius * length + (length + radius) * (length + pi * radius))
-    return 0.5 * (ddd) ** (1. / 3.)
+#def ER(radius, thickness, length):
+#    """
+#    Returns the effective radius used in the S*P calculation
+#    """
+#    radius = radius + thickness
+#    length = length + 2 * thickness
+#    ddd = 0.75 * radius * (2 * radius * length + (length + radius) * (length + pi * radius))
+#    return 0.5 * (ddd) ** (1. / 3.)
 
 def VR(radius, thickness, length):
Index: sasmodels/models/core_shell_ellipsoid.c
===================================================================
--- sasmodels/models/core_shell_ellipsoid.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_ellipsoid.c	(revision 3c60146f44ec3507ebbe0e1e7c740546e003f5b2)
@@ -36,4 +36,50 @@
     double vol = M_4PI_3*equat_shell*equat_shell*polar_shell;
     return vol;
+}
+
+static double
+radius_from_volume(double radius_equat_core, double x_core, double thick_shell, double x_polar_shell)
+{
+    const double volume_ellipsoid = form_volume(radius_equat_core, x_core, thick_shell, x_polar_shell);
+    return cbrt(0.75*volume_ellipsoid/M_PI);
+}
+
+static double
+radius_from_curvature(double radius_equat_core, double x_core, double thick_shell, double x_polar_shell)
+{
+    // Trivial cases
+    if (1.0 == x_core && 1.0 == x_polar_shell) return radius_equat_core + thick_shell;
+    if ((radius_equat_core + thick_shell)*(radius_equat_core*x_core + thick_shell*x_polar_shell) == 0.)  return 0.;
+
+    // see equation (26) in A.Isihara, J.Chem.Phys. 18(1950)1446-1449
+    const double radius_equat_tot = radius_equat_core + thick_shell;
+    const double radius_polar_tot = radius_equat_core*x_core + thick_shell*x_polar_shell;
+    const double ratio = (radius_polar_tot < radius_equat_tot
+                          ? radius_polar_tot / radius_equat_tot
+                          : radius_equat_tot / radius_polar_tot);
+    const double e1 = sqrt(1.0 - ratio*ratio);
+    const double b1 = 1.0 + asin(e1) / (e1 * ratio);
+    const double bL = (1.0 + e1) / (1.0 - e1);
+    const double b2 = 1.0 + 0.5 * ratio * ratio / e1 * log(bL);
+    const double delta = 0.75 * b1 * b2;
+    const double ddd = 2.0 * (delta + 1.0) * radius_polar_tot * radius_equat_tot * radius_equat_tot;
+    return 0.5 * cbrt(ddd);
+}
+
+static double
+effective_radius(int mode, double radius_equat_core, double x_core, double thick_shell, double x_polar_shell)
+{
+    const double radius_equat_tot = radius_equat_core + thick_shell;
+    const double radius_polar_tot = radius_equat_core*x_core + thick_shell*x_polar_shell;
+
+    if (mode == 1) {
+        return radius_from_volume(radius_equat_core, x_core, thick_shell, x_polar_shell);
+    } else if (mode == 2) {
+        return radius_from_curvature(radius_equat_core, x_core, thick_shell, x_polar_shell);
+    } else if (mode == 3) {
+        return (radius_polar_tot < radius_equat_tot ? radius_polar_tot : radius_equat_tot);
+    } else {
+        return (radius_polar_tot > radius_equat_tot ? radius_polar_tot : radius_equat_tot);
+    }
 }
 
Index: sasmodels/models/core_shell_ellipsoid.py
===================================================================
--- sasmodels/models/core_shell_ellipsoid.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_ellipsoid.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -146,13 +146,14 @@
 source = ["lib/sas_3j1x_x.c", "lib/gauss76.c", "core_shell_ellipsoid.c"]
 have_Fq = True
-
-def ER(radius_equat_core, x_core, thick_shell, x_polar_shell):
-    """
-        Returns the effective radius used in the S*P calculation
-    """
-    from .ellipsoid import ER as ellipsoid_ER
-    polar_outer = radius_equat_core*x_core + thick_shell*x_polar_shell
-    equat_outer = radius_equat_core + thick_shell
-    return ellipsoid_ER(polar_outer, equat_outer)
+effective_radius_type = ["equivalent sphere","average outer curvature", "min outer radius", "max outer radius"]
+
+#def ER(radius_equat_core, x_core, thick_shell, x_polar_shell):
+#    """
+#        Returns the effective radius used in the S*P calculation
+#    """
+#    from .ellipsoid import ER as ellipsoid_ER
+#    polar_outer = radius_equat_core*x_core + thick_shell*x_polar_shell
+#    equat_outer = radius_equat_core + thick_shell
+#    return ellipsoid_ER(polar_outer, equat_outer)
 
 def random():
Index: sasmodels/models/core_shell_parallelepiped.c
===================================================================
--- sasmodels/models/core_shell_parallelepiped.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_parallelepiped.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -25,4 +25,40 @@
         2.0 * length_a * length_b * thick_rim_c;
 #endif
+}
+
+static double
+radius_from_volume(double length_a, double length_b, double length_c,
+                   double thick_rim_a, double thick_rim_b, double thick_rim_c)
+{
+    const double volume_paral = form_volume(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c);
+    return cbrt(0.75*volume_paral/M_PI);
+}
+
+static double
+radius_from_crosssection(double length_a, double length_b, double thick_rim_a, double thick_rim_b)
+{
+    const double area_xsec_paral = length_a*length_b + 2.0*thick_rim_a*length_b + 2.0*thick_rim_b*length_a;
+    return sqrt(area_xsec_paral/M_PI);
+}
+
+static double
+effective_radius(int mode, double length_a, double length_b, double length_c,
+                 double thick_rim_a, double thick_rim_b, double thick_rim_c)
+{
+    if (mode == 1) {
+        return radius_from_volume(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c);
+    } else if (mode == 2) {
+        return 0.5 * (length_a + thick_rim_a);
+    } else if (mode == 3) {
+        return 0.5 * (length_b + thick_rim_b);
+    } else if (mode == 4) {
+        return 0.5 * (length_c + thick_rim_c);
+    } else if (mode == 5) {
+        return radius_from_crosssection(length_a, length_b, thick_rim_a, thick_rim_b);
+    } else if (mode == 6) {
+        return 0.5*sqrt(square(length_a+thick_rim_a) + square(length_b+thick_rim_b));
+    } else {
+        return 0.5*sqrt(square(length_a+thick_rim_a) + square(length_b+thick_rim_b) + square(length_c+thick_rim_c));
+    }
 }
 
Index: sasmodels/models/core_shell_parallelepiped.py
===================================================================
--- sasmodels/models/core_shell_parallelepiped.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_parallelepiped.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -227,16 +227,17 @@
 source = ["lib/gauss76.c", "core_shell_parallelepiped.c"]
 have_Fq = True
-
-
-def ER(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c):
-    """
-        Return equivalent radius (ER)
-    """
-    from .parallelepiped import ER as ER_p
-
-    a = length_a + 2*thick_rim_a
-    b = length_b + 2*thick_rim_b
-    c = length_c + 2*thick_rim_c
-    return ER_p(a, b, c)
+effective_radius_type = ["equivalent sphere","half outer length_a", "half outer length_b", "half outer length_c",
+                         "equivalent circular cross-section","half outer ab diagonal","half outer diagonal"]
+
+#def ER(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c):
+#    """
+#        Return equivalent radius (ER)
+#    """
+#    from .parallelepiped import ER as ER_p
+#
+#    a = length_a + 2*thick_rim_a
+#    b = length_b + 2*thick_rim_b
+#    c = length_c + 2*thick_rim_c
+#    return ER_p(a, b, c)
 
 # VR defaults to 1.0
Index: sasmodels/models/core_shell_sphere.c
===================================================================
--- sasmodels/models/core_shell_sphere.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_sphere.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -3,4 +3,14 @@
 {
     return M_4PI_3 * cube(radius + thickness);
+}
+
+static double
+effective_radius(int mode, double radius, double thickness)
+{
+    if (mode == 1) {
+        return radius + thickness;
+    } else {
+        return radius;
+    }
 }
 
Index: sasmodels/models/core_shell_sphere.py
===================================================================
--- sasmodels/models/core_shell_sphere.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/core_shell_sphere.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -78,15 +78,16 @@
 source = ["lib/sas_3j1x_x.c", "lib/core_shell.c", "core_shell_sphere.c"]
 have_Fq = True
+effective_radius_type = ["outer radius", "core radius"]
 
 demo = dict(scale=1, background=0, radius=60, thickness=10,
             sld_core=1.0, sld_shell=2.0, sld_solvent=0.0)
 
-def ER(radius, thickness):
-    """
-        Equivalent radius
-        @param radius: core radius
-        @param thickness: shell thickness
-    """
-    return radius + thickness
+#def ER(radius, thickness):
+#    """
+#        Equivalent radius
+#        @param radius: core radius
+#        @param thickness: shell thickness
+#    """
+#    return radius + thickness
 
 def VR(radius, thickness):
Index: sasmodels/models/cylinder.c
===================================================================
--- sasmodels/models/cylinder.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/cylinder.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -11,4 +11,34 @@
 {
     return sas_2J1x_x(qab*radius) * sas_sinx_x(qc*0.5*length);
+}
+
+static double
+radius_from_volume(double radius, double length)
+{
+    return cbrt(0.75*radius*radius*length);
+}
+
+static double
+radius_from_diagonal(double radius, double length)
+{
+    return sqrt(radius*radius + 0.25*length*length);
+}
+
+static double
+effective_radius(int mode, double radius, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(radius, length);
+    } else if (mode == 2) {
+        return radius;
+    } else if (mode == 3) {
+        return 0.5*length;
+    } else if (mode == 4) {
+        return (radius < 0.5*length ? radius : 0.5*length);
+    } else if (mode == 5) {
+        return (radius > 0.5*length ? radius : 0.5*length);
+    } else {
+        return radius_from_diagonal(radius,length);
+    }
 }
 
Index: sasmodels/models/cylinder.py
===================================================================
--- sasmodels/models/cylinder.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/cylinder.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -139,11 +139,12 @@
 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "cylinder.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","radius","half length","half min dimension","half max dimension","half diagonal"]
 
-def ER(radius, length):
-    """
-        Return equivalent radius (ER)
-    """
-    ddd = 0.75 * radius * (2 * radius * length + (length + radius) * (length + pi * radius))
-    return 0.5 * (ddd) ** (1. / 3.)
+#def ER(radius, length):
+#    """
+#        Return equivalent radius (ER)
+#    """
+#    ddd = 0.75 * radius * (2 * radius * length + (length + radius) * (length + pi * radius))
+#    return 0.5 * (ddd) ** (1. / 3.)
 
 def random():
Index: sasmodels/models/ellipsoid.c
===================================================================
--- sasmodels/models/ellipsoid.c	(revision 6e7ba14b7bd7549d79f388fe396c80945675b80b)
+++ sasmodels/models/ellipsoid.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -4,5 +4,4 @@
     return M_4PI_3*radius_polar*radius_equatorial*radius_equatorial;
 }
-
 
 static double
@@ -20,5 +19,5 @@
 
     // see equation (26) in A.Isihara, J.Chem.Phys. 18(1950)1446-1449
-    const double ratio = (radius_polar < radius_equatorial 
+    const double ratio = (radius_polar < radius_equatorial
                           ? radius_polar / radius_equatorial
                           : radius_equatorial / radius_polar);
@@ -36,7 +35,7 @@
 {
     if (mode == 1) {
+        return radius_from_volume(radius_polar, radius_equatorial);
+    } else if (mode == 2) {
         return radius_from_curvature(radius_polar, radius_equatorial);
-    } else if (mode == 2) {
-        return radius_from_volume(radius_polar, radius_equatorial);
     } else if (mode == 3) {
         return (radius_polar < radius_equatorial ? radius_polar : radius_equatorial);
Index: sasmodels/models/ellipsoid.py
===================================================================
--- sasmodels/models/ellipsoid.py	(revision 6e7ba14b7bd7549d79f388fe396c80945675b80b)
+++ sasmodels/models/ellipsoid.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -164,5 +164,5 @@
 source = ["lib/sas_3j1x_x.c", "lib/gauss76.c", "ellipsoid.c"]
 have_Fq = True
-effective_radius_type = ["average curvature", "equivalent sphere", "min radius", "max radius"]
+effective_radius_type = ["equivalent sphere","average curvature", "min radius", "max radius"]
 
 def random():
Index: sasmodels/models/elliptical_cylinder.c
===================================================================
--- sasmodels/models/elliptical_cylinder.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/elliptical_cylinder.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -3,4 +3,56 @@
 {
     return M_PI * radius_minor * radius_minor * r_ratio * length;
+}
+
+static double
+radius_from_volume(double radius_minor, double r_ratio, double length)
+{
+    const double volume_ellcyl = form_volume(radius_minor,r_ratio,length);
+    return cbrt(0.75*volume_ellcyl/M_PI);
+}
+
+static double
+radius_from_min_dimension(double radius_minor, double r_ratio, double length)
+{
+    const double rad_min = (r_ratio > 1.0 ? radius_minor : r_ratio*radius_minor);
+    return (rad_min < length ? rad_min : length);
+}
+
+static double
+radius_from_max_dimension(double radius_minor, double r_ratio, double length)
+{
+    const double rad_max = (r_ratio < 1.0 ? radius_minor : r_ratio*radius_minor);
+    return (rad_max > length ? rad_max : length);
+}
+
+static double
+radius_from_diagonal(double radius_minor, double r_ratio, double length)
+{
+    const double radius_max = (r_ratio > 1.0 ? radius_minor*r_ratio : radius_minor);
+    return sqrt(radius_max*radius_max + 0.25*length*length);
+}
+
+static double
+effective_radius(int mode, double radius_minor, double r_ratio, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(radius_minor, r_ratio, length);
+    } else if (mode == 2) {
+        return 0.5*radius_minor*(1.0 + r_ratio);
+    } else if (mode == 3) {
+        return (r_ratio > 1.0 ? radius_minor : r_ratio*radius_minor);
+    } else if (mode == 4) {
+        return (r_ratio < 1.0 ? radius_minor : r_ratio*radius_minor);
+    } else if (mode == 5) {
+        return sqrt(radius_minor*radius_minor*r_ratio);
+    } else if (mode == 6) {
+        return 0.5*length;
+    } else if (mode == 7) {
+        return radius_from_min_dimension(radius_minor,r_ratio,length);
+    } else if (mode == 8) {
+        return radius_from_max_dimension(radius_minor,r_ratio,length);
+    } else {
+        return radius_from_diagonal(radius_minor,r_ratio,length);
+    }
 }
 
Index: sasmodels/models/elliptical_cylinder.py
===================================================================
--- sasmodels/models/elliptical_cylinder.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/elliptical_cylinder.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -123,4 +123,6 @@
 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "elliptical_cylinder.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","average radius","min radius","max radius",
+                         "equivalent circular cross-section","half length","half min dimension","half max dimension","half diagonal"]
 
 demo = dict(scale=1, background=0, radius_minor=100, axis_ratio=1.5, length=400.0,
@@ -128,15 +130,15 @@
             theta_pd=10, phi_pd=2, psi_pd=3)
 
-def ER(radius_minor, axis_ratio, length):
-    """
-        Equivalent radius
-        @param radius_minor: Ellipse minor radius
-        @param axis_ratio: Ratio of major radius over minor radius
-        @param length: Length of the cylinder
-    """
-    radius = sqrt(radius_minor * radius_minor * axis_ratio)
-    ddd = 0.75 * radius * (2 * radius * length
-                           + (length + radius) * (length + pi * radius))
-    return 0.5 * (ddd) ** (1. / 3.)
+#def ER(radius_minor, axis_ratio, length):
+#    """
+#        Equivalent radius
+#        @param radius_minor: Ellipse minor radius
+#        @param axis_ratio: Ratio of major radius over minor radius
+#        @param length: Length of the cylinder
+#    """
+#    radius = sqrt(radius_minor * radius_minor * axis_ratio)
+#    ddd = 0.75 * radius * (2 * radius * length
+#                           + (length + radius) * (length + pi * radius))
+#    return 0.5 * (ddd) ** (1. / 3.)
 
 def random():
Index: sasmodels/models/fuzzy_sphere.c
===================================================================
--- sasmodels/models/fuzzy_sphere.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
+++ sasmodels/models/fuzzy_sphere.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -0,0 +1,26 @@
+static double form_volume(double radius, double fuzziness)
+{
+    return M_4PI_3*cube(radius);
+}
+
+static double
+effective_radius(int mode, double radius, double fuzziness)
+{
+    if (mode == 1) {
+        return radius;
+    } else {
+        return radius + fuzziness;
+    }
+}
+
+static void Fq(double q, double *F1, double *F2, double sld, double sld_solvent,
+               double radius, double fuzziness)
+{
+    const double qr = q*radius;
+    const double bes = sas_3j1x_x(qr);
+    const double qf = exp(-0.5*square(q*fuzziness));
+    const double contrast = (sld - sld_solvent);
+    const double form = contrast * form_volume(radius,fuzziness) * bes * qf;
+    *F1 = 1.0e-2*form;
+    *F2 = 1.0e-4*form*form;
+}
Index: sasmodels/models/fuzzy_sphere.py
===================================================================
--- sasmodels/models/fuzzy_sphere.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/fuzzy_sphere.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -78,35 +78,17 @@
               ["sld_solvent", "1e-6/Ang^2",  3, [-inf, inf], "sld",    "Solvent scattering length density"],
               ["radius",      "Ang",        60, [0, inf],    "volume", "Sphere radius"],
-              ["fuzziness",   "Ang",        10, [0, inf],    "",       "std deviation of Gaussian convolution for interface (must be << radius)"],
+              ["fuzziness",   "Ang",        10, [0, inf],    "volume",       "std deviation of Gaussian convolution for interface (must be << radius)"],
              ]
 # pylint: enable=bad-whitespace,line-too-long
 
-source = ["lib/sas_3j1x_x.c"]
+source = ["lib/sas_3j1x_x.c","fuzzy_sphere.c"]
 have_Fq = True
+effective_radius_type = ["radius","radius + fuzziness"]
 
-c_code = """
-static double form_volume(double radius)
-{
-    return M_4PI_3*cube(radius);
-}
-
-static void Fq(double q, double *F1, double *F2, double sld, double sld_solvent,
-               double radius, double fuzziness)
-{
-    const double qr = q*radius;
-    const double bes = sas_3j1x_x(qr);
-    const double qf = exp(-0.5*square(q*fuzziness));
-    const double contrast = (sld - sld_solvent);
-    const double form = contrast * form_volume(radius) * bes * qf;
-    *F1 = 1.0e-2*form;
-    *F2 = 1.0e-4*form*form;
-}
-"""
-
-def ER(radius):
-    """
-    Return radius
-    """
-    return radius
+#def ER(radius):
+#    """
+#    Return radius
+#    """
+#    return radius
 
 # VR defaults to 1.0
Index: sasmodels/models/hollow_cylinder.c
===================================================================
--- sasmodels/models/hollow_cylinder.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/hollow_cylinder.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -22,4 +22,34 @@
 }
 
+static double
+radius_from_volume(double radius, double thickness, double length)
+{
+    const double volume_outer_cyl = M_PI*square(radius + thickness)*length;
+    return cbrt(0.75*volume_outer_cyl/M_PI);
+}
+
+static double
+radius_from_diagonal(double radius, double thickness, double length)
+{
+    return sqrt(square(radius + thickness) + 0.25*square(length));
+}
+
+static double
+effective_radius(int mode, double radius, double thickness, double length)
+{
+    if (mode == 1) {
+        return radius_from_volume(radius, thickness, length);
+    } else if (mode == 2) {
+        return radius + thickness;
+    } else if (mode == 3) {
+        return 0.5*length;
+    } else if (mode == 4) {
+        return (radius + thickness < 0.5*length ? radius + thickness : 0.5*length);
+    } else if (mode == 5) {
+        return (radius + thickness > 0.5*length ? radius + thickness : 0.5*length);
+    } else {
+        return radius_from_diagonal(radius,thickness,length);
+    }
+}
 
 static void
Index: sasmodels/models/hollow_cylinder.py
===================================================================
--- sasmodels/models/hollow_cylinder.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/hollow_cylinder.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -90,23 +90,25 @@
 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "hollow_cylinder.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","outer radius","half length",
+                         "half outer min dimension","half outer max dimension","half outer diagonal"]
 
 # pylint: disable=W0613
-def ER(radius, thickness, length):
-    """
-    :param radius:      Cylinder core radius
-    :param thickness:   Cylinder wall thickness
-    :param length:      Cylinder length
-    :return:            Effective radius
-    """
-    router = radius + thickness
-    if router == 0 or length == 0:
-        return 0.0
-    len1 = router
-    len2 = length/2.0
-    term1 = len1*len1*2.0*len2/2.0
-    term2 = 1.0 + (len2/len1)*(1.0 + 1/len2/2.0)*(1.0 + pi*len1/len2/2.0)
-    ddd = 3.0*term1*term2
-    diam = pow(ddd, (1.0/3.0))
-    return diam
+#def ER(radius, thickness, length):
+#    """
+#    :param radius:      Cylinder core radius
+#    :param thickness:   Cylinder wall thickness
+#    :param length:      Cylinder length
+#    :return:            Effective radius
+#    """
+#    router = radius + thickness
+#    if router == 0 or length == 0:
+#        return 0.0
+#    len1 = router
+#    len2 = length/2.0
+#    term1 = len1*len1*2.0*len2/2.0
+#    term2 = 1.0 + (len2/len1)*(1.0 + 1/len2/2.0)*(1.0 + pi*len1/len2/2.0)
+#    ddd = 3.0*term1*term2
+#    diam = pow(ddd, (1.0/3.0))
+#    return diam
 
 def VR(radius, thickness, length):
Index: sasmodels/models/hollow_rectangular_prism.c
===================================================================
--- sasmodels/models/hollow_rectangular_prism.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/hollow_rectangular_prism.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -11,4 +11,24 @@
     double vol_shell = vol_total - vol_core;
     return vol_shell;
+}
+
+static double
+effective_radius(int mode, double length_a, double b2a_ratio, double c2a_ratio, double thickness)
+{
+    if (mode == 1) {
+        return cbrt(0.75*cube(length_a)*b2a_ratio*c2a_ratio/M_PI);
+    } else if (mode == 2) {
+        return 0.5 * length_a;
+    } else if (mode == 3) {
+        return 0.5 * length_a*b2a_ratio;
+    } else if (mode == 4) {
+        return 0.5 * length_a*c2a_ratio;
+    } else if (mode == 5) {
+        return length_a*sqrt(b2a_ratio/M_PI);
+    } else if (mode == 6) {
+        return 0.5*sqrt(square(length_a) * (1.0 + square(b2a_ratio)));
+    } else {
+        return 0.5*sqrt(square(length_a) * (1.0 + square(b2a_ratio) + square(c2a_ratio)));
+    }
 }
 
Index: sasmodels/models/hollow_rectangular_prism.py
===================================================================
--- sasmodels/models/hollow_rectangular_prism.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/hollow_rectangular_prism.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -143,18 +143,20 @@
 source = ["lib/gauss76.c", "hollow_rectangular_prism.c"]
 have_Fq = True
-
-def ER(length_a, b2a_ratio, c2a_ratio, thickness):
-    """
-    Return equivalent radius (ER)
-    thickness parameter not used
-    """
-    b_side = length_a * b2a_ratio
-    c_side = length_a * c2a_ratio
-
-    # surface average radius (rough approximation)
-    surf_rad = sqrt(length_a * b_side / pi)
-
-    ddd = 0.75 * surf_rad * (2 * surf_rad * c_side + (c_side + surf_rad) * (c_side + pi * surf_rad))
-    return 0.5 * (ddd) ** (1. / 3.)
+effective_radius_type = ["equivalent sphere","half length_a", "half length_b", "half length_c",
+                         "equivalent outer circular cross-section","half ab diagonal","half diagonal"]
+
+#def ER(length_a, b2a_ratio, c2a_ratio, thickness):
+#    """
+#    Return equivalent radius (ER)
+#    thickness parameter not used
+#    """
+#    b_side = length_a * b2a_ratio
+#    c_side = length_a * c2a_ratio
+#
+#    # surface average radius (rough approximation)
+#    surf_rad = sqrt(length_a * b_side / pi)
+#
+#    ddd = 0.75 * surf_rad * (2 * surf_rad * c_side + (c_side + surf_rad) * (c_side + pi * surf_rad))
+#    return 0.5 * (ddd) ** (1. / 3.)
 
 def VR(length_a, b2a_ratio, c2a_ratio, thickness):
Index: sasmodels/models/hollow_rectangular_prism_thin_walls.c
===================================================================
--- sasmodels/models/hollow_rectangular_prism_thin_walls.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/hollow_rectangular_prism_thin_walls.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -6,4 +6,24 @@
     double vol_shell = 2.0 * (length_a*length_b + length_a*length_c + length_b*length_c);
     return vol_shell;
+}
+
+static double
+effective_radius(int mode, double length_a, double b2a_ratio, double c2a_ratio)
+{
+    if (mode == 1) {
+        return cbrt(0.75*cube(length_a)*b2a_ratio*c2a_ratio/M_PI);
+    } else if (mode == 2) {
+        return 0.5 * length_a;
+    } else if (mode == 3) {
+        return 0.5 * length_a*b2a_ratio;
+    } else if (mode == 4) {
+        return 0.5 * length_a*c2a_ratio;
+    } else if (mode == 5) {
+        return length_a*sqrt(b2a_ratio/M_PI);
+    } else if (mode == 6) {
+        return 0.5*sqrt(square(length_a) * (1.0 + square(b2a_ratio)));
+    } else {
+        return 0.5*sqrt(square(length_a) * (1.0 + square(b2a_ratio) + square(c2a_ratio)));
+    }
 }
 
Index: sasmodels/models/hollow_rectangular_prism_thin_walls.py
===================================================================
--- sasmodels/models/hollow_rectangular_prism_thin_walls.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/hollow_rectangular_prism_thin_walls.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -103,17 +103,19 @@
 source = ["lib/gauss76.c", "hollow_rectangular_prism_thin_walls.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","half length_a", "half length_b", "half length_c",
+                         "equivalent outer circular cross-section","half ab diagonal","half diagonal"]
 
-def ER(length_a, b2a_ratio, c2a_ratio):
-    """
-        Return equivalent radius (ER)
-    """
-    b_side = length_a * b2a_ratio
-    c_side = length_a * c2a_ratio
-
-    # surface average radius (rough approximation)
-    surf_rad = sqrt(length_a * b_side / pi)
-
-    ddd = 0.75 * surf_rad * (2 * surf_rad * c_side + (c_side + surf_rad) * (c_side + pi * surf_rad))
-    return 0.5 * (ddd) ** (1. / 3.)
+#def ER(length_a, b2a_ratio, c2a_ratio):
+#    """
+#        Return equivalent radius (ER)
+#    """
+#    b_side = length_a * b2a_ratio
+#    c_side = length_a * c2a_ratio
+#
+#    # surface average radius (rough approximation)
+#    surf_rad = sqrt(length_a * b_side / pi)
+#
+#    ddd = 0.75 * surf_rad * (2 * surf_rad * c_side + (c_side + surf_rad) * (c_side + pi * surf_rad))
+#    return 0.5 * (ddd) ** (1. / 3.)
 
 def VR(length_a, b2a_ratio, c2a_ratio):
Index: sasmodels/models/mono_gauss_coil.c
===================================================================
--- sasmodels/models/mono_gauss_coil.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
+++ sasmodels/models/mono_gauss_coil.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -0,0 +1,31 @@
+static double form_volume(double rg)
+{
+    return 1.0;
+}
+
+static double
+effective_radius(int mode, double rg)
+{
+    if (mode == 1) {
+        return rg;
+    } else if (mode == 2) {
+        return 2.0*rg;
+    } else if (mode == 3) {
+        return 3.0*rg;
+    } else {
+        return sqrt(5.0/3.0)*rg;
+    }
+}
+
+double Iq(double q, double i_zero, double rg)
+{
+    const double uarg = square(q*rg);
+    const double inten;
+    if (q == 0) {
+        inten = i_zero;
+    } else {
+        inten = 2.0*i_zero * (exp(-uarg) + uarg - 1.0)/square(uarg);
+    }
+
+    return inten;
+}
Index: sasmodels/models/mono_gauss_coil.py
===================================================================
--- sasmodels/models/mono_gauss_coil.py	(revision 2d81cfe3be42579d563407fb9275b7b516fee234)
+++ sasmodels/models/mono_gauss_coil.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -54,5 +54,5 @@
 
 import numpy as np
-from numpy import inf, exp, errstate
+from numpy import inf
 
 name = "mono_gauss_coil"
@@ -69,18 +69,24 @@
 parameters = [
     ["i_zero", "1/cm", 70.0, [0.0, inf], "", "Intensity at q=0"],
-    ["rg", "Ang", 75.0, [0.0, inf], "", "Radius of gyration"],
+    ["rg", "Ang", 75.0, [0.0, inf], "volume", "Radius of gyration"],
     ]
+
+source = ["mono_gauss_coil.c"]
+have_Fq = False
+effective_radius_type = ["R_g","2R_g","3R_g","(5/3)^0.5*R_g"]
+
+
 # pylint: enable=bad-whitespace, line-too-long
 
-# NB: Scale and Background are implicit parameters on every model
-def Iq(q, i_zero, rg):
-    # pylint: disable = missing-docstring
-    z = (q * rg)**2
-
-    with errstate(invalid='ignore'):
-        inten = (i_zero * 2.0) * (exp(-z) + z - 1.0)/z**2
-        inten[q == 0] = i_zero
-    return inten
-Iq.vectorized = True # Iq accepts an array of q values
+## NB: Scale and Background are implicit parameters on every model
+#def Iq(q, i_zero, rg):
+#    # pylint: disable = missing-docstring
+#    z = (q * rg)**2
+#
+#    with errstate(invalid='ignore'):
+#        inten = (i_zero * 2.0) * (exp(-z) + z - 1.0)/z**2
+#        inten[q == 0] = i_zero
+#    return inten
+#Iq.vectorized = True # Iq accepts an array of q values
 
 def random():
Index: sasmodels/models/multilayer_vesicle.c
===================================================================
--- sasmodels/models/multilayer_vesicle.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/multilayer_vesicle.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -47,4 +47,10 @@
 }
 
+static double
+effective_radius(int mode, double radius, double thick_shell, double thick_solvent, double fp_n_shells)
+{
+    return radius + fp_n_shells*thick_shell + (fp_n_shells - 1.0)*thick_solvent;
+}
+
 static void
 Fq(double q,
Index: sasmodels/models/multilayer_vesicle.py
===================================================================
--- sasmodels/models/multilayer_vesicle.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/multilayer_vesicle.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -146,8 +146,9 @@
 source = ["lib/sas_3j1x_x.c", "multilayer_vesicle.c"]
 have_Fq = True
+effective_radius_type = ["outer radius"]
 
-def ER(radius, thick_shell, thick_solvent, n_shells):
-    n_shells = int(n_shells+0.5)
-    return radius + n_shells * (thick_shell + thick_solvent) - thick_solvent
+#def ER(radius, thick_shell, thick_solvent, n_shells):
+#    n_shells = int(n_shells+0.5)
+#    return radius + n_shells * (thick_shell + thick_solvent) - thick_solvent
 
 def random():
Index: sasmodels/models/onion.c
===================================================================
--- sasmodels/models/onion.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/onion.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -40,4 +40,15 @@
 }
 
+static double
+effective_radius(int mode, double radius_core, double n_shells, double thickness[])
+{
+  int n = (int)(n_shells+0.5);
+  double r = radius_core;
+  for (int i=0; i < n; i++) {
+    r += thickness[i];
+  }
+  return r;
+}
+
 static void
 Fq(double q, double *F1, double *F2, double sld_core, double radius_core, double sld_solvent,
Index: sasmodels/models/onion.py
===================================================================
--- sasmodels/models/onion.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/onion.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -316,4 +316,5 @@
 single = False
 have_Fq = True
+effective_radius_type = ["outer radius"]
 
 profile_axes = ['Radius (A)', 'SLD (1e-6/A^2)']
@@ -366,8 +367,8 @@
     return np.asarray(z), np.asarray(rho)
 
-def ER(radius_core, n_shells, thickness):
-    """Effective radius"""
-    n = int(n_shells[0]+0.5)
-    return np.sum(thickness[:n], axis=0) + radius_core
+#def ER(radius_core, n_shells, thickness):
+#    """Effective radius"""
+#    n = int(n_shells[0]+0.5)
+#    return np.sum(thickness[:n], axis=0) + radius_core
 
 demo = {
Index: sasmodels/models/parallelepiped.c
===================================================================
--- sasmodels/models/parallelepiped.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/parallelepiped.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -3,4 +3,24 @@
 {
     return length_a * length_b * length_c;
+}
+
+static double
+effective_radius(int mode, double length_a, double length_b, double length_c)
+{
+    if (mode == 1) {
+        return cbrt(0.75*length_a*length_b*length_c/M_PI);
+    } else if (mode == 2) {
+        return 0.5 * length_a;
+    } else if (mode == 3) {
+        return 0.5 * length_b;
+    } else if (mode == 4) {
+        return 0.5 * length_c;
+    } else if (mode == 5) {
+        return sqrt(length_a*length_b/M_PI);
+    } else if (mode == 6) {
+        return 0.5*sqrt(length_a*length_a + length_b*length_b);
+    } else {
+        return 0.5*sqrt(length_a*length_a + length_b*length_b + length_c*length_c);
+    }
 }
 
Index: sasmodels/models/parallelepiped.py
===================================================================
--- sasmodels/models/parallelepiped.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/parallelepiped.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -231,20 +231,22 @@
 source = ["lib/gauss76.c", "parallelepiped.c"]
 have_Fq = True
-
-def ER(length_a, length_b, length_c):
-    """
-    Return effective radius (ER) for P(q)*S(q)
-    """
-    # now that axes can be in any size order, need to sort a,b,c
-    # where a~b and c is either much smaller or much larger
-    abc = np.vstack((length_a, length_b, length_c))
-    abc = np.sort(abc, axis=0)
-    selector = (abc[1] - abc[0]) > (abc[2] - abc[1])
-    length = np.where(selector, abc[0], abc[2])
-    # surface average radius (rough approximation)
-    radius = sqrt(np.where(~selector, abc[0]*abc[1], abc[1]*abc[2]) / pi)
-
-    ddd = 0.75 * radius * (2*radius*length + (length + radius)*(length + pi*radius))
-    return 0.5 * (ddd) ** (1. / 3.)
+effective_radius_type = ["equivalent sphere","half length_a", "half length_b", "half length_c",
+                         "equivalent circular cross-section","half ab diagonal","half diagonal"]
+
+#def ER(length_a, length_b, length_c):
+#    """
+#    Return effective radius (ER) for P(q)*S(q)
+#    """
+#    # now that axes can be in any size order, need to sort a,b,c
+#    # where a~b and c is either much smaller or much larger
+#    abc = np.vstack((length_a, length_b, length_c))
+#    abc = np.sort(abc, axis=0)
+#    selector = (abc[1] - abc[0]) > (abc[2] - abc[1])
+#    length = np.where(selector, abc[0], abc[2])
+#    # surface average radius (rough approximation)
+#    radius = sqrt(np.where(~selector, abc[0]*abc[1], abc[1]*abc[2]) / pi)
+#
+#    ddd = 0.75 * radius * (2*radius*length + (length + radius)*(length + pi*radius))
+#    return 0.5 * (ddd) ** (1. / 3.)
 
 # VR defaults to 1.0
Index: sasmodels/models/pringle.c
===================================================================
--- sasmodels/models/pringle.c	(revision 74768cb764a04223ec9e992e316cb8c211adfe34)
+++ sasmodels/models/pringle.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -104,4 +104,14 @@
 }
 
+static double
+effective_radius(int mode, double radius, double thickness, double alpha, double beta)
+{
+    if (mode == 1) {
+        return cbrt(0.75*radius*radius*thickness);
+    } else {
+        return radius;
+    }
+}
+
 double Iq(
     double q,
Index: sasmodels/models/pringle.py
===================================================================
--- sasmodels/models/pringle.py	(revision ef07e950965796e2a3a8156fcade98ce5e403001)
+++ sasmodels/models/pringle.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -74,12 +74,13 @@
 source = ["lib/polevl.c", "lib/sas_J0.c", "lib/sas_J1.c", \
           "lib/sas_JN.c", "lib/gauss76.c", "pringle.c"]
+effective_radius_type = ["equivalent sphere","radius"]
 
-def ER(radius, thickness, alpha, beta):
-    """
-    Return equivalent radius (ER)
-    """
-    ddd = 0.75 * radius * (2 * radius * thickness + (thickness + radius) \
-                           * (thickness + pi * radius))
-    return 0.5 * (ddd) ** (1. / 3.)
+#def ER(radius, thickness, alpha, beta):
+#    """
+#    Return equivalent radius (ER)
+#    """
+#    ddd = 0.75 * radius * (2 * radius * thickness + (thickness + radius) \
+#                           * (thickness + pi * radius))
+#    return 0.5 * (ddd) ** (1. / 3.)
 
 def random():
Index: sasmodels/models/raspberry.c
===================================================================
--- sasmodels/models/raspberry.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/raspberry.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -1,3 +1,3 @@
-double form_volume(double radius_lg);
+double form_volume(double radius_lg, double radius_sm, double penetration);
 
 double Iq(double q,
@@ -6,5 +6,5 @@
           double radius_lg, double radius_sm, double penetration);
 
-double form_volume(double radius_lg)
+double form_volume(double radius_lg, double radius_sm, double penetration)
 {
     //Because of the complex structure, volume normalization must
@@ -12,4 +12,14 @@
     double volume=1.0;
     return volume;
+}
+
+static double
+effective_radius(int mode, double radius_lg, double radius_sm, double penetration)
+{
+    if (mode == 1) {
+        return radius_lg;
+    } else {
+        return radius_lg + 2.0*radius_sm - penetration;
+    }
 }
 
Index: sasmodels/models/raspberry.py
===================================================================
--- sasmodels/models/raspberry.py	(revision ef07e950965796e2a3a8156fcade98ce5e403001)
+++ sasmodels/models/raspberry.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -145,11 +145,12 @@
               ["radius_lg", "Ang", 5000, [0, inf], "volume",
                "radius of large spheres"],
-              ["radius_sm", "Ang", 100, [0, inf], "",
+              ["radius_sm", "Ang", 100, [0, inf], "volume",
                "radius of small spheres"],
-              ["penetration", "Ang", 0, [-1, 1], "",
+              ["penetration", "Ang", 0, [-1, 1], "volume",
                "fractional penetration depth of small spheres into large sphere"],
              ]
 
 source = ["lib/sas_3j1x_x.c", "raspberry.c"]
+effective_radius_type = ["radius_large","radius_outer"]
 
 def random():
Index: sasmodels/models/rectangular_prism.c
===================================================================
--- sasmodels/models/rectangular_prism.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/rectangular_prism.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -3,4 +3,24 @@
 {
     return length_a * (length_a*b2a_ratio) * (length_a*c2a_ratio);
+}
+
+static double
+effective_radius(int mode, double length_a, double b2a_ratio, double c2a_ratio)
+{
+    if (mode == 1) {
+        return cbrt(0.75*cube(length_a)*b2a_ratio*c2a_ratio/M_PI);
+    } else if (mode == 2) {
+        return 0.5 * length_a;
+    } else if (mode == 3) {
+        return 0.5 * length_a*b2a_ratio;
+    } else if (mode == 4) {
+        return 0.5 * length_a*c2a_ratio;
+    } else if (mode == 5) {
+        return length_a*sqrt(b2a_ratio/M_PI);
+    } else if (mode == 6) {
+        return 0.5*sqrt(square(length_a) * (1.0 + square(b2a_ratio)));
+    } else {
+        return 0.5*sqrt(square(length_a) * (1.0 + square(b2a_ratio) + square(c2a_ratio)));
+    }
 }
 
Index: sasmodels/models/rectangular_prism.py
===================================================================
--- sasmodels/models/rectangular_prism.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/rectangular_prism.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -136,17 +136,19 @@
 source = ["lib/gauss76.c", "rectangular_prism.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","half length_a", "half length_b", "half length_c",
+                         "equivalent circular cross-section","half ab diagonal","half diagonal"]
 
-def ER(length_a, b2a_ratio, c2a_ratio):
-    """
-        Return equivalent radius (ER)
-    """
-    b_side = length_a * b2a_ratio
-    c_side = length_a * c2a_ratio
-
-    # surface average radius (rough approximation)
-    surf_rad = sqrt(length_a * b_side / pi)
-
-    ddd = 0.75 * surf_rad * (2 * surf_rad * c_side + (c_side + surf_rad) * (c_side + pi * surf_rad))
-    return 0.5 * (ddd) ** (1. / 3.)
+#def ER(length_a, b2a_ratio, c2a_ratio):
+#    """
+#        Return equivalent radius (ER)
+#    """
+#    b_side = length_a * b2a_ratio
+#    c_side = length_a * c2a_ratio
+#
+#    # surface average radius (rough approximation)
+#    surf_rad = sqrt(length_a * b_side / pi)
+#
+#    ddd = 0.75 * surf_rad * (2 * surf_rad * c_side + (c_side + surf_rad) * (c_side + pi * surf_rad))
+#    return 0.5 * (ddd) ** (1. / 3.)
 
 def random():
Index: sasmodels/models/sphere.c
===================================================================
--- sasmodels/models/sphere.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
+++ sasmodels/models/sphere.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -0,0 +1,19 @@
+static double form_volume(double radius)
+{
+    return M_4PI_3*cube(radius);
+}
+
+static double
+effective_radius(int mode, double radius)
+{
+    return radius;
+}
+
+static void Fq(double q, double *f1, double *f2, double sld, double sld_solvent, double radius)
+{
+    const double bes = sas_3j1x_x(q*radius);
+    const double contrast = (sld - sld_solvent);
+    const double form = contrast * form_volume(radius) * bes;
+    *f1 = 1.0e-2*form;
+    *f2 = 1.0e-4*form*form;
+}
Index: sasmodels/models/sphere.py
===================================================================
--- sasmodels/models/sphere.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/sphere.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -67,28 +67,13 @@
              ]
 
-source = ["lib/sas_3j1x_x.c"]
+source = ["lib/sas_3j1x_x.c","sphere.c"]
 have_Fq = True
+effective_radius_type = ["radius"]
 
-c_code = """
-static double form_volume(double radius)
-{
-    return M_4PI_3*cube(radius);
-}
-
-static void Fq(double q, double *f1, double *f2, double sld, double sld_solvent, double radius)
-{
-    const double bes = sas_3j1x_x(q*radius);
-    const double contrast = (sld - sld_solvent);
-    const double form = contrast * form_volume(radius) * bes;
-    *f1 = 1.0e-2*form;
-    *f2 = 1.0e-4*form*form;
-}
-"""
-
-def ER(radius):
-    """
-    Return equivalent radius (ER)
-    """
-    return radius
+#def ER(radius):
+#    """
+#    Return equivalent radius (ER)
+#    """
+#    return radius
 
 # VR defaults to 1.0
Index: sasmodels/models/spherical_sld.c
===================================================================
--- sasmodels/models/spherical_sld.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/spherical_sld.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -10,4 +10,15 @@
     }
     return M_4PI_3*cube(r);
+}
+
+static double
+effective_radius(int mode, double fp_n_shells, double thickness[], double interface[])
+{
+    int n_shells= (int)(fp_n_shells + 0.5);
+    double r = 0.0;
+    for (int i=0; i < n_shells; i++) {
+        r += thickness[i] + interface[i];
+    }
+    return r;
 }
 
Index: sasmodels/models/spherical_sld.py
===================================================================
--- sasmodels/models/spherical_sld.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/spherical_sld.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -210,4 +210,5 @@
 single = False  # TODO: fix low q behaviour
 have_Fq = True
+effective_radius_type = ["outer radius"]
 
 profile_axes = ['Radius (A)', 'SLD (1e-6/A^2)']
@@ -255,10 +256,10 @@
 
 
-def ER(n_shells, thickness, interface):
-    """Effective radius"""
-    n_shells = int(n_shells + 0.5)
-    total = (np.sum(thickness[:n_shells], axis=1)
-             + np.sum(interface[:n_shells], axis=1))
-    return total
+#def ER(n_shells, thickness, interface):
+#    """Effective radius"""
+#    n_shells = int(n_shells + 0.5)
+#    total = (np.sum(thickness[:n_shells], axis=1)
+#             + np.sum(interface[:n_shells], axis=1))
+#    return total
 
 
Index: sasmodels/models/triaxial_ellipsoid.c
===================================================================
--- sasmodels/models/triaxial_ellipsoid.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/triaxial_ellipsoid.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -7,4 +7,35 @@
 }
 
+static double
+radius_from_volume(double radius_equat_minor, double radius_equat_major, double radius_polar)
+{
+    return cbrt(radius_equat_minor*radius_equat_major*radius_polar);
+}
+
+static double
+radius_from_min_dimension(double radius_equat_minor, double radius_equat_major, double radius_polar)
+{
+    const double rad_equat_min = (radius_equat_minor < radius_equat_major ? radius_equat_minor : radius_equat_major);
+    return (rad_equat_min < radius_polar ? rad_equat_min : radius_polar);
+}
+
+static double
+radius_from_max_dimension(double radius_equat_minor, double radius_equat_major, double radius_polar)
+{
+    const double rad_equat_max = (radius_equat_minor < radius_equat_major ? radius_equat_major : radius_equat_minor);
+    return (rad_equat_max > radius_polar ? rad_equat_max : radius_polar);
+}
+
+static double
+effective_radius(int mode, double radius_equat_minor, double radius_equat_major, double radius_polar)
+{
+    if (mode == 1) {
+        return radius_from_volume(radius_equat_minor,radius_equat_major, radius_polar);
+    } else if (mode == 2) {
+        return radius_from_min_dimension(radius_equat_minor,radius_equat_major, radius_polar);
+    } else {
+        return radius_from_max_dimension(radius_equat_minor,radius_equat_major, radius_polar);
+    }
+}
 
 static void
Index: sasmodels/models/triaxial_ellipsoid.py
===================================================================
--- sasmodels/models/triaxial_ellipsoid.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/triaxial_ellipsoid.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -158,4 +158,5 @@
 source = ["lib/sas_3j1x_x.c", "lib/gauss76.c", "triaxial_ellipsoid.c"]
 have_Fq = True
+effective_radius_type = ["equivalent sphere","min radius", "max radius"]
 
 def ER(radius_equat_minor, radius_equat_major, radius_polar):
Index: sasmodels/models/vesicle.c
===================================================================
--- sasmodels/models/vesicle.c	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/vesicle.c	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -6,4 +6,9 @@
 }
 
+static double
+effective_radius(int mode, double radius, double thickness)
+{
+    return radius + thickness;
+}
 
 static void
Index: sasmodels/models/vesicle.py
===================================================================
--- sasmodels/models/vesicle.py	(revision 71b751d6a3a4ef4164f3b322841ddf3875c025c5)
+++ sasmodels/models/vesicle.py	(revision d277229f02cb7770fbb4ea2ad506d96bed705d75)
@@ -95,13 +95,14 @@
 source = ["lib/sas_3j1x_x.c", "vesicle.c"]
 have_Fq = True
+effective_radius_type = ["outer radius"]
 
-def ER(radius, thickness):
-    '''
-    returns the effective radius used in the S*P calculation
-
-    :param radius: core radius
-    :param thickness: shell thickness
-    '''
-    return radius + thickness
+#def ER(radius, thickness):
+#    '''
+#    returns the effective radius used in the S*P calculation
+#
+#    :param radius: core radius
+#    :param thickness: shell thickness
+#    '''
+#    return radius + thickness
 
 def VR(radius, thickness):
