Index: src/sas/sascalc/calculator/c_extensions/librefl.c
===================================================================
--- src/sas/sascalc/calculator/c_extensions/librefl.c	(revision f54e82cf5664e7969aeaa5c2abb7c1edce590c27)
+++ src/sas/sascalc/calculator/c_extensions/librefl.c	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -7,5 +7,5 @@
 #include <stdio.h>
 #include <stdlib.h>
-#if defined(_MSC_VER)
+#if defined _MSC_VER  || defined __TINYCC__
 #define NEED_ERF
 #endif
@@ -21,5 +21,14 @@
 
 
-#ifdef _WIN32
+#ifdef __TINYCC__
+# ifdef isnan
+#   undef isnan
+# endif
+# ifdef isfinite
+#   undef isfinite
+# endif
+# define isnan(x) (x != x)
+# define isfinite(x) (x != INFINITY && x != -INFINITY)
+#elif defined _WIN32
 # include <float.h>
 # if !defined __MINGW32__ || defined __NO_ISOCEXT
@@ -30,6 +39,6 @@
 #   define isinf(x) (!_finite(x) && !_isnan(x))
 #  endif
-#  ifndef finite
-#   define finite(x) _finite(x)
+#  ifndef isfinite
+#   define isfinite(x) _finite(x)
 #  endif
 # endif
