Index: example/sesansfit.py
===================================================================
--- example/sesansfit.py	(revision 4c1bfb30f146978f59d2dcbbfa8d1a9fa98f62db)
+++ example/sesansfit.py	(revision d459d4e9aa26271c364f8d00fb9d2532734b2872)
@@ -42,9 +42,9 @@
             dy = err_data
             sample = Sample()
-            needs_all_q = acceptance_angle is not None
+            has_no_finite_acceptance = acceptance_angle is not None
         data = SESANSData1D()
         data.acceptance_angle = acceptance_angle
 
-    data.needs_all_q = acceptance_angle is not None
+    data.has_no_finite_acceptance = acceptance_angle is not None
     if "radius" in initial_vals:
         radius = initial_vals.get("radius")
Index: sasmodels/compare.py
===================================================================
--- sasmodels/compare.py	(revision af92b736ef07ae4becfadd8b6368696e118aeae9)
+++ sasmodels/compare.py	(revision 72a081dea6caa8fa493057133a6232f6b118c89a)
@@ -369,5 +369,5 @@
             model = MultiplicationModel(P, S)
         else:
-            raise ValueError("mixture models not handled yet")
+            raise ValueError("sasview mixture models not supported by compare")
     else:
         model = get_model(model_info['oldname'])
@@ -424,20 +424,10 @@
     Return a model calculator using the OpenCL calculation engine.
     """
-    def builder(model_info):
-        try:
-            return core.build_model(model_info, dtype=dtype, platform="ocl")
-        except Exception as exc:
-            print(exc)
-            print("... trying again with single precision")
-            return core.build_model(model_info, dtype='single', platform="ocl")
-    if model_info['composition']:
-        composition_type, parts = model_info['composition']
-        if composition_type == 'product':
-            P, S = [builder(p) for p in parts]
-            model = product.ProductModel(P, S)
-        else:
-            raise ValueError("mixture models not handled yet")
-    else:
-        model = builder(model_info)
+    try:
+        model = core.build_model(model_info, dtype=dtype, platform="ocl")
+    except Exception as exc:
+        print(exc)
+        print("... trying again with single precision")
+        model = core.build_model(model_info, dtype='single', platform="ocl")
     calculator = DirectModel(data, model, cutoff=cutoff)
     calculator.engine = "OCL%s"%DTYPE_MAP[dtype]
@@ -450,16 +440,5 @@
     if dtype == 'quad':
         dtype = 'longdouble'
-    def builder(model_info):
-        return core.build_model(model_info, dtype=dtype, platform="dll")
-
-    if model_info['composition']:
-        composition_type, parts = model_info['composition']
-        if composition_type == 'product':
-            P, S = [builder(p) for p in parts]
-            model = product.ProductModel(P, S)
-        else:
-            raise ValueError("mixture models not handled yet")
-    else:
-        model = builder(model_info)
+    model = core.build_model(model_info, dtype=dtype, platform="dll")
     calculator = DirectModel(data, model, cutoff=cutoff)
     calculator.engine = "OMP%s"%DTYPE_MAP[dtype]
@@ -715,19 +694,11 @@
         print("expected parameters: model N1 N2")
 
-    def _get_info(name):
-        try:
-            model_info = core.load_model_info(name)
-        except ImportError, exc:
-            print(str(exc))
-            print("Use one of:\n    " + models)
-            sys.exit(1)
-        return model_info
-
     name = args[0]
-    if '*' in name:
-        parts = [_get_info(k) for k in name.split('*')]
-        model_info = product.make_product_info(*parts)
-    else:
-        model_info = _get_info(name)
+    try:
+        model_info = core.load_model_info(name)
+    except ImportError, exc:
+        print(str(exc))
+        print("Could not find model; use one of:\n    " + models)
+        sys.exit(1)
 
     invalid = [o[1:] for o in flags
@@ -749,5 +720,5 @@
         'res'       : 0.0,
         'accuracy'  : 'Low',
-        'cutoff'    : 1e-5,
+        'cutoff'    : 0.0,
         'seed'      : -1,  # default to preset
         'mono'      : False,
Index: sasmodels/core.py
===================================================================
--- sasmodels/core.py	(revision d5ba8419b0a797faa3fe41fde9334c5a19282992)
+++ sasmodels/core.py	(revision 72a081dea6caa8fa493057133a6232f6b118c89a)
@@ -3,6 +3,7 @@
 """
 
