Index: extra/pylint.rc
===================================================================
--- extra/pylint.rc	(revision 5ef0633b151126a2a8e376666e05ccbcc0341316)
+++ extra/pylint.rc	(revision 37a725200a1edb6dbd7a029a236c3ea2cfc7522c)
@@ -6,5 +6,5 @@
 # Python code to execute, usually for sys.path manipulation such as
 # pygtk.require().
-#init-hook=
+#init-hook='import os, sys; sys.path.extend([os.getcwd(),os.path.join(os.getcwd(),"extra")])'
 
 # Profiled execution.
Index: sasmodels/__init__.py
===================================================================
--- sasmodels/__init__.py	(revision 989005365096670e54afec254875979f35bd395a)
+++ sasmodels/__init__.py	(revision 37a725200a1edb6dbd7a029a236c3ea2cfc7522c)
@@ -1,1 +1,17 @@
+"""
+sasmodels
+=========
+
+**sasmodels** is a package containing models for small angle neutron and xray
+scattering.  Models supported are the one dimensional circular average and
+two dimensional oriented patterns.  As well as the form factor calculations
+for the individual shapes **sasmodels** also provides automatic shape
+polydispersity, angular dispersion and resolution convolution.  SESANS
+patterns can be computed for any model.
+
+Models can be written in python or in C.  C models can run on the GPU if
+OpenCL drivers are available.  See :mod:`generate` for details on
+defining new models.
+"""
+
 __version__ = "0.9"
Index: sasmodels/bumps_model.py
===================================================================
--- sasmodels/bumps_model.py	(revision ec7e360eb9b8ec7bb8f5006ed71720a9fa7d593b)
+++ sasmodels/bumps_model.py	(revision 37a725200a1edb6dbd7a029a236c3ea2cfc7522c)
@@ -6,9 +6,13 @@
 arguments to set the initial value for each parameter.
 
-:class:`Experiment` combines the *Model* function with a data file loaded by the
-sasview data loader.  *Experiment* takes a *cutoff* parameter controlling
+:class:`Experiment` combines the *Model* function with a data file loaded by
+the sasview data loader.  *Experiment* takes a *cutoff* parameter controlling
 how far the polydispersity integral extends.
 
 """
+
+__all__ = [
+    "Model", "Experiment",
+    ]
 
 import warnings
@@ -20,18 +24,60 @@
 
 # CRUFT: old style bumps wrapper which doesn't separate data and model
+# pylint: disable=invalid-name
 def BumpsModel(data, model, cutoff=1e-5, **kw):
+    r"""
+    Bind a model to data, along with a polydispersity cutoff.
+
+    *data* is a :class:`data.Data1D`, :class:`data.Data2D` or
+    :class:`data.Sesans` object.  Use :func:`data.empty_data1D` or
+    :func:`data.empty_data2D` to define $q, \Delta q$ calculation
+    points for displaying the SANS curve when there is no measured data.
+
+    *model* is a runnable module as returned from :func:`core.load_model`.
+
+    *cutoff* is the polydispersity weight cutoff.
+
+    Any additional *key=value* pairs are model dependent parameters.
+
+    Returns an :class:`Experiment` object.
+
+    Note that the usual Bumps semantics is not fully supported, since
+    assigning *M.name = parameter* on the returned experiment object
+    does not set that parameter in the model.  Range setting will still
+    work as expected though.
+
+    .. deprecated:: 0.1
+        Use :class:`Experiment` instead.
+    """
     warnings.warn("Use of BumpsModel is deprecated.  Use bumps_model.Experiment instead.")
+
+    # Create the model and experiment
     model = Model(model, **kw)
     experiment = Experiment(data=data, model=model, cutoff=cutoff)
-    for k in model._parameter_names:
-        setattr(experiment, k, getattr(model, k))
+
+    # Copy the model parameters up to the experiment object.
+    for k, v in model.parameters().items():
+        setattr(experiment, k, v)
     return experiment
 
+
 def create_parameters(model_info, **kwargs):
+    """
+    Generate Bumps parameters from the model info.
+
+    *model_info* is returned from :func:`generate.model_info` on the
+    model definition module.
+
+    Any additional *key=value* pairs are initial values for the parameters
+    to the models.  Uninitialized parameters will use the model default
+    value.
+
+    Returns a dictionary of *{name: Parameter}* containing the bumps
+    parameters for each model parameter, and a dictionary of
+    *{name: str}* containing the polydispersity distribution types.
+    """
     # lazy import; this allows the doc builder and nosetests to run even
     # when bumps is not on the path.
     from bumps.names import Parameter
-
-    partype = model_info['partype']
 
     pars = {}
@@ -40,10 +86,10 @@
         value = kwargs.pop(name, default)
         pars[name] = Parameter.default(value, name=name, limits=limits)
-    for name in partype['pd-2d']:
+    for name in model_info['partype']['pd-2d']:
         for xpart, xdefault, xlimits in [
-            ('_pd', 0., limits),
-            ('_pd_n', 35., (0, 1000)),
-            ('_pd_nsigma', 3., (0, 10)),
-        ]:
+                ('_pd', 0., limits),
+                ('_pd_n', 35., (0, 1000)),
+                ('_pd_nsigma', 3., (0, 10)),
+            ]:
             xname = name + xpart
             xvalue = kwargs.pop(xname, xdefault)
@@ -51,5 +97,5 @@
 
     pd_types = {}
-    for name in partype['pd-2d']:
+    for name in model_info['partype']['pd-2d']:
         xname = name + '_pd_type'
         xvalue = kwargs.pop(xname, 'gaussian')
@@ -63,10 +109,19 @@
 
 class Model(object):
+    """
+    Bumps wrapper for a SAS model.
+
+    *model* is a runnable module as returned from :func:`core.load_model`.
+
+    *cutoff* is the polydispersity weight cutoff.
+
+    Any additional *key=value* pairs are model dependent parameters.
+    """
     def __init__(self, model, **kwargs):
         self._sasmodel = model
         pars, pd_types = create_parameters(model.info, **kwargs)
-        for k,v in pars.items():
+        for k, v in pars.items():
             setattr(self, k, v)
-        for k,v in pd_types.items():
+        for k, v in pd_types.items():
             setattr(self, k, v)
         self._parameter_names = list(pars.keys())
@@ -75,9 +130,14 @@
     def parameters(self):
         """