@@ -84,5 +93,5 @@
 double erf(double x)
 {
-    if (!finite(x)) {
+    if (!isfinite(x)) {
         if (isnan(x)) return x;      /* erf(NaN)   = NaN   */
         return (x>0 ? 1.0 : -1.0);   /* erf(+-inf) = +-1.0 */
@@ -94,5 +103,5 @@
 double erfc(double x)
 {
-    if (!finite(x)) {
+    if (!isfinite(x)) {
         if (isnan(x)) return x;      /* erfc(NaN)   = NaN      */
         return (x>0 ? 0.0 : 2.0);    /* erfc(+-inf) = 0.0, 2.0 */
Index: src/sas/sascalc/calculator/c_extensions/sld2i.c
===================================================================
--- src/sas/sascalc/calculator/c_extensions/sld2i.c	(revision f54e82cf5664e7969aeaa5c2abb7c1edce590c27)
+++ src/sas/sascalc/calculator/c_extensions/sld2i.c	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -25,8 +25,9 @@
  * @param s_theta: angle (from x-axis) of the up spin in degree
  */
-void initGenI(GenI* this, int npix, double* x, double* y, double* z, double* sldn,
+void initGenI(GenI* this, int is_avg, int npix, double* x, double* y, double* z, double* sldn,
 			double* mx, double* my, double* mz, double* voli,
 			double in_spin, double out_spin,
 			double s_theta) {
+	this->is_avg = is_avg;
 	this->n_pix = npix;
 	this->x_val = x;
@@ -63,8 +64,6 @@
 	Cplx temp_fi;
 
+	double count = 0.0;
 	int i, j;
-
-	double count = 0.0;
-	//check if this computation is for averaging
 
 	cassign(&iqr, 0.0, 0.0);
@@ -78,4 +77,6 @@
 
 	// Loop over q-values and multiply apply matrix
+
+	//printf("npoints: %d, npix: %d\n", npoints, this->n_pix);
 	for(i=0; i<npoints; i++){
 		//I_out[i] = 0.0;
@@ -86,4 +87,5 @@
 		//printf("i: %d\n", i);
 		//q = sqrt(qx[i]*qx[i] + qy[i]*qy[i]); // + qz[i]*qz[i]);
+
 		for(j=0; j<this->n_pix; j++){
 			if (this->sldn_val[j]!=0.0
@@ -143,5 +145,5 @@
 		I_out[i] *= (1.0E+8 / count); //in cm (unit) / number; //to be multiplied by vol_pix
 	}
-	//printf ("count = %d %g %g %g %g\n", count, sldn_val[0],mx_val[0], my_val[0], mz_val[0]);
+	//printf("count = %d %g %g %g %g\n", count, this->sldn_val[0],this->mx_val[0], this->my_val[0], this->mz_val[0]);
 }
 /**
@@ -154,19 +156,18 @@
 	// Assumes that q doesn't have qz component and sld_n is all real
 	//double Pi = 4.0*atan(1.0);
-	int is_sym = this->n_pix < 0;
 	double qr = 0.0;
 	double sumj;
 	double sld_j = 0.0;
 	double count = 0.0;
-	int n_pix = is_sym ? -this->n_pix : this->n_pix;
+	int i, j, k;
+
 	//Assume that pixel volumes are given in vol_pix in A^3 unit
 	// Loop over q-values and multiply apply matrix
-    int i, j, k;
 	for(i=0; i<npoints; i++){
 		sumj =0.0;
-		for(j=0; j<n_pix; j++){
+		for(j=0; j<this->n_pix; j++){
 			//Isotropic: Assumes all slds are real (no magnetic)
 			//Also assumes there is no polarization: No dependency on spin
-			if (is_sym == 1){
+			if (this->is_avg == 1){
 				// approximation for a spherical symmetric particle
 				qr = sqrt(this->x_val[j]*this->x_val[j]+this->y_val[j]*this->y_val[j]+this->z_val[j]*this->z_val[j])*q[i];
@@ -182,5 +183,5 @@
 				//full calculation
 				//pragma omp parallel for
-				for(k=0; k<n_pix; k++){
+				for(k=0; k<this->n_pix; k++){
 					sld_j =  this->sldn_val[j] * this->sldn_val[k] * this->vol_pix[j] * this->vol_pix[k];
 					qr = (this->x_val[j]-this->x_val[k])*(this->x_val[j]-this->x_val[k])+
@@ -201,9 +202,9 @@
 		}
 		I_out[i] = sumj;
-		if (is_sym == 1){
+		if (this->is_avg == 1) {
 			I_out[i] *= sumj;
 		}
 		I_out[i] *= (1.0E+8 / count); //in cm (unit) / number; //to be multiplied by vol_pix
 	}
-	//printf ("count = %d %g %g %g %g\n", count, sldn_val[0],mx_val[0], my_val[0], mz_val[0]);
+	//printf("count = %d %g %g %g %g\n", count, sldn_val[0],mx_val[0], my_val[0], mz_val[0]);
 }
Index: src/sas/sascalc/calculator/c_extensions/sld2i.h
===================================================================
--- src/sas/sascalc/calculator/c_extensions/sld2i.h	(revision eca7c6f6e2ca0325599a4051ad6daefe074f983f)
+++ src/sas/sascalc/calculator/c_extensions/sld2i.h	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -10,4 +10,5 @@
 typedef struct {
 	// vectors
+	int is_avg;
 	int n_pix;
 	double* x_val;
@@ -26,6 +27,6 @@
 
 // Constructor
-void initGenI(GenI*, int npix, double* x, double* y, double* z, double* sldn,
-		double* mx, double* my, double* mz, double* voli,
+void initGenI(GenI*, int is_avg, int npix, double* x, double* y, double* z,
+		double* sldn, double* mx, double* my, double* mz, double* voli,
 		double in_spin, double out_spin,
 		double s_theta);
Index: src/sas/sascalc/calculator/c_extensions/sld2i_module.c
===================================================================
--- src/sas/sascalc/calculator/c_extensions/sld2i_module.c	(revision f54e82cf5664e7969aeaa5c2abb7c1edce590c27)
+++ src/sas/sascalc/calculator/c_extensions/sld2i_module.c	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -35,5 +35,9 @@
 void
 del_sld2i(PyObject *obj){
+#if PY_MAJOR_VERSION < 3
+	GenI* sld2i = (GenI *)obj;
+#else
 	GenI* sld2i = (GenI *)(PyCapsule_GetPointer(obj, "GenI"));
+#endif
 	PyMem_Free((void *)sld2i);
 }
@@ -51,10 +55,6 @@
 	PyObject *mz_val_obj;
 	PyObject *vol_pix_obj;
-	Py_ssize_t n_x;
-	//PyObject rlimit_obj;
-	//PyObject npoints_obj;
-	//PyObject nrbins_obj;
-	//PyObject nphibins_obj;
-	int n_pix;
+	Py_ssize_t n_x, n_y, n_z, n_sld, n_mx, n_my, n_mz, n_vol_pix;
+	int is_avg;
 	double* x_val;
 	double* y_val;
@@ -68,20 +68,25 @@
 	double outspin;
 	double stheta;
-	GenI *sld2i;
-
-	if (!PyArg_ParseTuple(args, "iOOOOOOOOddd", &n_pix, &x_val_obj, &y_val_obj, &z_val_obj, &sldn_val_obj, &mx_val_obj, &my_val_obj, &mz_val_obj, &vol_pix_obj, &inspin, &outspin, &stheta)) return NULL;
-	OUTVECTOR(x_val_obj, x_val, n_x);
-	OUTVECTOR(y_val_obj, y_val, n_x);
-	OUTVECTOR(z_val_obj, z_val, n_x);
-	OUTVECTOR(sldn_val_obj, sldn_val, n_x);
-	OUTVECTOR(mx_val_obj, mx_val, n_x);
-	OUTVECTOR(my_val_obj, my_val, n_x);
-	OUTVECTOR(mz_val_obj, mz_val, n_x);
-	OUTVECTOR(vol_pix_obj, vol_pix, n_x);
-	sld2i =  PyMem_Malloc(sizeof(GenI));
+	PyObject *obj;
+	GenI* sld2i;
+
+	//printf("new GenI\n");
+	if (!PyArg_ParseTuple(args, "iOOOOOOOOddd", &is_avg, &x_val_obj, &y_val_obj, &z_val_obj, &sldn_val_obj, &mx_val_obj, &my_val_obj, &mz_val_obj, &vol_pix_obj, &inspin, &outspin, &stheta)) return NULL;
+	INVECTOR(x_val_obj, x_val, n_x);
+	INVECTOR(y_val_obj, y_val, n_y);
+	INVECTOR(z_val_obj, z_val, n_z);
+	INVECTOR(sldn_val_obj, sldn_val, n_sld);
+	INVECTOR(mx_val_obj, mx_val, n_mx);
+	INVECTOR(my_val_obj, my_val, n_my);
+	INVECTOR(mz_val_obj, mz_val, n_mz);
+	INVECTOR(vol_pix_obj, vol_pix, n_vol_pix);
+	sld2i = PyMem_Malloc(sizeof(GenI));
+	//printf("sldi:%p\n", sld2i);
 	if (sld2i != NULL) {
-		initGenI(sld2i, n_pix,x_val,y_val,z_val,sldn_val,mx_val,my_val,mz_val,vol_pix,inspin,outspin,stheta);
+		initGenI(sld2i,is_avg,(int)n_x,x_val,y_val,z_val,sldn_val,mx_val,my_val,mz_val,vol_pix,inspin,outspin,stheta);
 	}
-	return PyCapsule_New(sld2i, "GenI", del_sld2i);
+	obj = PyCapsule_New(sld2i, "GenI", del_sld2i);
+	//printf("constructed %p\n", obj);
+	return obj;
 }
 
@@ -90,27 +95,27 @@
  */
 PyObject * genicom_inputXY(PyObject *self, PyObject *args) {
-	int npoints;
+	PyObject *gen_obj;
 	PyObject *qx_obj;
+	PyObject *qy_obj;
+	PyObject *I_out_obj;
+	Py_ssize_t n_qx, n_qy, n_out;
 	double *qx;
-	PyObject *qy_obj;
 	double *qy;
-	PyObject *I_out_obj;
-	Py_ssize_t n_out;
 	double *I_out;
-	PyObject *gen_obj;
-	GenI *sld2i;
-
-	if (!PyArg_ParseTuple(args, "OiOOO",  &gen_obj, &npoints, &qx_obj, &qy_obj, &I_out_obj)) return NULL;
-	OUTVECTOR(qx_obj, qx, n_out);
-	OUTVECTOR(qy_obj, qy, n_out);
+	GenI* sld2i;
+
+	//printf("in genicom_inputXY\n");
+	if (!PyArg_ParseTuple(args, "OOOO",  &gen_obj, &qx_obj, &qy_obj, &I_out_obj)) return NULL;
+	sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI");
+	INVECTOR(qx_obj, qx, n_qx);
+	INVECTOR(qy_obj, qy, n_qy);
 	OUTVECTOR(I_out_obj, I_out, n_out);
+	//printf("qx, qy, I_out: %d %d %d, %d %d %d\n", qx, qy, I_out, n_qx, n_qy, n_out);
 
 	// Sanity check
-	//if(n_in!=n_out) return Py_BuildValue("i",-1);
-
-	// Set the array pointers
-	sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI");
-
-	genicomXY(sld2i, npoints, qx, qy, I_out);
+	//if(n_q!=n_out) return Py_BuildValue("i",-1);
+
+	genicomXY(sld2i, (int)n_qx, qx, qy, I_out);
+	//printf("done calc\n");
 	//return PyCObject_FromVoidPtr(s, del_genicom);
 	return Py_BuildValue("i",1);
@@ -121,25 +126,21 @@
  */
 PyObject * genicom_input(PyObject *self, PyObject *args) {
-	int npoints;
+	PyObject *gen_obj;
 	PyObject *q_obj;
+	PyObject *I_out_obj;
+	Py_ssize_t n_q, n_out;
 	double *q;
-	PyObject *I_out_obj;
-	Py_ssize_t n_out;
 	double *I_out;
-	PyObject *gen_obj;
 	GenI *sld2i;
 
-	if (!PyArg_ParseTuple(args, "OiOO",  &gen_obj, &npoints, &q_obj, &I_out_obj)) return NULL;
-	OUTVECTOR(q_obj, q, n_out);
+	if (!PyArg_ParseTuple(args, "OOO",  &gen_obj, &q_obj, &I_out_obj)) return NULL;
+	sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI");
+	INVECTOR(q_obj, q, n_q);
 	OUTVECTOR(I_out_obj, I_out, n_out);
 
 	// Sanity check
-	//if(n_in!=n_out) return Py_BuildValue("i",-1);
-
-	// Set the array pointers
-	sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI");
-
-	genicom(sld2i, npoints, q, I_out);
-	//return PyCObject_FromVoidPtr(s, del_genicom);
+	//if (n_q!=n_out) return Py_BuildValue("i",-1);
+
+	genicom(sld2i, (int)n_q, q, I_out);
 	return Py_BuildValue("i",1);
 }
Index: src/sas/sascalc/calculator/instrument.py
===================================================================
--- src/sas/sascalc/calculator/instrument.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/calculator/instrument.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -314,5 +314,5 @@
         """
         To plot the wavelength spactrum
-        : requirment: matplotlib.pyplot
+        : requirement: matplotlib.pyplot
         """
         try:
Index: src/sas/sascalc/calculator/resolution_calculator.py
===================================================================
--- src/sas/sascalc/calculator/resolution_calculator.py	(revision 8f83719fd67e6a72acdcd666e7bf1e2326b52cd0)
+++ src/sas/sascalc/calculator/resolution_calculator.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -1007,6 +1007,6 @@
         try:
             detector_offset = self.sample2detector_distance[1]
-        except Exception as ex:
-            logger.error(ex)
+        except:
+            logger.error(sys.exc_value)
 
         # detector size in [no of pix_x,no of pix_y]
@@ -1057,7 +1057,7 @@
         # qx_value and qy_value values in array
         qx_value = qx_value.repeat(detector_pix_nums_y)
-        qx_value = qx_value.reshape(int(detector_pix_nums_x), int(detector_pix_nums_y))
+        qx_value = qx_value.reshape(detector_pix_nums_x, detector_pix_nums_y)
         qy_value = qy_value.repeat(detector_pix_nums_x)
-        qy_value = qy_value.reshape(int(detector_pix_nums_y), int(detector_pix_nums_x))
+        qy_value = qy_value.reshape(detector_pix_nums_y, detector_pix_nums_x)
         qy_value = qy_value.transpose()
 
@@ -1094,6 +1094,6 @@
             output.qx_data = qx_value
             output.qy_data = qy_value
-        except Exception as ex:
-            logger.error(ex)
+        except:
+            logger.error(sys.exc_value)
 
         return output
Index: src/sas/sascalc/calculator/sas_gen.py
===================================================================
--- src/sas/sascalc/calculator/sas_gen.py	(revision b58265c3c76f95c80a659bfb713f1605c80532a6)
+++ src/sas/sascalc/calculator/sas_gen.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -118,5 +118,5 @@
         self.is_avg = is_avg
 
-    def _gen(self, x, y, i):
+    def _gen(self, qx, qy):
         """
         Evaluate the function
@@ -129,24 +129,35 @@
         pos_y = self.data_y
         pos_z = self.data_z
-        len_x = len(pos_x)
         if self.is_avg is None:
-            len_x *= -1
             pos_x, pos_y, pos_z = transform_center(pos_x, pos_y, pos_z)
-        len_q = len(x)
         sldn = copy.deepcopy(self.data_sldn)
         sldn -= self.params['solvent_SLD']
-        model = mod.new_GenI(len_x, pos_x, pos_y, pos_z,
-                             sldn, self.data_mx, self.data_my,
-                             self.data_mz, self.data_vol,
-                             self.params['Up_frac_in'],
-                             self.params['Up_frac_out'],
-                             self.params['Up_theta'])
-        if y == []:
-            mod.genicom(model, len_q, x, i)
-        else:
-            mod.genicomXY(model, len_q, x, y, i)
+        # **** WARNING **** new_GenI holds pointers to numpy vectors
+        # be sure that they are contiguous double precision arrays and make 
+        # sure the GC doesn't eat them before genicom is called.
+        # TODO: rewrite so that the parameters are passed directly to genicom
+        args = (
+            (1 if self.is_avg else 0),
+            pos_x, pos_y, pos_z,
+            sldn, self.data_mx, self.data_my,
+            self.data_mz, self.data_vol,
+            self.params['Up_frac_in'],
+            self.params['Up_frac_out'],
+            self.params['Up_theta'])
+        model = mod.new_GenI(*args)
+        if len(qy):
+            qx, qy = _vec(qx), _vec(qy)
+            I_out = np.empty_like(qx)
+            #print("npoints", qx.shape, "npixels", pos_x.shape)
+            mod.genicomXY(model, qx, qy, I_out)
+            #print("I_out after", I_out)
+        else:
+            qx = _vec(qx)
+            I_out = np.empty_like(qx)
+            mod.genicom(model, qx, I_out)
         vol_correction = self.data_total_volume / self.params['total_volume']
-        return  self.params['scale'] * vol_correction * i + \
-                        self.params['background']
+        result = (self.params['scale'] * vol_correction * I_out
+                  + self.params['background'])
+        return result
 
     def set_sld_data(self, sld_data=None):
@@ -156,12 +167,12 @@
         self.sld_data = sld_data
         self.data_pos_unit = sld_data.pos_unit
-        self.data_x = sld_data.pos_x
-        self.data_y = sld_data.pos_y
-        self.data_z = sld_data.pos_z
-        self.data_sldn = sld_data.sld_n
-        self.data_mx = sld_data.sld_mx
-        self.data_my = sld_data.sld_my
-        self.data_mz = sld_data.sld_mz
-        self.data_vol = sld_data.vol_pix
+        self.data_x = _vec(sld_data.pos_x)
+        self.data_y = _vec(sld_data.pos_y)
+        self.data_z = _vec(sld_data.pos_z)
+        self.data_sldn = _vec(sld_data.sld_n)
+        self.data_mx = _vec(sld_data.sld_mx)
+        self.data_my = _vec(sld_data.sld_my)
+        self.data_mz = _vec(sld_data.sld_mz)
+        self.data_vol = _vec(sld_data.vol_pix)
         self.data_total_volume = sum(sld_data.vol_pix)
         self.params['total_volume'] = sum(sld_data.vol_pix)
@@ -180,11 +191,10 @@
         :return: (I value)
         """
-        if x.__class__.__name__ == 'list':
+        if isinstance(x, list):
             if len(x[1]) > 0:
                 msg = "Not a 1D."
                 raise ValueError(msg)
-            i_out = np.zeros_like(x[0])
             # 1D I is found at y =0 in the 2D pattern
-            out = self._gen(x[0], [], i_out)
+            out = self._gen(x[0], [])
             return out
         else:
@@ -199,8 +209,6 @@
         :Use this runXY() for the computation
         """
-        if x.__class__.__name__ == 'list':
-            i_out = np.zeros_like(x[0])
-            out = self._gen(x[0], x[1], i_out)
-            return out
+        if isinstance(x, list):
+            return self._gen(x[0], x[1])
         else:
             msg = "Q must be given as list of qx's and qy's"
@@ -214,14 +222,13 @@
                       where qx,qy are 1D ndarrays (for 2D).
         """
-        if qdist.__class__.__name__ == 'list':
-            if len(qdist[1]) < 1:
-                out = self.run(qdist)
-            else:
-                out = self.runXY(qdist)
-            return out
+        if isinstance(qdist, list):
+            return self.run(qdist) if len(qdist[1]) < 1 else self.runXY(qdist)
         else:
             mesg = "evalDistribution is expecting an ndarray of "
             mesg += "a list [qx,qy] where qx,qy are arrays."
             raise RuntimeError(mesg)
+
+def _vec(v):
+    return np.ascontiguousarray(v, 'd')
 
 class OMF2SLD(object):
@@ -1041,4 +1048,10 @@
         self.line_z = line_z
 
+def _get_data_path(*path_parts):
+    from os.path import realpath, join as joinpath, dirname, abspath
+    # in sas/sascalc/calculator;  want sas/sasview/test
+    return joinpath(dirname(realpath(__file__)),
+                    '..', '..', 'sasview', 'test', *path_parts)
+
 def test_load():
     """
@@ -1046,18 +1059,12 @@
     """
     from mpl_toolkits.mplot3d import Axes3D
-    current_dir = os.path.abspath(os.path.curdir)
-    print(current_dir)
-    for i in range(6):
-        current_dir, _ = os.path.split(current_dir)
-        tfile = os.path.join(current_dir, "test", "CoreXY_ShellZ.txt")
-        ofile = os.path.join(current_dir, "test", "A_Raw_Example-1.omf")
-        if os.path.isfile(tfile):
-            tfpath = tfile
-            ofpath = ofile
-            break
+    tfpath = _get_data_path("1d_data", "CoreXY_ShellZ.txt")
+    ofpath = _get_data_path("coordinate_data", "A_Raw_Example-1.omf")
+    if not os.path.isfile(tfpath) or not os.path.isfile(ofpath):
+        raise ValueError("file(s) not found: %r, %r"%(tfpath, ofpath))
     reader = SLDReader()
     oreader = OMFReader()
-    output = decode(reader.read(tfpath))
-    ooutput = decode(oreader.read(ofpath))
+    output = reader.read(tfpath)
+    ooutput = oreader.read(ofpath)
     foutput = OMF2SLD()
     foutput.set_data(ooutput)
@@ -1088,30 +1095,34 @@
     plt.show()
 
+def test_save():
+    ofpath = _get_data_path("coordinate_data", "A_Raw_Example-1.omf")
+    if not os.path.isfile(ofpath):
+        raise ValueError("file(s) not found: %r"%(ofpath,))
+    oreader = OMFReader()
+    omfdata = oreader.read(ofpath)
+    omf2sld = OMF2SLD()
+    omf2sld.set_data(omfdata)
+    writer = SLDReader()
+    writer.write("out.txt", omf2sld.output)
+
 def test():
     """
         Test code
     """
-    current_dir = os.path.abspath(os.path.curdir)
-    for i in range(3):
-        current_dir, _ = os.path.split(current_dir)
-        ofile = os.path.join(current_dir, "test", "A_Raw_Example-1.omf")
-        if os.path.isfile(ofile):
-            ofpath = ofile
-            break
+    ofpath = _get_data_path("coordinate_data", "A_Raw_Example-1.omf")
+    if not os.path.isfile(ofpath):
+        raise ValueError("file(s) not found: %r"%(ofpath,))
     oreader = OMFReader()
-    ooutput = decode(oreader.read(ofpath))
-    foutput = OMF2SLD()
-    foutput.set_data(ooutput)
-    writer = SLDReader()
-    writer.write(os.path.join(os.path.dirname(ofpath), "out.txt"),
-                 foutput.output)
+    omfdata = oreader.read(ofpath)
+    omf2sld = OMF2SLD()
+    omf2sld.set_data(omfdata)
     model = GenSAS()
-    model.set_sld_data(foutput.output)
-    x = np.arange(1000)/10000. + 1e-5
-    y = np.arange(1000)/10000. + 1e-5
-    i = np.zeros(1000)
-    model.runXY([x, y, i])
+    model.set_sld_data(omf2sld.output)
+    x = np.linspace(0, 0.1, 11)[1:]
+    return model.runXY([x, x])
 
 if __name__ == "__main__":
+    #test_load()
+    #test_save()
+    #print(test())
     test()
-    test_load()
Index: src/sas/sascalc/dataloader/data_info.py
===================================================================
--- src/sas/sascalc/dataloader/data_info.py	(revision 749b715f280e81297ccee885592a53f964909d62)
+++ src/sas/sascalc/dataloader/data_info.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -775,5 +775,4 @@
         clone.meta_data = deepcopy(self.meta_data)
         clone.errors = deepcopy(self.errors)
-        clone.isSesans = self.isSesans
 
         return clone
Index: src/sas/sascalc/dataloader/file_reader_base_class.py
===================================================================
--- src/sas/sascalc/dataloader/file_reader_base_class.py	(revision deaa0c6b324db1003ba4999149364cd82185294e)
+++ src/sas/sascalc/dataloader/file_reader_base_class.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -7,5 +7,5 @@
 import os
 import sys
-import re
+import math
 import logging
 from abc import abstractmethod
@@ -26,11 +26,16 @@
         return s.decode() if isinstance(s, bytes) else s
 
+# Data 1D fields for iterative purposes
+FIELDS_1D = ('x', 'y', 'dx', 'dy', 'dxl', 'dxw')
+# Data 2D fields for iterative purposes
+FIELDS_2D = ('data', 'qx_data', 'qy_data', 'q_data', 'err_data',
+                 'dqx_data', 'dqy_data', 'mask')
+DEPRECATION_MESSAGE = ("\rThe extension of this file suggests the data set migh"
+                       "t not be fully reduced. Support for the reader associat"
+                       "ed with this file type has been removed. An attempt to "
+                       "load the file was made, but, should it be successful, "
+                       "SasView cannot guarantee the accuracy of the data.")
+
 class FileReader(object):
-    # List of Data1D and Data2D objects to be sent back to data_loader
-    output = []
-    # Current plottable_(1D/2D) object being loaded in
-    current_dataset = None
-    # Current DataInfo object being loaded in
-    current_datainfo = None
     # String to describe the type of data this reader can load
     type_name = "ASCII"
@@ -39,13 +44,25 @@
     # List of allowed extensions
     ext = ['.txt']
+    # Deprecated extensions
+    deprecated_extensions = ['.asc', '.nxs']
     # Bypass extension check and try to load anyway
     allow_all = False
     # Able to import the unit converter
     has_converter = True
-    # Open file handle
-    f_open = None
     # Default value of zero
     _ZERO = 1e-16
 
+    def __init__(self):
+        # List of Data1D and Data2D objects to be sent back to data_loader
+        self.output = []
+        # Current plottable_(1D/2D) object being loaded in
+        self.current_dataset = None
+        # Current DataInfo object being loaded in
+        self.current_datainfo = None
+        # File path sent to reader
+        self.filepath = None
+        # Open file handle
+        self.f_open = None
+
     def read(self, filepath):
         """
@@ -54,4 +71,5 @@
         :param filepath: The full or relative path to a file to be loaded
         """
+        self.filepath = filepath
         if os.path.isfile(filepath):
             basename, extension = os.path.splitext(os.path.basename(filepath))
@@ -75,4 +93,7 @@
                     if not self.f_open.closed:
                         self.f_open.close()
+                    if any(filepath.lower().endswith(ext) for ext in
+                           self.deprecated_extensions):
+                        self.handle_error_message(DEPRECATION_MESSAGE)
                     if len(self.output) > 0:
                         # Sort the data that's been loaded
@@ -85,5 +106,18 @@
 
         # Return a list of parsed entries that data_loader can manage
-        return self.output
+        final_data = self.output
+        self.reset_state()
+        return final_data
+
+    def reset_state(self):
+        """
+        Resets the class state to a base case when loading a new data file so previous
+        data files do not appear a second time
+        """
+        self.current_datainfo = None
+        self.current_dataset = None
+        self.filepath = None
+        self.ind = None
+        self.output = []
 
     def nextline(self):
@@ -112,5 +146,5 @@
         """
         Generic error handler to add an error to the current datainfo to
-        propogate the error up the error chain.
+        propagate the error up the error chain.
         :param msg: Error message
         """
@@ -121,4 +155,5 @@
         else:
             logger.warning(msg)
+            raise NoKnownLoaderException(msg)
 
     def send_to_output(self):
@@ -142,24 +177,25 @@
                 # Sort data by increasing x and remove 1st point
                 ind = np.lexsort((data.y, data.x))
-                data.x = np.asarray([data.x[i] for i in ind]).astype(np.float64)
-                data.y = np.asarray([data.y[i] for i in ind]).astype(np.float64)
+                data.x = self._reorder_1d_array(data.x, ind)
+                data.y = self._reorder_1d_array(data.y, ind)
                 if data.dx is not None:
                     if len(data.dx) == 0:
                         data.dx = None
                         continue
-                    data.dx = np.asarray([data.dx[i] for i in ind]).astype(np.float64)
+                    data.dx = self._reorder_1d_array(data.dx, ind)
                 if data.dxl is not None:
-                    data.dxl = np.asarray([data.dxl[i] for i in ind]).astype(np.float64)
+                    data.dxl = self._reorder_1d_array(data.dxl, ind)
                 if data.dxw is not None:
-                    data.dxw = np.asarray([data.dxw[i] for i in ind]).astype(np.float64)
+                    data.dxw = self._reorder_1d_array(data.dxw, ind)
                 if data.dy is not None:
                     if len(data.dy) == 0:
                         data.dy = None
                         continue
-                    data.dy = np.asarray([data.dy[i] for i in ind]).astype(np.float64)
+                    data.dy = self._reorder_1d_array(data.dy, ind)
                 if data.lam is not None:
-                    data.lam = np.asarray([data.lam[i] for i in ind]).astype(np.float64)
+                    data.lam = self._reorder_1d_array(data.lam, ind)
                 if data.dlam is not None:
-                    data.dlam = np.asarray([data.dlam[i] for i in ind]).astype(np.float64)
+                    data.dlam = self._reorder_1d_array(data.dlam, ind)
+                data = self._remove_nans_in_data(data)
                 if len(data.x) > 0:
                     data.xmin = np.min(data.x)
@@ -167,4 +203,42 @@
                     data.ymin = np.min(data.y)
                     data.ymax = np.max(data.y)
+
+    @staticmethod
+    def _reorder_1d_array(array, ind):
+        """
+        Reorders a 1D array based on the indices passed as ind
+        :param array: Array to be reordered
+        :param ind: Indices used to reorder array
+        :return: reordered array
+        """
+        array = np.asarray(array, dtype=np.float64)
+        return array[ind]
+
+    @staticmethod
+    def _remove_nans_in_data(data):
+        """
+        Remove data points where nan is loaded
+        :param data: 1D or 2D data object
+        :return: data with nan points removed
+        """
+        if isinstance(data, Data1D):
+            fields = FIELDS_1D
+        elif isinstance(data, Data2D):
+            fields = FIELDS_2D
+        else:
+            return data
+        # Make array of good points - all others will be removed
+        good = np.isfinite(getattr(data, fields[0]))
+        for name in fields[1:]:
+            array = getattr(data, name)
+            if array is not None:
+                # Update good points only if not already changed
+                good &= np.isfinite(array)
+        if not np.all(good):
+            for name in fields:
+                array = getattr(data, name)
+                if array is not None:
+                    setattr(data, name, array[good])
+        return data
 
     def sort_two_d_data(self):
@@ -197,4 +271,5 @@
                     dataset.x_bins = dataset.qx_data[:int(n_cols)]
                 dataset.data = dataset.data.flatten()
+                dataset = self._remove_nans_in_data(dataset)
                 if len(dataset.data) > 0:
                     dataset.xmin = np.min(dataset.qx_data)
@@ -314,5 +389,5 @@
     def splitline(line):
         """
-        Splits a line into pieces based on common delimeters
+        Splits a line into pieces based on common delimiters
         :param line: A single line of text
         :return: list of values
Index: src/sas/sascalc/dataloader/loader.py
===================================================================
--- src/sas/sascalc/dataloader/loader.py	(revision dc8d1c2838582489b1d85751d7e27f7348c8685c)
+++ src/sas/sascalc/dataloader/loader.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -90,4 +90,6 @@
             ascii_loader = ascii_reader.Reader()
             return ascii_loader.read(path)
+        except NoKnownLoaderException:
+            pass  # Try the Cansas XML reader
         except DefaultReaderException:
             pass  # Loader specific error to try the cansas XML reader
@@ -100,4 +102,6 @@
             cansas_loader = cansas_reader.Reader()
             return cansas_loader.read(path)
+        except NoKnownLoaderException:
+            pass  # Try the NXcanSAS reader
         except DefaultReaderException:
             pass  # Loader specific error to try the NXcanSAS reader
Index: src/sas/sascalc/dataloader/readers/abs_reader.py
===================================================================
--- src/sas/sascalc/dataloader/readers/abs_reader.py	(revision 1efbc190a388190d54fbdbcf384110dd991977fe)
+++ src/sas/sascalc/dataloader/readers/abs_reader.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -29,7 +29,7 @@
     type_name = "IGOR 1D"
     # Wildcards
-    type = ["IGOR 1D files (*.abs)|*.abs"]
+    type = ["IGOR 1D files (*.abs)|*.abs", "IGOR 1D USANS files (*.cor)|*.cor"]
     # List of allowed extensions
-    ext = ['.abs']
+    ext = ['.abs', '.cor']
 
     def get_file_contents(self):
@@ -46,5 +46,4 @@
         self.current_datainfo = DataInfo()
         self.current_datainfo.filename = filepath
-        self.reset_data_list(len(lines))
         detector = Detector()
         data_line = 0
@@ -172,5 +171,5 @@
 
                 try:
-                    _x = float(toks[0])
+                    _x = float(toks[4])
                     _y = float(toks[1])
                     _dy = float(toks[2])
@@ -188,5 +187,13 @@
                     self.current_dataset.y[data_line] = _y
                     self.current_dataset.dy[data_line] = _dy
-                    self.current_dataset.dx[data_line] = _dx
+                    if _dx > 0:
+                        self.current_dataset.dx[data_line] = _dx
+                    else:
+                        if data_line == 0:
+                            self.current_dataset.dx = None
+                            self.current_dataset.dxl = np.zeros(len(lines))
+                            self.current_dataset.dxw = np.zeros(len(lines))
+                        self.current_dataset.dxl[data_line] = abs(_dx)
+                        self.current_dataset.dxw[data_line] = 0
                     data_line += 1
 
@@ -197,7 +204,10 @@
                     pass
 
+            # SANS Data:
             # The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev.
             # I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|
-            if line.count("The 6 columns") > 0:
+            # USANS Data:
+            # EMP LEVEL: <value> ; BKG LEVEL: <value>
+            if line.startswith("The 6 columns") or line.startswith("EMP LEVEL"):
                 is_data_started = True
 
Index: src/sas/sascalc/dataloader/readers/associations.py
===================================================================
--- src/sas/sascalc/dataloader/readers/associations.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/dataloader/readers/associations.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -26,4 +26,5 @@
     ".dat": "red2d_reader",
     ".abs": "abs_reader",
+    ".cor": "abs_reader",
     ".sans": "danse_reader",
     ".pdh": "anton_paar_saxs_reader"
Index: src/sas/sascalc/dataloader/readers/cansas_reader.py
===================================================================
--- src/sas/sascalc/dataloader/readers/cansas_reader.py	(revision 2b538cdefcdc3d89de8c018fe7f225f875614c5a)
+++ src/sas/sascalc/dataloader/readers/cansas_reader.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -68,7 +68,5 @@
         data files do not appear a second time
         """
-        self.current_datainfo = None
-        self.current_dataset = None
-        self.current_data1d = None
+        super(Reader, self).reset_state()
         self.data = []
         self.process = Process()
@@ -79,5 +77,4 @@
         self.names = []
         self.cansas_defaults = {}
-        self.output = []
         self.ns_list = None
         self.logging = []
@@ -85,5 +82,5 @@
 
     def read(self, xml_file, schema_path="", invalid=True):
-        if schema_path != "" or invalid != True:
+        if schema_path != "" or not invalid:
             # read has been called from self.get_file_contents because xml file doens't conform to schema
             _, self.extension = os.path.splitext(os.path.basename(xml_file))
@@ -945,5 +942,5 @@
             pos, "z", datainfo.sample.position.z,
             {"unit": datainfo.sample.position_unit})
-        if written == True:
+        if written:
             self.append(pos, sample)
 
@@ -958,5 +955,5 @@
             ori, "yaw", datainfo.sample.orientation.z,
             {"unit": datainfo.sample.orientation_unit})
-        if written == True:
+        if written:
             self.append(ori, sample)
 
@@ -1005,5 +1002,5 @@
             size, "z", datainfo.source.beam_size.z,
             {"unit": datainfo.source.beam_size_unit})
-        if written == True:
+        if written:
             self.append(size, source)
 
@@ -1061,5 +1058,5 @@
                     size, "z", aperture.size.z,
                     {"unit": aperture.size_unit})
-                if written == True:
+                if written:
                     self.append(size, apert)
 
@@ -1084,5 +1081,5 @@
             written = written | self.write_node(det, "SDD", item.distance,
                                                 {"unit": item.distance_unit})
-            if written == True:
+            if written:
                 self.append(det, instr)
 
@@ -1094,5 +1091,5 @@
             written = written | self.write_node(off, "z", item.offset.z,
                                                 {"unit": item.offset_unit})
-            if written == True:
+            if written:
                 self.append(off, det)
 
@@ -1106,5 +1103,5 @@
                                                 item.orientation.z,
                                                 {"unit": item.orientation_unit})
-            if written == True:
+            if written:
                 self.append(ori, det)
 
@@ -1118,5 +1115,5 @@
                                                 item.beam_center.z,
                                                 {"unit": item.beam_center_unit})
-            if written == True:
+            if written:
                 self.append(center, det)
 
@@ -1128,5 +1125,5 @@
             written = written | self.write_node(pix, "z", item.pixel_size.z,
                                                 {"unit": item.pixel_size_unit})
-            if written == True:
+            if written:
                 self.append(pix, det)
             self.write_node(det, "slit_length", item.slit_length,
Index: src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py
===================================================================
--- src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py	(revision 2b538cdefcdc3d89de8c018fe7f225f875614c5a)
+++ src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -9,11 +9,15 @@
 import sys
 
-from sas.sascalc.dataloader.data_info import plottable_1D, plottable_2D,\
+from ..data_info import plottable_1D, plottable_2D,\
     Data1D, Data2D, DataInfo, Process, Aperture, Collimation, \
     TransmissionSpectrum, Detector
-from sas.sascalc.dataloader.data_info import combine_data_info_with_plottable
-
-
-class Reader():
+from ..data_info import combine_data_info_with_plottable
+from ..loader_exceptions import FileContentsException, DefaultReaderException
+from ..file_reader_base_class import FileReader, decode
+
+def h5attr(node, key, default=None):
+    return decode(node.attrs.get(key, default))
+
+class Reader(FileReader):
     """
     A class for reading in CanSAS v2.0 data files. The existing iteration opens
@@ -25,4 +29,5 @@
     Any number of SASdata sets may be present in a SASentry and the data within
     can be either 1D I(Q) or 2D I(Qx, Qy).
+
     Also supports reading NXcanSAS formatted HDF5 files
 
@@ -39,8 +44,4 @@
     # Raw file contents to be processed
     raw_data = None
-    # Data info currently being read in
-    current_datainfo = None
-    # SASdata set currently being read in
-    current_dataset = None
     # List of plottable1D objects that should be linked to the current_datainfo
     data1d = None
@@ -55,8 +56,6 @@
     # Flag to bypass extension check
     allow_all = True
-    # List of files to return
-    output = None
-
-    def read(self, filename):
+
+    def get_file_contents(self):
         """
         This is the general read method that all SasView data_loaders must have.
@@ -66,5 +65,9 @@
         """
         # Reinitialize when loading a new data file to reset all class variables
-        self.reset_class_variables()
+        self.reset_state()
+
+        filename = self.f_open.name
+        self.f_open.close() # IO handled by h5py
+
         # Check that the file exists
         if os.path.isfile(filename):
@@ -74,20 +77,33 @@
             if extension in self.ext or self.allow_all:
                 # Load the data file
-                self.raw_data = h5py.File(filename, 'r')
-                # Read in all child elements of top level SASroot
-                self.read_children(self.raw_data, [])
-                # Add the last data set to the list of outputs
-                self.add_data_set()
-                # Close the data file
-                self.raw_data.close()
-        # Return data set(s)
-        return self.output
-
-    def reset_class_variables(self):
+                try:
+                    self.raw_data = h5py.File(filename, 'r')
+                except Exception as e:
+                    if extension not in self.ext:
+                        msg = "CanSAS2.0 HDF5 Reader could not load file {}".format(basename + extension)
+                        raise DefaultReaderException(msg)
+                    raise FileContentsException(e.message)
+                try:
+                    # Read in all child elements of top level SASroot
+                    self.read_children(self.raw_data, [])
+                    # Add the last data set to the list of outputs
+                    self.add_data_set()
+                except Exception as exc:
+                    raise FileContentsException(exc.message)
+                finally:
+                    # Close the data file
+                    self.raw_data.close()
+
+                for dataset in self.output:
+                    if isinstance(dataset, Data1D):
+                        if dataset.x.size < 5:
+                            self.output = []
+                            raise FileContentsException("Fewer than 5 data points found.")
+
+    def reset_state(self):
         """
         Create the reader object and define initial states for class variables
         """
-        self.current_datainfo = None
-        self.current_dataset = None
+        super(Reader, self).reset_state()
         self.data1d = []
         self.data2d = []
@@ -95,5 +111,4 @@
         self.errors = set()
         self.logging = []
-        self.output = []
         self.parent_class = u''
         self.detector = Detector()
@@ -115,8 +130,7 @@
             # Get all information for the current key
             value = data.get(key)
-            if value.attrs.get(u'canSAS_class') is not None:
-                class_name = value.attrs.get(u'canSAS_class')
-            else:
-                class_name = value.attrs.get(u'NX_class')
+            class_name = h5attr(value, u'canSAS_class')
+            if class_name is None:
+                class_name = h5attr(value, u'NX_class')
             if class_name is not None:
                 class_prog = re.compile(class_name)
@@ -125,4 +139,5 @@
 
             if isinstance(value, h5py.Group):
+                # Set parent class before recursion
                 self.parent_class = class_name
                 parent_list.append(key)
@@ -135,4 +150,6 @@
                 # Recursion step to access data within the group
                 self.read_children(value, parent_list)
+                # Reset parent class when returning from recursive method
+                self.parent_class = class_name
                 self.add_intermediate()
                 parent_list.remove(key)
@@ -165,4 +182,13 @@
                         self.current_dataset.x = data_set.flatten()
                     continue
+                elif key == u'Qdev':
+                    self.current_dataset.dx = data_set.flatten()
+                    continue
+                elif key == u'dQw':
+                    self.current_dataset.dxw = data_set.flatten()
+                    continue
+                elif key == u'dQl':
+                    self.current_dataset.dxl = data_set.flatten()
+                    continue
                 elif key == u'Qy':
                     self.current_dataset.yaxis("Q_y", unit)
@@ -198,4 +224,9 @@
 
                 for data_point in data_set:
+                    if isinstance(data_point, np.ndarray):
+                        if data_point.dtype.char == 'S':
+                            data_point = decode(bytes(data_point))
+                    else:
+                        data_point = decode(data_point)
                     # Top Level Meta Data
                     if key == u'definition':
@@ -203,4 +234,10 @@
                     elif key == u'run':
                         self.current_datainfo.run.append(data_point)
+                        try:
+                            run_name = h5attr(value, 'name')
+                            run_dict = {data_point: run_name}
+                            self.current_datainfo.run_name = run_dict
+                        except Exception:
+                            pass
                     elif key == u'title':
                         self.current_datainfo.title = data_point
@@ -411,5 +448,4 @@
         Data1D and Data2D objects
         """
-
         # Type cast data arrays to float64
         if len(self.current_datainfo.trans_spectrum) > 0:
@@ -435,20 +471,4 @@
         # Type cast data arrays to float64 and find min/max as appropriate
         for dataset in self.data2d:
-            dataset.data = dataset.data.astype(np.float64)
-            dataset.err_data = dataset.err_data.astype(np.float64)
-            if dataset.qx_data is not None:
-                dataset.xmin = np.min(dataset.qx_data)
-                dataset.xmax = np.max(dataset.qx_data)
-                dataset.qx_data = dataset.qx_data.astype(np.float64)
-            if dataset.dqx_data is not None:
-                dataset.dqx_data = dataset.dqx_data.astype(np.float64)
-            if dataset.qy_data is not None:
-                dataset.ymin = np.min(dataset.qy_data)
-                dataset.ymax = np.max(dataset.qy_data)
-                dataset.qy_data = dataset.qy_data.astype(np.float64)
-            if dataset.dqy_data is not None:
-                dataset.dqy_data = dataset.dqy_data.astype(np.float64)
-            if dataset.q_data is not None:
-                dataset.q_data = dataset.q_data.astype(np.float64)
             zeros = np.ones(dataset.data.size, dtype=bool)
             try:
@@ -473,29 +493,10 @@
                 dataset.x_bins = dataset.qx_data[:n_cols]
                 dataset.data = dataset.data.flatten()
-
-            final_dataset = combine_data_info_with_plottable(
-                dataset, self.current_datainfo)
-            self.output.append(final_dataset)
+            self.current_dataset = dataset
+            self.send_to_output()
 
         for dataset in self.data1d:
-            if dataset.x is not None:
-                dataset.x = dataset.x.astype(np.float64)
-                dataset.xmin = np.min(dataset.x)
-                dataset.xmax = np.max(dataset.x)
-            if dataset.y is not None:
-                dataset.y = dataset.y.astype(np.float64)
-                dataset.ymin = np.min(dataset.y)
-                dataset.ymax = np.max(dataset.y)
-            if dataset.dx is not None:
-                dataset.dx = dataset.dx.astype(np.float64)
-            if dataset.dxl is not None:
-                dataset.dxl = dataset.dxl.astype(np.float64)
-            if dataset.dxw is not None:
-                dataset.dxw = dataset.dxw.astype(np.float64)
-            if dataset.dy is not None:
-                dataset.dy = dataset.dy.astype(np.float64)
-            final_dataset = combine_data_info_with_plottable(
-                dataset, self.current_datainfo)
-            self.output.append(final_dataset)
+            self.current_dataset = dataset
+            self.send_to_output()
 
     def add_data_set(self, key=""):
@@ -579,7 +580,7 @@
         :return: unit for the value passed to the method
         """
-        unit = value.attrs.get(u'units')
+        unit = h5attr(value, u'units')
         if unit is None:
-            unit = value.attrs.get(u'unit')
+            unit = h5attr(value, u'unit')
         # Convert the unit formats
         if unit == "1/A":
Index: src/sas/sascalc/dataloader/readers/danse_reader.py
===================================================================
--- src/sas/sascalc/dataloader/readers/danse_reader.py	(revision cee5c78929349ae10afc88cb8b95e0c907f1826a)
+++ src/sas/sascalc/dataloader/readers/danse_reader.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -157,5 +157,5 @@
         # Store all data
         # Store wavelength
-        if has_converter == True and self.current_datainfo.source.wavelength_unit != 'A':
+        if has_converter and self.current_datainfo.source.wavelength_unit != 'A':
             conv = Converter('A')
             wavelength = conv(wavelength,
@@ -164,5 +164,5 @@
 
         # Store distance
-        if has_converter == True and detector.distance_unit != 'm':
+        if has_converter and detector.distance_unit != 'm':
             conv = Converter('m')
             distance = conv(distance, units=detector.distance_unit)
@@ -170,5 +170,5 @@
 
         # Store pixel size
-        if has_converter == True and detector.pixel_size_unit != 'mm':
+        if has_converter and detector.pixel_size_unit != 'mm':
             conv = Converter('mm')
             pixel = conv(pixel, units=detector.pixel_size_unit)
@@ -191,5 +191,5 @@
         x_vals = np.tile(x_vals, (size_y, 1)).flatten()
         y_vals = np.tile(y_vals, (size_x, 1)).T.flatten()
-        if (np.all(self.current_dataset.err_data is None)
+        if (np.all(self.current_dataset.err_data == None)
                 or np.any(self.current_dataset.err_data <= 0)):
             new_err_data = np.sqrt(np.abs(self.current_dataset.data))
Index: src/sas/sascalc/dataloader/readers/sesans_reader.py
===================================================================
--- src/sas/sascalc/dataloader/readers/sesans_reader.py	(revision 849094a5f7b0f78510cbd819f7325b0940f60cdb)
+++ src/sas/sascalc/dataloader/readers/sesans_reader.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -12,5 +12,5 @@
 from ..file_reader_base_class import FileReader
 from ..data_info import plottable_1D, DataInfo
-from ..loader_exceptions import FileContentsException, DataReaderException
+from ..loader_exceptions import FileContentsException
 
 # Check whether we have a converter available
@@ -18,5 +18,5 @@
 try:
     from sas.sascalc.data_util.nxsunit import Converter
-except:
+except ImportError:
     has_converter = False
 _ZERO = 1e-16
@@ -46,5 +46,5 @@
         line = self.nextline()
         params = {}
-        while not line.startswith("BEGIN_DATA"):
+        while line and not line.startswith("BEGIN_DATA"):
             terms = line.split()
             if len(terms) >= 2:
@@ -63,10 +63,11 @@
             raise FileContentsException("Wavelength has no units")
         if params["SpinEchoLength_unit"] != params["Wavelength_unit"]:
-            raise FileContentsException("The spin echo data has rudely used "
-                               "different units for the spin echo length "
-                               "and the wavelength.  While sasview could "
-                               "handle this instance, it is a violation "
-                               "of the file format and will not be "
-                               "handled by other software.")
+            raise FileContentsException(
+                "The spin echo data has rudely used "
+                "different units for the spin echo length "
+                "and the wavelength.  While sasview could "
+                "handle this instance, it is a violation "
+                "of the file format and will not be "
+                "handled by other software.")
 
         headers = self.nextline().split()
@@ -86,5 +87,5 @@
 
         if not data.size:
-            raise FileContentsException("{} is empty".format(path))
+            raise FileContentsException("{} is empty".format(self.filepath))
         x = data[:, headers.index("SpinEchoLength")]
         if "SpinEchoLength_error" in headers:
Index: src/sas/sascalc/file_converter/otoko_loader.py
===================================================================
--- src/sas/sascalc/file_converter/otoko_loader.py	(revision 0b1a677a6bec9b3b30979ce36e64645b3028908b)
+++ src/sas/sascalc/file_converter/otoko_loader.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -36,5 +36,5 @@
 
         Given the paths of two header files, this function will load each axis in
-        turn.  If loading is successfull then an instance of the OTOKOData class
+        turn.  If loading is successful then an instance of the OTOKOData class
         will be returned, else an exception will be raised.
 
Index: src/sas/sascalc/fit/AbstractFitEngine.py
===================================================================
--- src/sas/sascalc/fit/AbstractFitEngine.py	(revision acd9c311d646eec7fe07d86d00622f80b6c7ecf6)
+++ src/sas/sascalc/fit/AbstractFitEngine.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -78,7 +78,7 @@
     def get_params(self, fitparams):
         """
-        return a list of value of paramter to fit
-
-        :param fitparams: list of paramaters name to fit
+        return a list of value of parameter to fit
+
+        :param fitparams: list of parameters name to fit
 
         """
Index: src/sas/sascalc/fit/MultiplicationModel.py
===================================================================
--- src/sas/sascalc/fit/MultiplicationModel.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/fit/MultiplicationModel.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -68,5 +68,5 @@
         try:
             multiplicity = p_model.multiplicity
-        except:
+        except AttributeError:
             multiplicity = 1
         ## functional multiplicity of the model
@@ -76,5 +76,5 @@
         self.non_fittable = p_model.non_fittable
         self.multiplicity_info = []
-        self.fun_list = {}
+        self.fun_list = []
         if self.non_fittable > 1:
             try:
@@ -82,5 +82,5 @@
                 self.fun_list = p_model.fun_list
                 self.is_multiplicity_model = True
-            except:
+            except AttributeError:
                 pass
         else:
Index: src/sas/sascalc/fit/pagestate.py
===================================================================
--- src/sas/sascalc/fit/pagestate.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/fit/pagestate.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -13,4 +13,5 @@
 ################################################################################
 import time
+import re
 import os
 import sys
@@ -646,4 +647,9 @@
                     name = value.split(':', 1)[1].strip()
                     file_value = "File name:" + name
+                    #Truncating string so print doesn't complain of being outside margins
+                    if sys.platform != "win32":
+                        MAX_STRING_LENGHT = 50
+                        if len(file_value) > MAX_STRING_LENGHT:
+                            file_value = "File name:.."+file_value[-MAX_STRING_LENGHT+10:]
                     file_name = CENTRE % file_value
                     if len(title) == 0:
@@ -721,9 +727,12 @@
         html_str, text_str, title = self._get_report_string()
         # Allow 2 figures to append
-        image_links = [FEET_2%fig for fig in fig_urls]
-
+        #Constraining image width for OSX and linux, so print doesn't complain of being outside margins
+        if sys.platform == "win32":
+            image_links = [FEET_2%fig for fig in fig_urls]
+        else:
+            image_links = [FEET_2_unix%fig for fig in fig_urls]
         # final report html strings
         report_str = html_str + ELINE.join(image_links)
-
+        report_str += FEET_3
         return report_str, text_str
 
@@ -954,6 +963,6 @@
         if node.get('version'):
             # Get the version for model conversion purposes
-            self.version = tuple(int(e) for e in
-                                 str.split(node.get('version'), "."))
+            x = re.sub('[^\d.]', '', node.get('version'))
+            self.version = tuple(int(e) for e in str.split(x, "."))
             # The tuple must be at least 3 items long
             while len(self.version) < 3:
@@ -1368,5 +1377,8 @@
 """
 FEET_2 = \
-"""<img src="%s" ></img>
+"""<img src="%s"></img>
+"""
+FEET_2_unix = \
+"""<img src="%s" width="540"></img>
 """
 FEET_3 = \
Index: src/sas/sascalc/fit/qsmearing.py
===================================================================
--- src/sas/sascalc/fit/qsmearing.py	(revision 50fcb09b3ee47cf23c26b90d9c291f41415c0aa5)
+++ src/sas/sascalc/fit/qsmearing.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -90,5 +90,5 @@
             #print "data1D.dx[0]",data1D.dx[0],data1D.dxl[0]
     # If we found resolution smearing data, return a QSmearer
-    if _found_resolution == True:
+    if _found_resolution:
          return pinhole_smear(data, model)
 
@@ -113,5 +113,5 @@
                 break
     # If we found slit smearing data, return a slit smearer
-    if _found_slit == True:
+    if _found_slit:
         return slit_smear(data, model)
     return None
Index: src/sas/sascalc/pr/c_extensions/Cinvertor.c
===================================================================
--- src/sas/sascalc/pr/c_extensions/Cinvertor.c	(revision d04ac056c476a91de374975fdb618e1cf1d27ca1)
+++ src/sas/sascalc/pr/c_extensions/Cinvertor.c	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -735,5 +735,5 @@
 
 const char get_peaks_doc[] =
-	"Returns the number of peaks in the output P(r) distrubution\n"
+	"Returns the number of peaks in the output P(r) distribution\n"
 	"for the given set of coefficients.\n"
 	" @param args: c-parameters\n"
Index: src/sas/sascalc/pr/fit/AbstractFitEngine.py
===================================================================
--- src/sas/sascalc/pr/fit/AbstractFitEngine.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/pr/fit/AbstractFitEngine.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -78,7 +78,7 @@
     def get_params(self, fitparams):
         """
-        return a list of value of paramter to fit
-
-        :param fitparams: list of paramaters name to fit
+        return a list of value of parameter to fit
+
+        :param fitparams: list of parameters name to fit
 
         """
Index: src/sas/sascalc/pr/invertor.py
===================================================================
--- src/sas/sascalc/pr/invertor.py	(revision 6da860acc5670055935e7bdc8678d3827d1a057f)
+++ src/sas/sascalc/pr/invertor.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -222,8 +222,5 @@
         elif name == 'est_bck':
             value = self.get_est_bck()
-            if value == 1:
-                return True
-            else:
-                return False
+            return value == 1
         elif name in self.__dict__:
             return self.__dict__[name]
@@ -460,5 +457,5 @@
 
         # If we need to fit the background, add a term
-        if self.est_bck == True:
+        if self.est_bck:
             nfunc_0 = nfunc
             nfunc += 1
@@ -500,11 +497,11 @@
             cov = np.linalg.pinv(inv_cov)
             err = math.fabs(chi2 / float(npts - nfunc)) * cov
-        except Exception as ex:
+        except:
             # We were not able to estimate the errors
             # Return an empty error matrix
-            logger.error(ex)
+            logger.error(sys.exc_value)
 
         # Keep a copy of the last output
-        if self.est_bck == False:
+        if not self.est_bck:
             self.out = c
             self.cov = err
@@ -540,13 +537,13 @@
 
         """
-        from sas.sascalc.pr.num_term import NTermEstimator
+        from .num_term import NTermEstimator
         estimator = NTermEstimator(self.clone())
         try:
             return estimator.num_terms(isquit_func)
-        except Exception as ex:
+        except:
             # If we fail, estimate alpha and return the default
             # number of terms
             best_alpha, _, _ = self.estimate_alpha(self.nfunc)
-            logger.warning("Invertor.estimate_numterms: %s" % ex)
+            logger.warning("Invertor.estimate_numterms: %s" % sys.exc_value)
             return self.nfunc, best_alpha, "Could not estimate number of terms"
 
@@ -634,6 +631,6 @@
                 return best_alpha, message, elapsed
 
-        except Exception as ex:
-            message = "Invertor.estimate_alpha: %s" % ex
+        except:
+            message = "Invertor.estimate_alpha: %s" % sys.exc_value
             return 0, message, elapsed
 
@@ -658,5 +655,5 @@
         file.write("#slit_width=%g\n" % self.slit_width)
         file.write("#background=%g\n" % self.background)
-        if self.est_bck == True:
+        if self.est_bck:
             file.write("#has_bck=1\n")
         else:
@@ -738,8 +735,5 @@
                     elif line.startswith('#has_bck='):
                         toks = line.split('=')
-                        if int(toks[1]) == 1:
-                            self.est_bck = True
-                        else:
-                            self.est_bck = False
+                        self.est_bck = int(toks[1]) == 1
 
                     # Now read in the parameters
@@ -754,6 +748,6 @@
                         self.cov[i][i] = float(toks2[1])
 
-            except Exception as ex:
-                msg = "Invertor.from_file: corrupted file\n%s" % ex
+            except:
+                msg = "Invertor.from_file: corrupted file\n%s" % sys.exc_value
                 raise RuntimeError(msg)
         else:
Index: src/sas/sascalc/pr/num_term.py
===================================================================
--- src/sas/sascalc/pr/num_term.py	(revision 8f83719fd67e6a72acdcd666e7bf1e2326b52cd0)
+++ src/sas/sascalc/pr/num_term.py	(revision b8080e1affadb04559f0597dfddc5506d2044e9d)
@@ -55,5 +55,5 @@
         medi = 0
         for i in range(dv):
-            if odd == True:
+            if odd:
                 medi = osc[int(med)]
             else:
@@ -98,7 +98,7 @@
                 new_osc3.append(self.osc_list[i])
 
-        if flag9 == True:
+        if flag9:
             self.dataset = new_osc1
-        elif flag8 == True:
+        elif flag8:
             self.dataset = new_osc2
         else:
@@ -141,6 +141,5 @@
             div = len(nts)
             tem = float(div) / 2.0
-            odd = self.is_odd(div)
-            if odd == True:
+            if self.is_odd(div):
                 nt = nts[int(tem)]
             else:
@@ -148,5 +147,5 @@
             return nt, self.alpha_list[nt - 10], self.mess_list[nt - 10]
         except:
-            #TODO: check the logic above and make sure it doesn't 
+            #TODO: check the logic above and make sure it doesn't
             # rely on the try-except.
             return self.nterm_min, self.invertor.alpha, ''
@@ -183,6 +182,6 @@
                 data_y = np.append(data_y, test_y)
                 data_err = np.append(data_err, err)
-            except Exception as ex:
-                logger.error(ex)
+            except:
+                logger.error(sys.exc_value)
 
     return data_x, data_y, data_err