-from os.path import basename, dirname, join as joinpath
+from os.path import basename, dirname, join as joinpath, splitext
 from glob import glob
+import imp
 
 import numpy as np
@@ -11,5 +12,8 @@
 from . import weights
 from . import generate
-
+# TODO: remove circular references between product and core
+# product uses call_ER/call_VR, core uses make_product_info/ProductModel
+#from . import product
+from . import mixture
 from . import kernelpy
 from . import kerneldll
@@ -46,28 +50,44 @@
     Load model info and build model.
     """
+    return build_model(load_model_info(model_name), **kw)
+
+def load_model_info_from_path(path):
+    # Pull off the last .ext if it exists; there may be others
+    name = basename(splitext(path)[0])
+
+    # Not cleaning name since don't need to be able to reload this
+    # model later
+    # Should probably turf the model from sys.modules after we are done...
+
+    # Placing the model in the 'sasmodels.custom' name space, even
+    # though it doesn't actually exist.  imp.load_source doesn't seem
+    # to care.
+    kernel_module = imp.load_source('sasmodels.custom.'+name, path)
+
+    # Now that we have the module, we can load it as usual
+    model_info = generate.make_model_info(kernel_module)
+    return model_info
+
+def load_model_info(model_name):
+    """
+    Load a model definition given the model name.
+
+    This returns a handle to the module defining the model.  This can be
+    used with functions in generate to build the docs or extract model info.
+    """
     parts = model_name.split('+')
     if len(parts) > 1:
-        from .mixture import MixtureModel
-        models = [load_model(p, **kw) for p in parts]
-        return MixtureModel(models)
+        model_info_list = [load_model_info(p) for p in parts]
+        return mixture.make_mixture_info(model_info_list)
 
     parts = model_name.split('*')
     if len(parts) > 1:
+        from . import product
         # Note: currently have circular reference
-        from .product import ProductModel
         if len(parts) > 2:
             raise ValueError("use P*S to apply structure factor S to model P")
-        P, Q = [load_model(p, **kw) for p in parts]
-        return ProductModel(P, Q)
-
-    return build_model(load_model_info(model_name), **kw)
-
-def load_model_info(model_name):
-    """
-    Load a model definition given the model name.
-
-    This returns a handle to the module defining the model.  This can be
-    used with functions in generate to build the docs or extract model info.
-    """
+        P_info, Q_info = [load_model_info(p) for p in parts]
+        return product.make_product_info(P_info, Q_info)
+
     #import sys; print "\n".join(sys.path)
     __import__('sasmodels.models.'+model_name)
@@ -95,9 +115,16 @@
     otherwise it uses the default "ocl".
     """
-    source = generate.make_source(model_info)
-    if dtype is None:
-        dtype = 'single' if model_info['single'] else 'double'
-    if callable(model_info.get('Iq', None)):
-        return kernelpy.PyModel(model_info)
+    composition = model_info.get('composition', None)
+    if composition is not None:
+        composition_type, parts = composition
+        models = [build_model(p, dtype=dtype, platform=platform) for p in parts]
+        if composition_type == 'mixture':
+            return mixture.MixtureModel(model_info, models)
+        elif composition_type == 'product':
+            from . import product
+            P, S = parts
+            return product.ProductModel(model_info, P, S)
+        else:
+            raise ValueError('unknown mixture type %s'%composition_type)
 
     ## for debugging:
@@ -109,5 +136,9 @@
     # open(model_info['name']+'.c','w').write(source)
     # source = open(model_info['name']+'.cl','r').read()
