Index: docs/sphinx-docs/build_sphinx.py
===================================================================
--- docs/sphinx-docs/build_sphinx.py	(revision 5dd7499bd50d00b6f42a8bead02ef73dc39a3bd4)
+++ docs/sphinx-docs/build_sphinx.py	(revision dd72190ffcdea398395f73e9b999c8bf27912314)
@@ -36,5 +36,7 @@
 #/sasview-local-trunk/docs/sphinx-docs/build_sphinx.py
 SASMODELS_SOURCE_PROLOG = os.path.join(CURRENT_SCRIPT_DIR, "..", "..", "..", "sasmodels", "doc")
+SASMODELS_SOURCE_GPU = os.path.join(CURRENT_SCRIPT_DIR, "..", "..", "..", "sasmodels", "doc", "ref", "gpu")
 SASMODELS_SOURCE_SESANS = os.path.join(CURRENT_SCRIPT_DIR, "..", "..", "..", "sasmodels", "doc", "ref", "sesans")
+SASMODELS_SOURCE_SESANSIMG = os.path.join(CURRENT_SCRIPT_DIR, "..", "..", "..", "sasmodels", "doc", "ref", "sesans", "sesans_img")
 SASMODELS_SOURCE_MAGNETISM = os.path.join(CURRENT_SCRIPT_DIR, "..", "..", "..", "sasmodels", "doc", "ref", "magnetism")
 SASMODELS_SOURCE_MAGIMG = os.path.join(CURRENT_SCRIPT_DIR, "..", "..", "..", "sasmodels", "doc", "ref", "magnetism", "mag_img")
@@ -50,4 +52,5 @@
 SASMODELS_DEST_IMG = os.path.join(SASMODELS_DEST_PROLOG, "user", "model-imgs", "new-models")
 SASMODELS_DEST_MAGIMG = os.path.join(SASMODELS_DEST_PROLOG, "user", "mag_img")
+SASMODELS_DEST_SESANSIMG = os.path.join(SASMODELS_DEST_PROLOG, "user", "sesans_img")
 SASMODELS_DEST_BUILDIMG = os.path.join(SASMODELS_DEST_PROLOG, "user", "models", "img")
 
@@ -190,5 +193,5 @@
             tohere=os.path.join(SASMODELS_DEST_IMG,files)
             shutil.copy(fromhere,tohere)
-        else: print "no source directorty",SASMODELS_SOURCE_AUTOIMG ,"was found"
+    else: print "no source directory",SASMODELS_SOURCE_AUTOIMG ,"was found"
 
     # And the rst prolog with the unit substitutions
@@ -204,4 +207,16 @@
                     shutil.copy(fromhere,tohere)
 
+    if os.path.exists(SASMODELS_SOURCE_GPU):
+        print "Found docs folder SASMODELS_SOURCE_GPU at ", SASMODELS_SOURCE_GPU
+        if os.path.exists(SPHINX_SOURCE_USER):
+            print "Found docs folder SPHINX_SOURCE_USER      at ", SPHINX_SOURCE_USER
+            print "Copying sasmodels gpu files..."
+            for files in os.listdir(SASMODELS_SOURCE_GPU):
+                if files.endswith(".rst"):
+                    fromhere=os.path.join(SASMODELS_SOURCE_GPU,files)
+                    tohere=os.path.join(SPHINX_SOURCE_USER,files)
+                    shutil.copy(fromhere,tohere)
+
+
     if os.path.exists(SASMODELS_SOURCE_SESANS):
         print "Found docs folder SASMODELS_SOURCE_SESANS at ", SASMODELS_SOURCE_SESANS
@@ -227,5 +242,5 @@
 
     if os.path.exists(SASMODELS_SOURCE_MAGIMG):
-        print "Found img  folder SASMODELS_SOURCE_MAGIMG    at ", SASMODELS_SOURCE_MAGIMG
+        print "Found img folder SASMODELS_SOURCE_MAGIMG   at ", SASMODELS_SOURCE_MAGIMG
         if not os.path.exists(SASMODELS_DEST_MAGIMG):
             print "Missing docs folder SASMODELS_DEST_MAGIMG at ", SASMODELS_DEST_MAGIMG
@@ -237,5 +252,18 @@
             tohere=os.path.join(SASMODELS_DEST_MAGIMG,files)
             shutil.copy(fromhere,tohere)
