Index: src/sans/models/c_extension/c_smearer/smearer.cpp
===================================================================
--- src/sans/models/c_extension/c_smearer/smearer.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
+++ src/sans/models/c_extension/c_smearer/smearer.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
@@ -0,0 +1,373 @@
+/**
+	This software was developed by the University of Tennessee as part of the
+	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+	project funded by the US National Science Foundation.
+
+	If you use DANSE applications to do scientific research that leads to
+	publication, we ask that you acknowledge the use of the software with the
+	following sentence:
+
+	"This work benefited from DANSE software developed under NSF award DMR-0520547."
+
+	copyright 2009, University of Tennessee
+ */
+#include "smearer.hh"
+#include <stdio.h>
+#include <math.h>
+using namespace std;
+
+#if defined(_MSC_VER)
+extern "C" {
+#include "winFuncs.h"
+}
+#endif
+/**
+ * Constructor for BaseSmearer
+ *
+ * @param qmin: minimum Q value
+ * @param qmax: maximum Q value
+ * @param nbins: number of Q bins
+ */
+BaseSmearer :: BaseSmearer(double qmin, double qmax, int nbins) {
+	// Number of bins
+	this->nbins = nbins;
+	this->qmin = qmin;
+	this->qmax = qmax;
+	// Flag to keep track of whether we have a smearing matrix or
+	// whether we need to compute one
+	has_matrix = false;
+	even_binning = true;
+};
+
+/**
+ * Constructor for BaseSmearer
+ *
+ * Used for uneven binning
+ * @param q: array of Q values
+ * @param nbins: number of Q bins
+ */
+BaseSmearer :: BaseSmearer(double* q, int nbins) {
+	// Number of bins
+	this->nbins = nbins;
+	this->q_values = q;
+	// Flag to keep track of whether we have a smearing matrix or
+	// whether we need to compute one
+	has_matrix = false;
+	even_binning = false;
+};
+
+/**
+ * Constructor for SlitSmearer
+ *
+ * @param width: slit width in Q units
+ * @param height: slit height in Q units
+ * @param qmin: minimum Q value
+ * @param qmax: maximum Q value
+ * @param nbins: number of Q bins
+ */
+SlitSmearer :: SlitSmearer(double width, double height, double qmin, double qmax, int nbins) :
+	BaseSmearer(qmin, qmax, nbins){
+	this->height = height;
+	this->width = width;
+};
+
+/**
+ * Constructor for SlitSmearer
+ *
+ * @param width: slit width in Q units
+ * @param height: slit height in Q units
+ * @param q: array of Q values
+ * @param nbins: number of Q bins
+ */
+SlitSmearer :: SlitSmearer(double width, double height, double* q, int nbins) :
+	BaseSmearer(q, nbins){
+	this->height = height;
+	this->width = width;
+};
+
+/**
+ * Constructor for QSmearer
+ *
+ * @param width: array slit widths for each Q point, in Q units
+ * @param qmin: minimum Q value
+ * @param qmax: maximum Q value
+ * @param nbins: number of Q bins
+ */
+QSmearer :: QSmearer(double* width, double qmin, double qmax, int nbins) :
+	BaseSmearer(qmin, qmax, nbins){
+	this->width = width;
+};
+
+/**
+ * Constructor for QSmearer
+ *
+ * @param width: array slit widths for each Q point, in Q units
+ * @param q: array of Q values
+ * @param nbins: number of Q bins
+ */
+QSmearer :: QSmearer(double* width, double* q, int nbins) :
+	BaseSmearer(q, nbins){
+	this->width = width;
+};
+
+/**
+ * Compute the slit smearing matrix
+ *
+ * For even binning (q_min to q_max with nbins):
+ *
+ *   step = (q_max-q_min)/(nbins-1)
+ *   first bin goes from q_min to q_min+step
+ *   last bin goes from q_max to q_max+step
+ *
+ * For binning according to q array:
+ *
+ * Each q point represents a bin going from half the distance between it
+ * and the previous point to half the distance between it and the next point.
+ *
+ *    Example: bin i goes from (q_values[i-1]+q_values[i])/2 to (q_values[i]+q_values[i+1])/2
+ *
+ * The exceptions are the first and last bins, which are centered at the first and
+ * last q-values, respectively. The width of the first and last bins is the distance between
+ * their respective neighboring q-value.
+ */
+void SlitSmearer :: compute_matrix(){
+
+	weights = new vector<double>(nbins*nbins,0);
+
+	// Check the length of the data
+	if (nbins<2) return;
+	int npts_h = height>0.0 ? npts : 1;
+	int npts_w = width>0.0 ? npts : 1;
+
+	// If both height and width are great than zero,
+	// modify the number of points in each direction so
+	// that the total number of points is still what
+	// the user would expect (downgrade resolution)
+	//if(npts_h>1 && npts_w>1){
+	//	npts_h = (int)ceil(sqrt((double)npts));
+	//	npts_w = npts_h;
+	//}
+	double shift_h, shift_w, hbin_size, wbin_size;
+	// Make sure height and width are all positive (FWMH/2)
+	// Assumption; height and width are all same for all q points
+	if(npts_h == 1){
+		shift_h = 0.0;
+	} else {
+		shift_h = fabs(height);
+	}
+	if(npts_w == 1){
+		shift_w = 0.0;
+	} else {
+		shift_w = fabs(width);
+	}
+	// size of the h bin and w bin
+	hbin_size = shift_h / nbins;
+	wbin_size = shift_w / nbins;
+
+	// Loop over all q-values
+	double q, q_min, q_max, q_0=0.0;
+	for(int i=0; i<nbins; i++) {
+		// Find Weights
+		// Find q where the resolution smearing calculation of I(q) occurs
+		get_bin_range(i, &q, &q_min, &q_max);
+		// Block q becomes <=0
+		if (q <= 0){
+			continue;
+		}
+		// Find q[0] value to normalize the weight later,
+		//  otherwise, we will have a precision problem.
+		if (i == 0){
+			q_0 = q;
+		}
+		// Loop over all qj-values
+		for(int j=0; j<nbins; j++) {
+			double q_j, q_high, q_low;
+			// Calculate bin size of q_j
+			get_bin_range(j, &q_j, &q_low, &q_high);
+			// Block q_j becomes <=0
+			if (q_j <= 0){
+				continue;
+			}
+			// Check q_low that can not be negative.
+			if (q_low < 0.0){
+				q_low = 0.0;
+			}
+			// default parameter values
+			(*weights)[i*nbins+j] = 0.0;
+			// protect for negative q
+			if (q <= 0.0 || q_j <= 0.0){
+					continue;
+			}
+			double shift_w = 0.0;
+			// Condition: zero slit smear.
+			if (npts_w == 1 && npts_h == 1){
+				if(q_j == q) {
+					(*weights)[i*nbins+j] = 1.0;
+				}
+			}
+			//Condition:Smear weight integration for width >0 when the height (=0) does not present.
+			//Or height << width.
+			else if((npts_w!=1 && npts_h == 1)|| (npts_w!=1 && npts_h != 1 && width/height > 100.0)){
+				shift_w = width;
+				//del_w = width/((double)npts_w-1.0);
+				double q_shifted_low = q - shift_w;
+				// High limit of the resolution range
+				double q_shifted_high = q + shift_w;
+				// Go through all the q_js for weighting those points
+				if(q_j >= q_shifted_low && q_j <= q_shifted_high) {
+					// The weighting factor comes,
+					// Give some weight (delq_bin) for the q_j within the resolution range
+					// Weight should be same for all qs except
+					// for the q bin size at j.
+					// Note that the division by q_0 is only due to the precision problem
+					// where q_high - q_low gets to very small.
+					// Later, it will be normalized again.
+					(*weights)[i*nbins+j] += (q_high - q_low)/q_0 ;
+				}
+			}
+			else{
+				// Loop for width (;Height is analytical.)
+				// Condition: height >>> width, otherwise, below is not accurate enough.
+				// Smear weight numerical iteration for width >0 when the height (>0) presents.
+				// When width = 0, the numerical iteration will be skipped.
+				// The resolution calculation for the height is done by direct integration,
+				// assuming the I(q'=sqrt(q_j^2-(q+shift_w)^2)) is constant within a q' bin, [q_high, q_low].
+				// In general, this weight numerical iteration for width >0 might be a rough approximation,
+				// but it must be good enough when height >>> width.
+				for(int k=(-npts_w + 1); k<npts_w; k++){
+					if(npts_w!=1){
+						shift_w = width/((double)npts_w-1.0)*(double)k;
+					}
+					// For each q-value, compute the weight of each other q-bin
+					// in the I(q) array
+					// Low limit of the resolution range
+					double q_shift = q + shift_w;
+					if (q_shift < 0.0){
+						q_shift = 0.0;
+					}
+					double q_shifted_low = q_shift;
+					// High limit of the resolution range
+					double q_shifted_high = sqrt(q_shift * q_shift + shift_h * shift_h);
+
+
+					// Go through all the q_js for weighting those points
+					if(q_j >= q_shifted_low && q_j <= q_shifted_high) {
+						// The weighting factor comes,
+						// Give some weight (delq_bin) for the q_j within the resolution range
+						// Weight should be same for all qs except
+						// for the q bin size at j.
+						// Note that the division by q_0 is only due to the precision problem
+						// where q_high - q_low gets to very small.
+						// Later, it will be normalized again.
+
+						// The fabs below are not necessary but in case: the weight should never be imaginary.
+						// At the edge of each sub_width. weight += u(at q_high bin) - u(0), where u(0) = 0,
+						// and weighted by (2.0* npts_w -1.0)once for each q.
+						//if (q == q_j) {
+						if (q_low <= q_shift && q_high > q_shift) {
+							//if (k==0)
+								(*weights)[i*nbins+j] += (sqrt(fabs((q_high)*(q_high)-q_shift * q_shift)))/q_0;// * (2.0*double(npts_w)-1.0);
+						}
+						// For the rest of sub_width. weight += u(at q_high bin) - u(at q_low bin)
+						else{// if (u > 0.0){
+							(*weights)[i*nbins+j] += (sqrt(fabs((q_high)*(q_high)- q_shift * q_shift))-sqrt(fabs((q_low)*(q_low)- q_shift * q_shift)))/q_0 ;
+						}
+					}
+				}
+			}
+		}
+	}
+};
+
+/**
+ * Compute the point smearing matrix
+ */
+void QSmearer :: compute_matrix(){
+	weights = new vector<double>(nbins*nbins,0);
+
+	// Loop over all q-values
+	double q, q_min, q_max;
+	double q_j, q_jmax, q_jmin;
+	for(int i=0; i<nbins; i++) {
+		get_bin_range(i, &q, &q_min, &q_max);
+
+		for(int j=0; j<nbins; j++) {
+			get_bin_range(j, &q_j, &q_jmin, &q_jmax);
+
+			// Compute the fraction of the Gaussian contributing
+			// to the q_j bin between q_jmin and q_jmax
+			long double value =  erf( (q_jmax-q)/(sqrt(2.0)*width[i]) );
+        	value -= erf( (q_jmin-q)/(sqrt(2.0)*width[i]) );
+        	(*weights)[i*nbins+j] += value;
+		}
+	}
+}
+
+/**
+ * Computes the Q range of a given bin of the Q distribution.
+ * The range is computed according the the data distribution that
+ * was given to the object at initialization.
+ *
+ * @param i: number of the bin in the distribution
+ * @param q: q-value of bin i
+ * @param q_min: lower bound of the bin
+ * @param q_max: higher bound of the bin
+ *
+ */
+int BaseSmearer :: get_bin_range(int i, double* q, double* q_min, double* q_max) {
+	if (even_binning) {
+		double step = (qmax-qmin)/((double)nbins-1.0);
+		*q = qmin + (double)i*step;
+		*q_min = *q - 0.5*step;
+		*q_max = *q + 0.5*step;
+		return 1;
+	} else if (i>=0 && i<nbins) {
+		*q = q_values[i];
+		if (i==0) {
+			double step = (q_values[1]-q_values[0])/2.0;
+			*q_min = *q - step;
+			*q_max = *q + step;
+		} else if (i==nbins-1) {
+			double step = (q_values[i]-q_values[i-1])/2.0;
+			*q_min = *q - step;
+			*q_max = *q + step;
+		} else {
+			*q_min = *q - (q_values[i]-q_values[i-1])/2.0;
+			*q_max = *q + (q_values[i+1]-q_values[i])/2.0;
+		}
+		return 1;
+	}
+	return -1;
+}
+
+/**
+ * Perform smearing by applying the smearing matrix to the input Q array
+ */
+void BaseSmearer :: smear(double *iq_in, double *iq_out, int first_bin, int last_bin){
+
+	// If we haven't computed the smearing matrix, do it now
+	if(!has_matrix) {
+		compute_matrix();
+		has_matrix = true;
+	}
+
+	// Loop over q-values and multiply apply matrix
+	for(int q_i=first_bin; q_i<=last_bin; q_i++){
+		double sum = 0.0;
+		double counts = 0.0;
+
+		for(int i=first_bin; i<=last_bin; i++){
+			// Skip if weight is less than 1e-03(this value is much smaller than
+			// the weight at the 3*sigma distance
+			// Will speed up a little bit...
+			if ((*weights)[q_i*nbins+i] < 1.0e-003){
+				continue;
+			}
+			sum += iq_in[i] * (*weights)[q_i*nbins+i];
+			counts += (*weights)[q_i*nbins+i];
+		}
+
+		// Normalize counts
+		iq_out[q_i] = (counts>0.0) ? sum/counts : 0.0;
+	}
+}
Index: src/sans/models/c_extension/c_smearer/smearer.hh
===================================================================
--- src/sans/models/c_extension/c_smearer/smearer.hh	(revision 230f479e04002ef42bafef9a227d586459b717c1)
+++ src/sans/models/c_extension/c_smearer/smearer.hh	(revision 230f479e04002ef42bafef9a227d586459b717c1)
@@ -0,0 +1,97 @@
+/**
+	This software was developed by the University of Tennessee as part of the
+	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+	project funded by the US National Science Foundation.
+
+	If you use DANSE applications to do scientific research that leads to
+	publication, we ask that you acknowledge the use of the software with the
+	following sentence:
+
+	"This work benefited from DANSE software developed under NSF award DMR-0520547."
+
+	copyright 2009, University of Tennessee
+ */
+#ifndef SMEARER_CLASS_H
+#define SMEARER_CLASS_H
+
+#include <vector>
+
+using namespace std;
+
+/**
+ * Base smearer class, implementing the matrix multiplication only
+ */
+class BaseSmearer {
+protected:
+	// Internal flag: true when the weights vector is filled
+	bool has_matrix;
+	// True when only qmin, qmax and nbins are given. Bins are equidistant
+	bool even_binning;
+	// Smearing matrix
+	vector<double>* weights;
+	// Q vector
+	double* q_values;
+    // Q_min (Min Q-value for I(q))
+    double qmin;
+    // Q_max (Max Q_value for I(q))
+    double qmax;
+    // Number of Q bins
+    int nbins;
+
+public:
+    // Constructor
+    BaseSmearer(double qmin, double qmax, int nbins);
+    BaseSmearer(double* q, int nbins);
+	// Smear function
+	virtual void smear(double *, double *, int, int);
+	// Compute the smearing matrix
+	virtual void compute_matrix(){};
+	// Utility function to check the number of bins
+	int get_nbins() { return nbins; }
+	// Get the q range of a particular bin
+	virtual int get_bin_range(int, double*, double*, double*);
+};
+
+
+/**
+ * Slit smearer class
+ */
+class SlitSmearer : public BaseSmearer {
+
+protected:
+    // Number of points used in the smearing computation
+    static const int npts   = 500;
+
+public:
+    // Slit width in Q units
+    double width;
+    // Slit height in Q units
+    double height;
+
+    // Constructor
+	SlitSmearer(double width, double height, double qmin, double qmax, int nbins);
+	SlitSmearer(double width, double height, double* q, int nbins);
+	// Compute the smearing matrix
+	virtual void compute_matrix();
+};
+
+
+/**
+ * Point smearer class
+ */
+class QSmearer : public BaseSmearer {
+
+protected:
+    // Standard deviation in Q [A-1]
+    double* width;
+
+public:
+
+    // Constructor
+    QSmearer(double* width, double qmin, double qmax, int nbins);
+    QSmearer(double* width, double* q, int nbins);
+	// Compute the smearing matrix
+	virtual void compute_matrix();
+};
+
+#endif
Index: src/sans/models/c_extension/c_smearer/smearer2d_helper.cpp
===================================================================
--- src/sans/models/c_extension/c_smearer/smearer2d_helper.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
+++ src/sans/models/c_extension/c_smearer/smearer2d_helper.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
@@ -0,0 +1,76 @@
+/**
+	This software was developed by the University of Tennessee as part of the
+	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+	project funded by the US National Science Foundation.
+
+	If you use DANSE applications to do scientific research that leads to
+	publication, we ask that you acknowledge the use of the software with the
+	following sentence:
+
+	"This work benefited from DANSE software developed under NSF award DMR-0520547."
+
+	copyright 2009, University of Tennessee
+ */
+#include "smearer2d_helper.hh"
+#include <stdio.h>
+#include <math.h>
+using namespace std;
+
+/**
+ * Constructor for BaseSmearer
+ *
+ * binning
+ * @param qx: array of Qx values
+ * @param qy: array of Qy values
+ * @param nrbins: number of r bins
+ * @param nphibins: number of phi bins
+ */
+Smearer_helper :: Smearer_helper(int npoints, double* qx, double* qy,
+		double* dqx, double* dqy, double rlimit, int nrbins, int nphibins) {
+	// Number of bins
+	this->npoints = npoints;
+	this->rlimit = rlimit;
+	this->nrbins = nrbins;
+	this->nphibins = nphibins;
+	this->qx_values = qx;
+	this->qy_values = qy;
+	this->dqx_values = dqx;
+	this->dqy_values = dqy;
+};
+
+/**
+ * Compute the point smearing matrix
+ */
+void Smearer_helper :: smear2d(double *weights, double *qx_out, double *qy_out){
+
+	double rbin_size = rlimit / double(nrbins);
+	double phibin_size = 0.0;
+	double rbin = 0.0;
+	double phibin = 0.0;
+	double qr = 0.0;
+	double qphi = 0.0;
+	double Pi = 4.0*atan(1.0);
+	
+	// Loop over q-values and multiply apply matrix
+	for(int i=0; i<nrbins; i++){
+		rbin = rbin_size * (double(i) + 0.5);
+		for(int j=0; j<nphibins; j++){
+			phibin_size =  2.0 * Pi / double(nphibins);
+			phibin = phibin_size * (double(j));
+			for(int q_i=0; q_i<npoints; q_i++){
+				qr = sqrt(qx_values[q_i]*qx_values[q_i] + qy_values[q_i]*qy_values[q_i]);
+				qphi = atan(qy_values[q_i]/qx_values[q_i]);
+				qx_out[q_i + npoints*(nrbins * j + i)] = (rbin*dqx_values[q_i]*cos(phibin) + qr)*cos(qphi)-
+										rbin*dqy_values[q_i]*sin(phibin)*sin(qphi);
+				qy_out[q_i + npoints*(nrbins * j + i)] = (rbin*dqx_values[q_i]*cos(phibin) + qr)*sin(qphi)+
+										rbin*dqy_values[q_i]*sin(phibin)*cos(qphi);
+				if (q_i==0){
+					weights[nrbins * j + i] = exp(-0.5 * ((rbin - rbin_size / 2.0) *
+							(rbin - rbin_size / 2.0)))- exp(-0.5 * ((rbin + rbin_size / 2.0 ) *
+									(rbin + rbin_size / 2.0)));
+			}
+		}
+	}
+	}
+}
+
Index: src/sans/models/c_extension/c_smearer/smearer2d_helper.hh
===================================================================
--- src/sans/models/c_extension/c_smearer/smearer2d_helper.hh	(revision 230f479e04002ef42bafef9a227d586459b717c1)
+++ src/sans/models/c_extension/c_smearer/smearer2d_helper.hh	(revision 230f479e04002ef42bafef9a227d586459b717c1)
@@ -0,0 +1,50 @@
+/**
+	This software was developed by the University of Tennessee as part of the
+	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+	project funded by the US National Science Foundation.
+
+	If you use DANSE applications to do scientific research that leads to
+	publication, we ask that you acknowledge the use of the software with the
+	following sentence:
+
+	"This work benefited from DANSE software developed under NSF award DMR-0520547."
+
+	copyright 2009, University of Tennessee
+ */
+#ifndef SMEARER2D_HELPER_CLASS_H
+#define SMEARER2D_HELPER_CLASS_H
+
+#include <vector>
+
+using namespace std;
+
+/**
+ * Base smearer class, implementing the matrix multiplication only
+ */
+class Smearer_helper {
+protected:
+	// Smearing matrix
+	vector<double>* weights;
+	vector<double>* qx_out;
+	vector<double>* qy_out;
+	// Q vector
+	double* qx_values;
+	double* qy_values;
+	double* dqx_values;
+	double* dqy_values;
+    // r limit
+    double rlimit;
+    // Numbers
+    int npoints;
+    int nrbins;
+    int nphibins;
+
+public:
+    // Constructor
+	Smearer_helper(int npoints, double* qx, double* qy, double* dqx, double* dqy,
+			double rlimit, int nrbins, int nphibins);
+	// Smear function
+	virtual void smear2d(double *weights, double *qx_out, double *qy_out);
+};
+
+#endif
Index: src/sans/models/c_extension/c_smearer/smearer2d_helper_module.cpp
===================================================================
--- src/sans/models/c_extension/c_smearer/smearer2d_helper_module.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
+++ src/sans/models/c_extension/c_smearer/smearer2d_helper_module.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
@@ -0,0 +1,128 @@
+/**
+  Smearer module to perform point and slit smearing calculations
+
+	This software was developed by the University of Tennessee as part of the
+	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+	project funded by the US National Science Foundation.
+
+	See the license text in license.txt
+
+	copyright 2009, University of Tennessee
+ */
+#include <Python.h>
+#include <stdio.h>
+#include <smearer2d_helper.hh>
+
+// Utilities
+#define INVECTOR(obj,buf,len)										\
+    do { \
+        int err = PyObject_AsReadBuffer(obj, (const void **)(&buf), &len); \
+        if (err < 0) return NULL; \
+        len /= sizeof(*buf); \
+    } while (0)
+
+#define OUTVECTOR(obj,buf,len) \
+    do { \
+        int err = PyObject_AsWriteBuffer(obj, (void **)(&buf), &len); \
+        if (err < 0) return NULL; \
+        len /= sizeof(*buf); \
+    } while (0)
+
+
+/**
+ * Delete a Smearer2d object
+ */
+void del_smearer2d_helper(void *ptr){
+	Smearer_helper* smearer2d_helper = static_cast<Smearer_helper *>(ptr);
+	delete smearer2d_helper;
+	return;
+}
+
+/**
+ * Create a QSmearer as a python object by supplying a q array
+ */
+PyObject * new_Smearer_helper(PyObject *, PyObject *args) {
+	PyObject *qx_values_obj;
+	PyObject *qy_values_obj;
+	PyObject *dqx_values_obj;
+	PyObject *dqy_values_obj;
+	Py_ssize_t n_q;
+	//PyObject rlimit_obj;
+	//PyObject npoints_obj;
+	//PyObject nrbins_obj;
+	//PyObject nphibins_obj;
+	double* qx_values;
+	double* qy_values;
+	double* dqx_values;
+	double* dqy_values;
+	double rlimit;
+	int npoints;
+	int nrbins;
+	int nphibins;
+
+
+	if (!PyArg_ParseTuple(args, "OOOOdiii", &qx_values_obj, &qy_values_obj, &dqx_values_obj, &dqy_values_obj, &rlimit, &nrbins, &nphibins, &npoints)) return NULL;
+	OUTVECTOR(qx_values_obj, qx_values, n_q);
+	OUTVECTOR(qy_values_obj, qy_values, n_q);
+	OUTVECTOR(dqx_values_obj, dqx_values, n_q);
+	OUTVECTOR(dqy_values_obj, dqy_values, n_q);
+	Smearer_helper* smearer2d_helper = new Smearer_helper(npoints,qx_values,qy_values,dqx_values,dqy_values, rlimit, nrbins, nphibins);
+	return PyCObject_FromVoidPtr(smearer2d_helper, del_smearer2d_helper);
+}
+
+/**
+ * Smear the given input according to a given smearer object
+ */
+PyObject * smear2d_input(PyObject *, PyObject *args) {
+	PyObject *weights_obj;
+	Py_ssize_t w_out;
+	double *weights;
+	PyObject *qx_out_obj;
+	Py_ssize_t n_out;
+	double *qx_out;
+	PyObject *qy_out_obj;
+	//Py_ssize_t n_out;
+	double *qy_out;
+	PyObject *smear_obj;
+
+	if (!PyArg_ParseTuple(args, "OOOO",  &smear_obj, &weights_obj, &qx_out_obj, &qy_out_obj)) return NULL;
+	OUTVECTOR(weights_obj, weights, w_out);
+	OUTVECTOR(qx_out_obj, qx_out, n_out);
+	OUTVECTOR(qy_out_obj, qy_out, n_out);
+
+	// Sanity check
+	//if(n_in!=n_out) return Py_BuildValue("i",-1);
+
+	// Set the array pointers
+	void *temp = PyCObject_AsVoidPtr(smear_obj);
+	Smearer_helper* s = static_cast<Smearer_helper *>(temp);
+
+	s->smear2d(weights, qx_out, qy_out);
+	//return PyCObject_FromVoidPtr(s, del_smearer2d_helper);
+	return Py_BuildValue("i",1);
+}
+
+
+/**
+ * Define module methods
+ */
+static PyMethodDef module_methods[] = {
+	{"new_Smearer_helper", (PyCFunction)new_Smearer_helper, METH_VARARGS,
+		  "Create a new Q Smearer object"},
+	{"smearer2d_helper",(PyCFunction)smear2d_input, METH_VARARGS,
+		  "Smear the given input array"},
+    {NULL}
+};
+
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initsmearer2d_helper(void)
+{
+    PyObject* m;
+
+    m = Py_InitModule3("smearer2d_helper", module_methods,
+                       "Smearer2d_helper module");
+}
Index: src/sans/models/c_extension/c_smearer/smearer_module.cpp
===================================================================
--- src/sans/models/c_extension/c_smearer/smearer_module.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
+++ src/sans/models/c_extension/c_smearer/smearer_module.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
@@ -0,0 +1,205 @@
+/**
+ *  Smearer module to perform point and slit smearing calculations
+
+	This software was developed by the University of Tennessee as part of the
+	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+	project funded by the US National Science Foundation.
+
+	See the license text in license.txt
+
+	copyright 2009, University of Tennessee
+ */
+#include <Python.h>
+#include <stdio.h>
+#include <smearer.hh>
+
+// Utilities
+#define INVECTOR(obj,buf,len)										\
+    do { \
+        int err = PyObject_AsReadBuffer(obj, (const void **)(&buf), &len); \
+        if (err < 0) return NULL; \
+        len /= sizeof(*buf); \
+    } while (0)
+
+#define OUTVECTOR(obj,buf,len) \
+    do { \
+        int err = PyObject_AsWriteBuffer(obj, (void **)(&buf), &len); \
+        if (err < 0) return NULL; \
+        len /= sizeof(*buf); \
+    } while (0)
+
+/**
+ * Delete a SlitSmearer object
+ */
+void del_slit_smearer(void *ptr){
+	SlitSmearer* smearer = static_cast<SlitSmearer *>(ptr);
+	delete smearer;
+	return;
+}
+
+/**
+ * Create a SlitSmearer as a python object
+ */
+PyObject * new_slit_smearer(PyObject *, PyObject *args) {
+	double width;
+	double height;
+	double qmin;
+	double qmax;
+	int nbins;
+
+	if (!PyArg_ParseTuple(args, "ddddi", &width, &height, &qmin, &qmax, &nbins)) return NULL;
+	SlitSmearer* smearer = new SlitSmearer(width, height, qmin, qmax, nbins);
+	return PyCObject_FromVoidPtr(smearer, del_slit_smearer);
+}
+
+/**
+ * Create a SlitSmearer as a python object by supplying a q array
+ */
+PyObject * new_slit_smearer_with_q(PyObject *, PyObject *args) {
+	PyObject *qvalues_obj;
+	Py_ssize_t n_q;
+	double* qvalues;
+	double width;
+	double height;
+
+	if (!PyArg_ParseTuple(args, "ddO", &width, &height, &qvalues_obj)) return NULL;
+	OUTVECTOR(qvalues_obj, qvalues, n_q);
+	SlitSmearer* smearer = new SlitSmearer(width, height, qvalues, n_q);
+	return PyCObject_FromVoidPtr(smearer, del_slit_smearer);
+}
+
+/**
+ * Delete a QSmearer object
+ */
+void del_q_smearer(void *ptr){
+	QSmearer* smearer = static_cast<QSmearer *>(ptr);
+	delete smearer;
+	return;
+}
+
+/**
+ * Create a QSmearer as a python object
+ */
+PyObject * new_q_smearer(PyObject *, PyObject *args) {
+	PyObject *width_obj;
+	Py_ssize_t n_w;
+	double* width;
+	double qmin;
+	double qmax;
+	int nbins;
+
+	if (!PyArg_ParseTuple(args, "Oddi", &width_obj, &qmin, &qmax, &nbins)) return NULL;
+	OUTVECTOR(width_obj, width, n_w);
+	QSmearer* smearer = new QSmearer(width, qmin, qmax, nbins);
+	return PyCObject_FromVoidPtr(smearer, del_q_smearer);
+}
+
+/**
+ * Create a QSmearer as a python object by supplying a q array
+ */
+PyObject * new_q_smearer_with_q(PyObject *, PyObject *args) {
+	PyObject *width_obj;
+	Py_ssize_t n_w;
+	double* width;
+	PyObject *qvalues_obj;
+	Py_ssize_t n_q;
+	double* qvalues;
+
+	if (!PyArg_ParseTuple(args, "OO", &width_obj, &qvalues_obj)) return NULL;
+	OUTVECTOR(width_obj, width, n_w);
+	OUTVECTOR(qvalues_obj, qvalues, n_q);
+	QSmearer* smearer = new QSmearer(width, qvalues, n_q);
+	return PyCObject_FromVoidPtr(smearer, del_q_smearer);
+}
+
+/**
+ * Smear the given input according to a given smearer object
+ */
+PyObject * smear_input(PyObject *, PyObject *args) {
+	PyObject *input_iq_obj;
+	PyObject *output_iq_obj;
+	PyObject *smear_obj;
+	Py_ssize_t n_in;
+	Py_ssize_t n_out;
+	double *input_iq;
+	double *output_iq;
+	int first_bin;
+	int last_bin;
+
+
+	if (!PyArg_ParseTuple(args, "OOOii", &smear_obj, &input_iq_obj, &output_iq_obj, &first_bin, &last_bin)) return NULL;
+	OUTVECTOR(input_iq_obj, input_iq, n_in);
+	OUTVECTOR(output_iq_obj, output_iq, n_out);
+
+	// Sanity check
+	if(n_in!=n_out) return Py_BuildValue("i",-1);
+
+	// Set the array pointers
+	void *temp = PyCObject_AsVoidPtr(smear_obj);
+	BaseSmearer* s = static_cast<BaseSmearer *>(temp);
+
+	if(n_in!=s->get_nbins()) {
+		return Py_BuildValue("i",-2);
+	}
+
+	s->smear(input_iq, output_iq, first_bin, last_bin);
+
+	return Py_BuildValue("i",1);
+}
+
+/**
+ * Get the q-value of a given bin
+ */
+PyObject * get_q(PyObject *, PyObject *args) {
+	PyObject *smear_obj;
+	int bin;
+
+	if (!PyArg_ParseTuple(args, "Oi", &smear_obj, &bin)) return NULL;
+
+	// Set the array pointers
+	void *temp = PyCObject_AsVoidPtr(smear_obj);
+	BaseSmearer* s = static_cast<BaseSmearer *>(temp);
+
+	if(s->get_nbins()<=0 || s->get_nbins()<=bin) {
+		return NULL;
+	}
+
+	double q, q_min, q_max;
+	if (s->get_bin_range(bin, &q, &q_min, &q_max)<0) {
+		return NULL;
+	}
+	return Py_BuildValue("d", q);
+}
+
+
+/**
+ * Define module methods
+ */
+static PyMethodDef module_methods[] = {
+	{"new_slit_smearer", (PyCFunction)new_slit_smearer, METH_VARARGS,
+		  "Create a new Slit Smearer object"},
+	{"new_slit_smearer_with_q", (PyCFunction)new_slit_smearer_with_q, METH_VARARGS,
+		  "Create a new Slit Smearer object by supplying an array of Q values"},
+	{"new_q_smearer", (PyCFunction)new_q_smearer, METH_VARARGS,
+		  "Create a new Q Smearer object"},
+	{"new_q_smearer_with_q", (PyCFunction)new_q_smearer_with_q, METH_VARARGS,
+		  "Create a new Q Smearer object by supplying an array of Q values"},
+	{"smear",(PyCFunction)smear_input, METH_VARARGS,
+		  "Smear the given input array"},
+	{"get_q",(PyCFunction)get_q, METH_VARARGS,
+		  "Get the q-value of a given bin"},
+    {NULL}
+};
+
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initsmearer(void)
+{
+    PyObject* m;
+
+    m = Py_InitModule3("smearer", module_methods,
+                       "Q Smearing module");
+}