-
+    source = generate.make_source(model_info)
+    if dtype is None:
+        dtype = 'single' if model_info['single'] else 'double'
+    if callable(model_info.get('Iq', None)):
+        return kernelpy.PyModel(model_info)
     if (platform == "dll"
             or not HAVE_OPENCL
Index: sasmodels/mixture.py
===================================================================
--- sasmodels/mixture.py	(revision 72a081dea6caa8fa493057133a6232f6b118c89a)
+++ sasmodels/mixture.py	(revision 72a081dea6caa8fa493057133a6232f6b118c89a)
@@ -0,0 +1,145 @@
+"""
+Mixture model
+-------------
+
+The product model multiplies the structure factor by the form factor,
+modulated by the effective radius of the form.  The resulting model
+has a attributes of both the model description (with parameters, etc.)
+and the module evaluator (with call, release, etc.).
+
+To use it, first load form factor P and structure factor S, then create
+*ProductModel(P, S)*.
+"""
+from copy import copy
+import numpy as np
+
+from .generate import process_parameters, COMMON_PARAMETERS, Parameter
+
+SCALE=0
+BACKGROUND=1
+EFFECT_RADIUS=2
+VOLFRACTION=3
+
+def make_mixture_info(parts):
+    """
+    Create info block for product model.
+    """
+    flatten = []
+    for part in parts:
+        if part['composition'] and part['composition'][0] == 'mixture':
+            flatten.extend(part['compostion'][1])
+        else:
+            flatten.append(part)
+    parts = flatten
+
+    # Build new parameter list
+    pars = COMMON_PARAMETERS + []
+    for k, part in enumerate(parts):
+        # Parameter prefix per model, A_, B_, ...
+        prefix = chr(ord('A')+k) + '_'
+        for p in part['parameters']:
+            # No background on the individual mixture elements
+            if p.name == 'background':
+                continue
+            # TODO: promote Parameter to a full class
+            # this code knows too much about the implementation!
+            p = list(p)
+            if p[0] == 'scale':  # allow model subtraction
+                p[3] = [-np.inf, np.inf]  # limits
+            p[0] = prefix+p[0]   # relabel parameters with A_, ...
+            pars.append(p)
+
+    model_info = {}
+    model_info['id'] = '+'.join(part['id'])
+    model_info['name'] = ' + '.join(part['name'])
+    model_info['filename'] = None
+    model_info['title'] = 'Mixture model with ' + model_info['name']
+    model_info['description'] = model_info['title']
+    model_info['docs'] = model_info['title']
+    model_info['category'] = "custom"
+    model_info['parameters'] = pars
+    #model_info['single'] = any(part['single'] for part in parts)
+    model_info['structure_factor'] = False
+    model_info['variant_info'] = None
+    #model_info['tests'] = []
+    #model_info['source'] = []
+    # Iq, Iqxy, form_volume, ER, VR and sesans
+    # Remember the component info blocks so we can build the model
+    model_info['composition'] = ('mixture', parts)
+    process_parameters(model_info)
+    return model_info
+
+
+class MixtureModel(object):
+    def __init__(self, model_info, parts):
+        self.info = model_info
+        self.parts = parts
+
+    def __call__(self, q_vectors):
+        # Note: may be sending the q_vectors to the n times even though they
+        # are only needed once.  It would mess up modularity quite a bit to
+        # handle this optimally, especially since there are many cases where
+        # separate q vectors are needed (e.g., form in python and structure
+        # in opencl; or both in opencl, but one in single precision and the
+        # other in double precision).
+        kernels = [part(q_vectors) for part in self.parts]
+        return MixtureKernel(self.info, kernels)
+
+    def release(self):
+        """
+        Free resources associated with the model.
+        """
+        for part in self.parts:
+            part.release()
+
+
+class MixtureKernel(object):
+    def __init__(self, model_info, kernels):
+        dim = '2d' if kernels[0].q_input.is_2d else '1d'
+
+        # fixed offsets starts at 2 for scale and background
+        fixed_pars, pd_pars = [], []
+        offsets = [[2, 0]]
+        #vol_index = []
+        def accumulate(fixed, pd, volume):
+            # subtract 1 from fixed since we are removing background
+            fixed_offset, pd_offset = offsets[-1]
+            #vol_index.extend(k+pd_offset for k,v in pd if v in volume)
+            offsets.append([fixed_offset + len(fixed) - 1, pd_offset + len(pd)])
+            pd_pars.append(pd)
+        if dim == '2d':
+            for p in kernels:
+                partype = p.info['partype']
+                accumulate(partype['fixed-2d'], partype['pd-2d'], partype['volume'])
+        else:
+            for p in kernels:
+                partype = p.info['partype']
+                accumulate(partype['fixed-1d'], partype['pd-1d'], partype['volume'])
+
+        #self.vol_index = vol_index
+        self.offsets = offsets
+        self.fixed_pars = fixed_pars
+        self.pd_pars = pd_pars
+        self.info = model_info
+        self.kernels = kernels
+        self.results = None
+
+    def __call__(self, fixed_pars, pd_pars, cutoff=1e-5):
+        scale, background = fixed_pars[0:2]
+        total = 0.0
+        self.results = []  # remember the parts for plotting later
+        for k in range(len(self.offsets)-1):
+            start_fixed, start_pd = self.offsets[k]
+            end_fixed, end_pd = self.offsets[k+1]
+            part_fixed = [fixed_pars[start_fixed], 0.0] + fixed_pars[start_fixed+1:end_fixed]
+            part_pd = [pd_pars[start_pd], 0.0] + pd_pars[start_pd+1:end_pd]
+            part_result = self.kernels[k](part_fixed, part_pd)
+            total += part_result
+            self.results.append(scale*sum+background)
+
+        return scale*total + background
+
+    def release(self):
+        self.p_kernel.release()
+        self.q_kernel.release()
+
Index: sasmodels/models/core_shell_cylinder.py
===================================================================
--- sasmodels/models/core_shell_cylinder.py	(revision f4878dc778e82ee49c11c59cc0517797917067cc)
+++ sasmodels/models/core_shell_cylinder.py	(revision 01eece695fca4715baea58b0e86d78de1ed9ca7c)
@@ -12,5 +12,5 @@
 .. math::
 
-    P(q,\alpha) = \frac{\text{scale}}{V_s} F^2(q) + \text{background}
+    I(q,\alpha) = \frac{\text{scale}}{V_s} F^2(q) + \text{background}
 
 where
@@ -52,7 +52,6 @@
 
 To provide easy access to the orientation of the core-shell cylinder, we
-define the axis of the cylinder using two angles $\theta$ and $\phi$. As
-for the case of the cylinder, those angles are defined in
-:num:`figure #cylinder-orientation`.
+define the axis of the cylinder using two angles $\theta$ and $\phi$. 
+(see :ref:`cylinder model <cylinder-angle-definition>`)
 
 NB: The 2nd virial coefficient of the cylinder is calculated based on
@@ -74,5 +73,9 @@
 distribution $p(\theta,\phi) = 1.0$.
 
-2013/11/26 - Description reviewed by Heenan, R.
+Reference
+---------
+see, for example, Ian Livsey  J. Chem. Soc., Faraday Trans. 2, 1987,83, 1445-1452
+
+2016/03/18 - Description reviewed by RKH
 """
 
@@ -83,8 +86,8 @@
 description = """
 P(q,alpha)= scale/Vs*f(q)^(2) + background,
-      where: f(q)= 2(core_sld - solvant_sld)
+      where: f(q)= 2(sld_core - solvant_sld)
         * Vc*sin[qLcos(alpha/2)]
         /[qLcos(alpha/2)]*J1(qRsin(alpha))
-        /[qRsin(alpha)]+2(shell_sld-solvent_sld)
+        /[qRsin(alpha)]+2(sld_shell-sld_solvent)
         *Vs*sin[q(L+T)cos(alpha/2)][[q(L+T)
         *cos(alpha/2)]*J1(q(R+T)sin(alpha))
@@ -96,6 +99,6 @@
     Vc: the volume of the core
     L: the length of the core
-        shell_sld: the scattering length density of the shell
-    solvent_sld: the scattering length density of the solvent
+        sld_shell: the scattering length density of the shell
+    sld_solvent: the scattering length density of the solvent
     background: the background
     T: the thickness
@@ -109,9 +112,9 @@
 
 #             ["name", "units", default, [lower, upper], "type", "description"],
-parameters = [["core_sld", "1e-6/Ang^2", 4, [-inf, inf], "",
+parameters = [["sld_core", "1e-6/Ang^2", 4, [-inf, inf], "",
                "Cylinder core scattering length density"],
-              ["shell_sld", "1e-6/Ang^2", 4, [-inf, inf], "",
+              ["sld_shell", "1e-6/Ang^2", 4, [-inf, inf], "",
                "Cylinder shell scattering length density"],
-              ["solvent_sld", "1e-6/Ang^2", 1, [-inf, inf], "",
+              ["sld_solvent", "1e-6/Ang^2", 1, [-inf, inf], "",
                "Solvent scattering length density"],
               ["radius", "Ang", 20, [0, inf], "volume",
@@ -147,5 +150,5 @@
 
 demo = dict(scale=1, background=0,
-            core_sld=6, shell_sld=8, solvent_sld=1,
+            sld_core=6, sld_shell=8, sld_solvent=1,
             radius=45, thickness=25, length=340,
             theta=30, phi=15,
@@ -156,3 +159,7 @@
             phi_pd=15, phi_pd_n=1)
 oldname = 'CoreShellCylinderModel'
-oldpars = dict(theta='axis_theta', phi='axis_phi')
+oldpars = dict( sld_core='core_sld',
+               sld_shell='shell_sld',
+               sld_solvent='solvent_sld',
+               theta='axis_theta', phi='axis_phi')
+# ADDED by:  RKH  ON: 18Mar2016 renamed sld's etc
Index: sasmodels/models/cylinder.py
===================================================================
--- sasmodels/models/cylinder.py	(revision aa2edb2b2fb550caed0506dcf63bc7eac7e1779a)
+++ sasmodels/models/cylinder.py	(revision 01eece695fca4715baea58b0e86d78de1ed9ca7c)
@@ -2,5 +2,5 @@
 # Note: model title and parameter table are inserted automatically
 r"""
-The form factor is normalized by the particle volume.
+The form factor is normalized by the particle volume V = \piR^2L.
 
 Definition
@@ -19,6 +19,6 @@
 
     F(q) = 2 (\Delta \rho) V
-           \frac{\sin \left(q\tfrac12 L\cos\alpha \right)}
-                {q\tfrac12 L \cos \alpha}
+           \frac{\sin \left(\tfrac12 qL\cos\alpha \right)}
+                {\tfrac12 qL \cos \alpha}
            \frac{J_1 \left(q R \sin \alpha\right)}{q R \sin \alpha}
 
@@ -88,6 +88,6 @@
 title = "Right circular cylinder with uniform scattering length density."
 description = """
-     f(q,alpha) = 2*(sld - solvent_sld)*V*sin(qLcos(alpha/2))
-                /[qLcos(alpha/2)]*J1(qRsin(alpha/2))/[qRsin(alpha)]
+     f(q,alpha) = 2*(sld - sld_solvent)*V*sin(qLcos(alpha)/2))
+                /[qLcos(alpha)/2]*J1(qRsin(alpha))/[qRsin(alpha)]
 
             P(q,alpha)= scale/V*f(q,alpha)^(2)+background
@@ -107,5 +107,5 @@
 parameters = [["sld", "4e-6/Ang^2", 4, [-inf, inf], "",
                "Cylinder scattering length density"],
-              ["solvent_sld", "1e-6/Ang^2", 1, [-inf, inf], "",
+              ["sld_solvent", "1e-6/Ang^2", 1, [-inf, inf], "",
                "Solvent scattering length density"],
               ["radius", "Ang", 20, [0, inf], "volume",
@@ -130,5 +130,5 @@
 # parameters for demo
 demo = dict(scale=1, background=0,
-            sld=6, solvent_sld=1,
+            sld=6, sld_solvent=1,
             radius=20, length=300,
             theta=60, phi=60,
@@ -141,5 +141,5 @@
 # names and the target sasview model name.
 oldname = 'CylinderModel'
-oldpars = dict(theta='cyl_theta', phi='cyl_phi', sld='sldCyl', solvent_sld='sldSolv')
+oldpars = dict(theta='cyl_theta', phi='cyl_phi', sld='sldCyl', sld_solvent='sldSolv')
 
 
@@ -151,2 +151,3 @@
         ]
 del qx, qy  # not necessary to delete, but cleaner
+# ADDED by:  RKH  ON: 18Mar2016 renamed sld's etc
Index: sasmodels/models/hayter_msa_kernel.c
===================================================================
--- sasmodels/models/hayter_msa_kernel.c	(revision d529d93bd045e44913320de5e1c8db47f680e037)
+++ sasmodels/models/hayter_msa_kernel.c	(revision ce43de0146d69b5f356808e50821fbfa3cf1d0fa)
@@ -14,5 +14,5 @@
   
 double Iq(double QQ,
-      double radius_effective, double zz, double VolFrac, double Temp, double csalt, double dialec)  
+      double radius_effective, double VolFrac, double zz, double Temp, double csalt, double dialec)
 {
     double gMSAWave[17]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
Index: sasmodels/models/hollow_cylinder.py
===================================================================
--- sasmodels/models/hollow_cylinder.py	(revision 2f0c07deb2cb7a8c0c93476fbf1e0ffbe6c278cb)
+++ sasmodels/models/hollow_cylinder.py	(revision 01eece695fca4715baea58b0e86d78de1ed9ca7c)
@@ -31,5 +31,5 @@
     J_1(x)         &= (\sin(x)-x\cdot \cos(x)) / x^2
 
-where *scale* is a scale factor and $J_1$ is the 1st order
+where *scale* is a scale factor, $H = L/2$ and $J_1$ is the 1st order
 Bessel function.
 
@@ -62,5 +62,5 @@
 length = the total length of the cylinder
 sld = SLD of the shell
-solvent_sld = SLD of the solvent
+sld_solvent = SLD of the solvent
 background = incoherent background
 """
@@ -73,5 +73,5 @@
     ["length",      "Ang",    400.0, [0, inf],    "volume",      "Cylinder length"],
     ["sld",         "1/Ang^2",  6.3, [-inf, inf], "",            "Cylinder sld"],
-    ["solvent_sld", "1/Ang^2",  1,   [-inf, inf], "",            "Solvent sld"],
+    ["sld_solvent", "1/Ang^2",  1,   [-inf, inf], "",            "Solvent sld"],
     ["theta",       "degrees", 90,   [-360, 360], "orientation", "Theta angle"],
     ["phi",         "degrees",  0,   [-360, 360], "orientation", "Phi angle"],
@@ -113,5 +113,5 @@
 # parameters for demo
 demo = dict(scale=1.0, background=0.0, length=400.0, radius=30.0,
-            core_radius=20.0, sld=6.3, solvent_sld=1, theta=90, phi=0,
+            core_radius=20.0, sld=6.3, sld_solvent=1, theta=90, phi=0,
             radius_pd=.2, radius_pd_n=9,
             length_pd=.2, length_pd_n=10,
@@ -125,5 +125,5 @@
 oldpars = dict(scale='scale', background='background', radius='radius',
                core_radius='core_radius', sld='sldCyl', length='length',
-               solvent_sld='sldSolv', phi='axis_phi', theta='axis_theta')
+               sld_solvent='sldSolv', phi='axis_phi', theta='axis_theta')
 
 # Parameters for unit tests
Index: sasmodels/product.py
===================================================================
--- sasmodels/product.py	(revision d5ba8419b0a797faa3fe41fde9334c5a19282992)
+++ sasmodels/product.py	(revision 72a081dea6caa8fa493057133a6232f6b118c89a)
@@ -68,8 +68,8 @@
 
 class ProductModel(object):
-    def __init__(self, P, S):
+    def __init__(self, model_info, P, S):
+        self.info = model_info
         self.P = P
         self.S = S
-        self.info = make_product_info(P.info, S.info)
 
     def __call__(self, q_vectors):
Index: sasmodels/sasview_model.py
===================================================================
--- sasmodels/sasview_model.py	(revision 08376e707b88225bb8c73e3058792f08aabb9b07)
+++ sasmodels/sasview_model.py	(revision 787be866d11d3e33f22f7b4ac9d0ee1a15146903)
@@ -16,5 +16,4 @@
 import math
 from copy import deepcopy
-import warnings
 import collections
 
@@ -22,9 +21,11 @@
 
 from . import core
+from . import generate
 
 def standard_models():
     return [make_class(model_name) for model_name in core.list_models()]
 
-def make_class(model_name, namestyle='name'):
+# TODO: rename to make_class_from_name and update sasview
+def make_class(model_name):
     """
     Load the sasview model defined in *kernel_module*.
@@ -37,8 +38,15 @@
     """
     model_info = core.load_model_info(model_name)
+    return make_class_from_info(model_info)
+
+def make_class_from_file(path):
+    model_info = core.load_model_info_from_path(path)
+    return make_class_from_info(model_info)
+
+def make_class_from_info(model_info):
     def __init__(self, multfactor=1):
         SasviewModel.__init__(self)
     attrs = dict(__init__=__init__, _model_info=model_info)
-    ConstructedModel = type(model_info[namestyle], (SasviewModel,), attrs)
+    ConstructedModel = type(model_info['name'], (SasviewModel,), attrs)
     return ConstructedModel
 
Index: sasmodels/sesans.py
===================================================================
--- sasmodels/sesans.py	(revision a06430cd1ac1662ddeef978e2f7b97f0579f0945)
+++ sasmodels/sesans.py	(revision d459d4e9aa26271c364f8d00fb9d2532734b2872)
@@ -1,7 +1,9 @@
 """
-Conversion of scattering cross section from SANS in absolute
-units into SESANS using a Hankel transformation
+Conversion of scattering cross section from SANS (I(q), or rather, ds/dO) in absolute
+units (cm-1)into SESANS correlation function G using a Hankel transformation, then converting
+the SESANS correlation function into polarisation from the SESANS experiment
 
-Everything is in units of metres except specified otherwise
+Everything is in units of metres except specified otherwise (NOT TRUE!!!)
+Everything is in conventional units (nm for spin echo length)
 
 Wim Bouwman (w.g.bouwman@tudelft.nl), June 2013
@@ -18,5 +20,9 @@
     r"""
     Return a $q$ vector suitable for SESANS covering from $2\pi/ (10 R_{\max})$
-    to $q_max$.
+    to $q_max$. This is the integration range of the Hankel transform; bigger range and 
+    more points makes a better numerical integration.
+    Smaller q_min will increase reliable spin echo length range. 
+    Rmax is the "radius" of the largest expected object and can be set elsewhere.
+    q_max is determined by the acceptance angle of the SESANS instrument.
     """
     q_min = dq = 0.1 * 2*pi / Rmax
@@ -24,7 +30,15 @@
     
 def make_all_q(data):
-    if not data.needs_all_q:
+    """
+    Return a $q$ vector suitable for calculating the total scattering cross section for
+    calculating the effect of finite acceptance angles on Time of Flight SESANS instruments.
+    If no acceptance is given, or unwanted (set "unwanted" flag in paramfile), no all_q vector is needed.
+    If the instrument has a rectangular acceptance, 2 all_q vectors are needed.
+    If the instrument has a circular acceptance, 1 all_q vector is needed
+    
+    """
+    if not data.has_no_finite_acceptance:
         return []
-    elif needs_Iqxy(data):
+    elif data.has_yz_acceptance(data):
         # compute qx, qy
         Qx, Qy = np.meshgrid(qx, qy)
@@ -32,7 +46,13 @@
     else:
         # else only need q
+        # data.has_z_acceptance
         return [q]
 
 def transform(data, q_calc, Iq_calc, qmono, Iq_mono):
+    """
+    Decides which transform type is to be used, based on the experiment data file contents (header)
+    (2016-03-19: currently controlled from parameters script)
+    nqmono is the number of q vectors to be used for the detector integration
+    """
     nqmono = len(qmono)
     if nqmono == 0:
@@ -62,5 +82,5 @@
                   q_calc, Iq_calc)
                   
-def Cosine2D(data, q_calc, Iq_calc, qx, qy, Iq_mono):
+def call_Cosine2D(data, q_calc, Iq_calc, qx, qy, Iq_mono):
     return hankel(data.x, data.y, data.lam * 1e-9,
                   data.sample.thickness / 10,