-        else: print "no source directorty",SASMODELS_SOURCE_MAGIMG ,"was found"
+    else: print "no source directory",SASMODELS_SOURCE_MAGIMG ,"was found"
+
+    if os.path.exists(SASMODELS_SOURCE_SESANSIMG):
+        print "Found img folder SASMODELS_SOURCE_MAGIMG   at ", SASMODELS_SOURCE_SESANSIMG
+        if not os.path.exists(SASMODELS_DEST_MAGIMG):
+            print "Missing docs folder SASMODELS_DEST_MAGIMG at ", SASMODELS_DEST_SESANSIMG
+            os.makedirs(SASMODELS_DEST_SESANSIMG)
+            print "created SASMODELS_DEST_SESANSIMG at ", SASMODELS_DEST_SESANSIMG
+        print "Copying sasmodels model auto-generated image files..."
+        for files in os.listdir(SASMODELS_SOURCE_SESANSIMG):
+            fromhere=os.path.join(SASMODELS_SOURCE_SESANSIMG,files)
+            tohere=os.path.join(SASMODELS_DEST_SESANSIMG,files)
+            shutil.copy(fromhere,tohere)
+    else: print "no source directory",SASMODELS_SOURCE_SESANSIMG ,"was found"
 
     if os.path.exists(SASMODELS_SOURCE_REF_MODELS):
Index: src/sas/sascalc/dataloader/data_info.py
===================================================================
--- src/sas/sascalc/dataloader/data_info.py	(revision 45d766273b9962bed84bd4bb7cb2c0227b97686d)
+++ src/sas/sascalc/dataloader/data_info.py	(revision 1b1a1c1f5fa5d17a2e503d0e1803259f57dc943a)
@@ -881,7 +881,7 @@
                 raise ValueError, msg
             # Here we could also extrapolate between data points
-            ZERO = 1.0e-12
+            TOLERANCE = 0.01
             for i in range(len(self.x)):
-                if math.fabs(self.x[i] - other.x[i]) > ZERO:
+                if math.fabs((self.x[i] - other.x[i])/self.x[i]) > TOLERANCE:
                     msg = "Incompatible data sets: x-values do not match"
                     raise ValueError, msg
@@ -1093,4 +1093,5 @@
         """
         err_other = None
+        TOLERANCE = 0.01
         if isinstance(other, Data2D):
             # Check that data lengths are the same
@@ -1101,9 +1102,9 @@
                 raise ValueError, msg
             for ind in range(len(self.data)):
-                if self.qx_data[ind] != other.qx_data[ind]:
-                    msg = "Incompatible data sets: qx-values do not match"
+                if math.fabs((self.qx_data[ind] - other.qx_data[ind])/self.qx_data[ind]) > TOLERANCE:
+                    msg = "Incompatible data sets: qx-values do not match: %s %s" % (self.qx_data[ind], other.qx_data[ind])
                     raise ValueError, msg
-                if self.qy_data[ind] != other.qy_data[ind]:
-                    msg = "Incompatible data sets: qy-values do not match"
+                if math.fabs((self.qy_data[ind] - other.qy_data[ind])/self.qy_data[ind]) > TOLERANCE:
+                    msg = "Incompatible data sets: qy-values do not match: %s %s" % (self.qy_data[ind], other.qy_data[ind])
                     raise ValueError, msg
 
Index: src/sas/sasgui/guiframe/dataFitting.py
===================================================================
--- src/sas/sasgui/guiframe/dataFitting.py	(revision d85c194ea2f78cb2b9b3de9c969e1b8ebea6b6d2)
+++ src/sas/sasgui/guiframe/dataFitting.py	(revision 9b6d62d61651fd47f2c1045d4d7ac93baea0c533)
@@ -363,73 +363,5 @@
         _str = "%s\n" % LoadData2D.__str__(self)
         return _str 
-    
-    def _validity_check(self, other):
-        """
-        Checks that the data lengths are compatible.
-        Checks that the x vectors are compatible.
-        Returns errors vectors equal to original
-        errors vectors if they were present or vectors
-        of zeros when none was found.
-        
-        :param other: other data set for operation
-        
-        :return: dy for self, dy for other [numpy arrays]
-        
-        :raise ValueError: when lengths are not compatible
-        
-        """
-        err_other = None
-        if isinstance(other, Data2D):
-            # Check that data lengths are the same
-            if len(self.data) != len(other.data) or \
-                len(self.qx_data) != len(other.qx_data) or \
-                len(self.qy_data) != len(other.qy_data):
-                msg = "Unable to perform operation: data length are not equal"
-                raise ValueError, msg
-            #if len(self.data) < 1:
-            #    msg = "Incompatible data sets: I-values do not match"
-            #    raise ValueError, msg 
-            for ind in range(len(self.data)):
-                if self.qx_data[ind] != other.qx_data[ind]:
-                    msg = "Incompatible data sets: qx-values do not match"
-                    raise ValueError, msg
-                if self.qy_data[ind] != other.qy_data[ind]:
-                    msg = "Incompatible data sets: qy-values do not match"
-                    raise ValueError, msg
-                   
-            # Check that the scales match
-            err_other = other.err_data
-            if other.err_data == None or \
-                (len(other.err_data) != len(other.data)):
-                err_other = numpy.zeros(len(other.data))
-            
-        # Check that we have errors, otherwise create zero vector
-        err = self.err_data
-        if self.err_data == None or \
-            (len(self.err_data) != len(self.data)):
-            err = numpy.zeros(len(other.data))
-            
-        return err, err_other
-
-    def _validity_check_union(self, other):
-        """
-        Checks that the data lengths are compatible.
-        Checks that the x vectors are compatible.
-        Returns errors vectors equal to original
-        errors vectors if they were present or vectors
-        of zeros when none was found.
-        
-        :param other: other data set for operation
-        
-        :return: bool
-        
-        :raise ValueError: when data types are not compatible
-        
-        """
-        if not isinstance(other, Data2D):
-            msg = "Unable to perform operation: different types of data set"
-            raise ValueError, msg   
-        return True
-    
+
     def _perform_operation(self, other, operation):
         """