-        Return a dictionary of parameters
+        Return a dictionary of parameters objects for the parameters,
+        excluding polydispersity distribution type.
         """
         return dict((k, getattr(self, k)) for k in self._parameter_names)
 
     def state(self):
+        """
+        Return a dictionary of current values for all the parameters,
+        including polydispersity distribution type.
+        """
         pars = dict((k, getattr(self, k).value) for k in self._parameter_names)
         pars.update((k, getattr(self, k)) for k in self._pd_type_names)
@@ -85,18 +145,18 @@
 
 class Experiment(DataMixin):
-    """
-    Return a bumps wrapper for a SAS model.
-
-    *data* is the data to be fitted.
-
-    *model* is the SAS model from :func:`core.load_model`.
+    r"""
+    Bumps wrapper for a SAS experiment.
+
+    *data* is a :class:`data.Data1D`, :class:`data.Data2D` or
+    :class:`data.Sesans` object.  Use :func:`data.empty_data1D` or
+    :func:`data.empty_data2D` to define $q, \Delta q$ calculation
+    points for displaying the SANS curve when there is no measured data.
+
+    *model* is a :class:`Model` object.
 
     *cutoff* is the integration cutoff, which avoids computing the
     the SAS model where the polydispersity weight is low.
 
-    Model parameters can be initialized with additional keyword
-    arguments, or by assigning to model.parameter_name.value.
-
-    The resulting bumps model can be used directly in a FitProblem call.
+    The resulting model can be used directly in a Bumps FitProblem call.
     """
     def __init__(self, data, model, cutoff=1e-5):
@@ -109,9 +169,13 @@
 
     def update(self):
+        """
+        Call when model parameters have changed and theory needs to be
+        recalculated.
+        """
         self._cache = {}
 
     def numpoints(self):
         """
-            Return the number of points
+        Return the number of data points
         """
         return len(self.Iq)
@@ -124,4 +188,10 @@
 
     def theory(self):
+        """
+        Return the theory corresponding to the model parameters.
+
+        This method uses lazy evaluation, and requires model.update() to be
+        called when the parameters have changed.
+        """
         if 'theory' not in self._cache:
             pars = self.model.state()
@@ -130,8 +200,16 @@
 
     def residuals(self):
+        """
+        Return theory minus data normalized by uncertainty.
+        """
         #if np.any(self.err ==0): print("zeros in err")
         return (self.theory() - self.Iq) / self.dIq
 
     def nllf(self):
+        """
+        Return the negative log likelihood of seeing data given the model
+        parameters, up to a normalizing constant which depends on the data
+        uncertainty.
+        """
         delta = self.residuals()
         #if np.any(np.isnan(R)): print("NaN in residuals")
@@ -149,8 +227,16 @@
 
     def simulate_data(self, noise=None):
+        """
+        Generate simulated data.
+        """
         Iq = self.theory()
         self._set_data(Iq, noise)
 
     def save(self, basename):
+        """
+        Save the model parameters and data into a file.
+
+        Not Implemented.
+        """
         pass
 