Index: src/sas/sasgui/perspectives/calculator/data_operator.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/data_operator.py	(revision 0e760e9190d1a156409589ee9c50372130d80dbe)
+++ src/sas/sasgui/perspectives/calculator/data_operator.py	(revision 61780e3355265f8377c4d588db7b820d2c9989a7)
@@ -397,5 +397,5 @@
             self._set_textctrl_color(self.data1_cbox, 'pink')
             self._set_textctrl_color(self.data2_cbox, 'pink')
-            msg = "DataOperation: Data types must be same."
+            msg = "DataOperation: %s" % sys.exc_value
             self.send_warnings(msg, 'error')
             self.output = None
Index: src/sas/sasgui/perspectives/fitting/fitting.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/fitting.py	(revision e89aed5c946bf39b3cb963b0c7805341c30d2432)
+++ src/sas/sasgui/perspectives/fitting/fitting.py	(revision 286c7571e8019b4c28a92d3d497cac7da825076c)
@@ -1742,8 +1742,9 @@
                                       data_id=str(page_id) + " " + data.name + " unsmeared")
 
-                self.create_theory_1D(x, unsmeared_data, page_id, model, data, state,
-                                      data_description="Data unsmeared",
-                                      data_id="Data  " + data.name + " unsmeared",
-                                      dy=unsmeared_error)
+                if unsmeared_data is not None and unsmeared_error is not None:
+                    self.create_theory_1D(x, unsmeared_data, page_id, model, data, state,
+                                          data_description="Data unsmeared",
+                                          data_id="Data  " + data.name + " unsmeared",
+                                          dy=unsmeared_error)
                 
             if sq_model is not None and pq_model is not None:
Index: src/sas/sasgui/perspectives/fitting/model_thread.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/model_thread.py	(revision ca4d9854c75a5344e770dec25221dfeb5a270915)
+++ src/sas/sasgui/perspectives/fitting/model_thread.py	(revision 286c7571e8019b4c28a92d3d497cac7da825076c)
@@ -179,17 +179,20 @@
             unsmeared_output[first_bin:last_bin+1] = self.model.evalDistribution(mask)
             output = self.smearer(unsmeared_output, first_bin, last_bin)
-            
+
             # Rescale data to unsmeared model
-            unsmeared_data = numpy.zeros((len(self.data.x)))
-            unsmeared_error = numpy.zeros((len(self.data.x)))
-            unsmeared_data[first_bin:last_bin+1] = self.data.y[first_bin:last_bin+1]\
-                                                    * unsmeared_output[first_bin:last_bin+1]\
-                                                    / output[first_bin:last_bin+1]
-            unsmeared_error[first_bin:last_bin+1] = self.data.dy[first_bin:last_bin+1]\
-                                                    * unsmeared_output[first_bin:last_bin+1]\
-                                                    / output[first_bin:last_bin+1]
-            unsmeared_output=unsmeared_output[index]
-            unsmeared_data=unsmeared_data[index]
-            unsmeared_error=unsmeared_error
+            # Check that the arrays are compatible. If we only have a model but no data,
+            # the length of data.y will be zero.
+            if isinstance(self.data.y, numpy.ndarray) and output.shape == self.data.y.shape:
+                unsmeared_data = numpy.zeros((len(self.data.x)))
+                unsmeared_error = numpy.zeros((len(self.data.x)))
+                unsmeared_data[first_bin:last_bin+1] = self.data.y[first_bin:last_bin+1]\
+                                                        * unsmeared_output[first_bin:last_bin+1]\
+                                                        / output[first_bin:last_bin+1]
+                unsmeared_error[first_bin:last_bin+1] = self.data.dy[first_bin:last_bin+1]\
+                                                        * unsmeared_output[first_bin:last_bin+1]\
+                                                        / output[first_bin:last_bin+1]
+                unsmeared_output=unsmeared_output[index]
+                unsmeared_data=unsmeared_data[index]
+                unsmeared_error=unsmeared_error
         else:
             output[index] = self.model.evalDistribution(self.data.x[index])
