Index: sansmodels/src/sans/models/PeakGaussModel.py
===================================================================
--- sansmodels/src/sans/models/PeakGaussModel.py	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
+++ sansmodels/src/sans/models/PeakGaussModel.py	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+""" 
+    Model describes a Gaussian shaped peak including a flat background
+    Provide F(q) = scale*exp( -1/2 *[(q-q0)/B]^2 )+ background
+    PeakGaussModel function as a BaseComponent model
+"""
+
+from sans.models.BaseComponent import BaseComponent
+import math
+
+class PeakGaussModel(BaseComponent):
+   
+    """
+        Class that evaluates a gaussian  shaped peak.
+        
+        F(q) = scale*exp( -1/2 *[(q-qo)/B]^2 )+ background
+        
+        The model has three parameters: 
+            scale     =  scale
+            q0        =  peak position
+            B         =  standard deviation
+            background=  incoherent background
+    """
+        
+    def __init__(self):
+        """ Initialization """
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        
+        ## Name of the model
+        self.name = "Peak Gauss Model"
+        self.description=""" F(q) = scale*exp( -1/2 *[(q-q0)/B]^2 )+ background
+        
+        The model has three parameters: 
+        scale     =  scale
+        q0        =  peak position
+        B         =  standard deviation
+        background=  incoherent background"""
+        ## Define parameters
+        self.params = {}
+        self.params['scale']              = 100.0
+        self.params['q0']                 = 0.05
+        self.params['B']              = 0.005
+        self.params['background']         = 1.0
+
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['q0']            = ['[1/A]', None, None]
+        self.details['scale']             = ['', 0, None]
+        self.details['B']            = ['[1/A]', None, None]
+        self.details['background']        = ['[1/cm]', None, None]
+        #list of parameter that cannot be fitted
+        self.fixed= []  
+            
+    def _PeakGauss(self, x):
+        """
+            Evaluate  F(x) = scale*exp( -1/2 *[(x-q0)/B]^2 )+ background
+           
+        """
+        return self.params['scale']*math.exp(-1/2 *\
+                         math.pow((x - self.params['q0'])/self.params['B'],2)) \
+                            + self.params['background']
+       
+   
+    def run(self, x = 0.0):
+        """ Evaluate the model
+            @param x: input q-value (float or [float, float] as [r, theta])
+            @return: (Peak Gaussian value)
+        """
+        if x.__class__.__name__ == 'list':
+            return self._PeakGauss(x[0])
+        elif x.__class__.__name__ == 'tuple':
+            raise ValueError, "Tuples are not allowed as input to BaseComponent models"
+        else:
+            return self._PeakGauss(x)
+   
+    def runXY(self, x = 0.0):
+        """ Evaluate the model
+            @param x: input q-value (float or [float, float] as [qx, qy])
+            @return: Peak Gaussian value
+        """
+        if x.__class__.__name__ == 'list':
+            q = math.sqrt(x[0]**2 + x[1]**2)
+            return self._PeakGauss(q)
+        elif x.__class__.__name__ == 'tuple':
+            raise ValueError, "Tuples are not allowed as input to BaseComponent models"
+        else:
+            return self._PeakGauss(x)
Index: sansmodels/src/sans/models/PeakLorentzModel.py
===================================================================
--- sansmodels/src/sans/models/PeakLorentzModel.py	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
+++ sansmodels/src/sans/models/PeakLorentzModel.py	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+""" 
+    Model describes a Lorentzian shaped peak including a flat background
+    Provide F(q) = scale/(1+[(q-q0)/B]^2 ) + background
+    PeakLorentzModel function as a BaseComponent model
+"""
+
+from sans.models.BaseComponent import BaseComponent
+import math
+
+class PeakLorentzModel(BaseComponent):
+   
+    """
+        Class that evaluates a gaussian  shaped peak.
+        
+        F(q) = scale/(1+[(q-q0)/B]^2 ) + background
+        
+        The model has three parameters: 
+            scale     =  scale
+            q0        =  peak position
+            B         =  ( hwhm) half-width-halfmaximum
+            background=  incoherent background
+    """
+        
+    def __init__(self):
+        """ Initialization """
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        
+        ## Name of the model
+        self.name = "Peak Lorentz Model"
+        self.description=""" F(q) = scale/(1+[(q-q0)/B]^2 ) + background
+        
+        The model has three parameters: 
+        scale     =  scale
+        q0        =  peak position
+        B         =  ( hwhm) half-width-halfmaximum
+        background=  incoherent background"""
+        ## Define parameters
+        self.params = {}
+        self.params['scale']              = 100.0
+        self.params['q0']                 = 0.05
+        self.params['B']              = 0.005
+        self.params['background']         = 1.0
+
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['q0']            = ['[1/A]', None, None]
+        self.details['scale']             = ['', 0, None]
+        self.details['B']            = ['[1/A]', None, None]
+        self.details['background']        = ['[1/cm]', None, None]
+        #list of parameter that cannot be fitted
+        self.fixed= []  
+            
+    def _PeakLorentz(self, x):
+        """
+            Evaluate  F(x) = scale/(1+[(x-q0)/B]^2 ) + background
+           
+        """
+        return self.params['scale']/(1+\
+                         math.pow((x - self.params['q0'])/self.params['B'],2)) \
+                            + self.params['background']
+       
+   
+    def run(self, x = 0.0):
+        """ Evaluate the model
+            @param x: input q-value (float or [float, float] as [r, theta])
+            @return: Peak Lorentzian value
+        """
+        if x.__class__.__name__ == 'list':
+            return self._PeakLorentz(x[0])
+        elif x.__class__.__name__ == 'tuple':
+            raise ValueError, "Tuples are not allowed as input to BaseComponent models"
+        else:
+            return self._PeakLorentz(x)
+   
+    def runXY(self, x = 0.0):
+        """ Evaluate the model
+            @param x: input q-value (float or [float, float] as [qx, qy])
+            @return: Peak Lorentzian value
+        """
+        if x.__class__.__name__ == 'list':
+            q = math.sqrt(x[0]**2 + x[1]**2)
+            return self._PeakLorentz(q)
+        elif x.__class__.__name__ == 'tuple':
+            raise ValueError, "Tuples are not allowed as input to BaseComponent models"
+        else:
+            return self._PeakLorentz(x)
Index: sansmodels/src/sans/models/c_extensions/core_shell_cylinder.h
===================================================================
--- sansmodels/src/sans/models/c_extensions/core_shell_cylinder.h	(revision 1ed3834d2e968f8ff632d0b368f55ac28174df7a)
+++ sansmodels/src/sans/models/c_extensions/core_shell_cylinder.h	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -32,5 +32,5 @@
  // 		phi: the axis_phi of the cylinder...
  //		</text>
- //[FIXED]= <text> axis_phi.width; axis_theta.width; length.width;radius.width; thickness_width</text>
+ //[FIXED]= <text> axis_phi.width; axis_theta.width; length.width;radius.width; thickness.width</text>
  //[ORIENTATION_PARAMS]= axis_phi; axis_theta;axis_phi.width; axis_theta.width
 
Index: sansmodels/src/sans/models/c_extensions/hollow_cylinder.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/hollow_cylinder.c	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
+++ sansmodels/src/sans/models/c_extensions/hollow_cylinder.c	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -0,0 +1,106 @@
+/**
+ * Scattering model for a hollow cylinder
+ * @author:gervaise alina / UTK
+ */
+
+#include "hollow_cylinder.h"
+#include "libCylinder.h"
+#include <math.h>
+#include <stdio.h>
+
+
+/**
+ * Function to evaluate 1D scattering function
+ * @param pars: parameters of the hollow cylinder
+ * @param q: q-value
+ * @return: function value
+ */
+double hollow_cylinder_analytical_1D(HollowCylinderParameters *pars, double q) {
+	double dp[6];
+	
+	dp[0] = pars->scale;
+	dp[1] = pars->core_radius;
+	dp[2] = pars->shell_radius;
+	dp[3] = pars->length;
+	dp[4] = pars->contrast;
+	dp[5] = pars->background;
+	
+	return HollowCylinder(dp, q);
+}
+    
+/**
+ * Function to evaluate 2D scattering function
+ * @param pars: parameters of the Hollow cylinder
+ * @param q: q-value
+ * @return: function value
+ */
+double hollow_cylinder_analytical_2DXY(HollowCylinderParameters *pars, double qx, double qy) {
+	double q;
+	q = sqrt(qx*qx+qy*qy);
+    return hollow_cylinder_analytical_2D_scaled(pars, q, qx/q, qy/q);
+} 
+
+/**
+ * Function to evaluate 2D scattering function
+ * @param pars: parameters of the hollow cylinder
+ * @param q: q-value
+ * @param phi: angle phi
+ * @return: function value
+ */
+double hollow_cylinder_analytical_2D(HollowCylinderParameters *pars, double q, double phi) {
+    return hollow_cylinder_analytical_2D_scaled(pars, q, cos(phi), sin(phi));
+} 
+
+/**
+ * Function to evaluate 2D scattering function
+ * @param pars: parameters of the hollow cylinder
+ * @param q: q-value
+ * @param q_x: q_x / q
+ * @param q_y: q_y / q
+ * @return: function value
+ */
+double hollow_cylinder_analytical_2D_scaled(HollowCylinderParameters *pars, double q, double q_x, double q_y) {
+	double cyl_x, cyl_y, cyl_z;
+	double q_z;
+	double  alpha,vol, cos_val;
+	double answer;
+        
+    // Cylinder orientation
+    cyl_x = sin(pars->axis_theta) * cos(pars->axis_phi);
+    cyl_y = sin(pars->axis_theta) * sin(pars->axis_phi);
+    cyl_z = cos(pars->axis_theta);
+     
+    // q vector
+    q_z = 0;
+        
+    // Compute the angle btw vector q and the
+    // axis of the cylinder
+    cos_val = cyl_x*q_x + cyl_y*q_y + cyl_z*q_z;
+    
+    // The following test should always pass
+    if (fabs(cos_val)>1.0) {
+    	printf("core_shell_cylinder_analytical_2D: Unexpected error: cos(alpha)=%g\n", cos_val);
+     	return 0;
+    }
+    
+	alpha = acos( cos_val );
+	
+	// Call the IGOR library function to get the kernel
+	answer = HolCylKernel(q, pars->core_radius, pars->shell_radius, pars->length, cos_val);
+	
+	//normalize by cylinder volume
+	vol=acos(-1.0)*((pars->core_radius *pars->core_radius)-(pars->shell_radius*pars->shell_radius))
+			*(pars->length);
+	answer /= vol;
+	
+	//convert to [cm-1]
+	answer *= 1.0e8;
+	
+	//Scale
+	answer *= pars->scale;
+	
+	// add in the background
+	answer += pars->background;
+	
+	return answer;
+}
Index: sansmodels/src/sans/models/c_extensions/hollow_cylinder.h
===================================================================
--- sansmodels/src/sans/models/c_extensions/hollow_cylinder.h	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
+++ sansmodels/src/sans/models/c_extensions/hollow_cylinder.h	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -0,0 +1,59 @@
+#if !defined(hollow_cylinder_h)
+#define hollow_cylinder_h
+
+/**
+ * Structure definition for hollow cylinder parameters
+ */
+ //[PYTHONCLASS] = HollowCylinderModel
+ //[DISP_PARAMS] = core_radius, shell_radius, length, axis_theta, axis_phi
+ //[DESCRIPTION] = <text></text>
+ //[FIXED]= <text> axis_phi.width; axis_theta.width; length.width;core_radius.width; shell_radius</text>
+ //[ORIENTATION_PARAMS]= axis_phi; axis_theta;axis_phi.width; axis_theta.width
+
+
+typedef struct {
+    /// Scale factor
+    //  [DEFAULT]=scale=1.0
+    double scale;
+
+    /// Core radius [A]
+    //  [DEFAULT]=core_radius=20.0 [A]
+    double core_radius;
+
+    /// Shell radius [A]
+    //  [DEFAULT]=shell_radius=30.0 [A]
+    double shell_radius;
+
+    /// Hollow cylinder length [A]
+    //  [DEFAULT]=length=400.0 [A]
+    double length;
+
+    /// Contrast  [1/A²]
+    //  [DEFAULT]=contrast=5.3e-6 [1/A²]
+    double contrast;
+
+	/// Incoherent Background [1/cm]
+	//  [DEFAULT]=background=0.01 [1/cm]
+	double background;
+
+    /// Orientation of the long axis of the hollow cylinder w/respect incoming beam [rad]
+    //  [DEFAULT]=axis_theta=1.57 [rad]
+    double axis_theta;
+
+    /// Orientation of the long axis of the hollow cylinder in the plane of the detector [rad]
+    //  [DEFAULT]=axis_phi=0.0 [rad]
+    double axis_phi;
+
+} HollowCylinderParameters;
+
+
+
+/// 1D scattering function
+double hollow_cylinder_analytical_1D(HollowCylinderParameters *pars, double q);
+
+/// 2D scattering function
+double hollow_cylinder_analytical_2D(HollowCylinderParameters *pars, double q, double phi);
+double hollow_cylinder_analytical_2DXY(HollowCylinderParameters *pars, double qx, double qy);
+double hollow_cylinder_analytical_2D_scaled(HollowCylinderParameters *pars, double q, double q_x, double q_y);
+
+#endif
Index: sansmodels/src/sans/models/c_models/c_models.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/c_models.cpp	(revision 34c30203f24453aa528815f48e84a90b0bbd95be)
+++ sansmodels/src/sans/models/c_models/c_models.cpp	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -31,4 +31,5 @@
 void addCLamellarModel(PyObject *module);
 void addCLamellarFFHGModel(PyObject *module);
+void addCHollowCylinderModel(PyObject *module);
 
 
@@ -181,7 +182,9 @@
 	addCLamellarModel(m);
 	addCLamellarFFHGModel(m);
+	addCHollowCylinderModel(m);
 	addDisperser(m);
 	addCGaussian(m);
 	addCLorentzian(m);
 
+
 }
Index: sansmodels/src/sans/models/c_models/hollowcylinder.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/hollowcylinder.cpp	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
+++ sansmodels/src/sans/models/c_models/hollowcylinder.cpp	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -0,0 +1,208 @@
+/**
+	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 2008, University of Tennessee
+ */
+
+/**
+ * Scattering model classes
+ * The classes use the IGOR library found in
+ *   sansmodels/src/libigor
+ *
+ *	TODO: refactor so that we pull in the old sansmodels.c_extensions
+ */
+
+#include <math.h>
+#include "models.hh"
+#include "parameters.hh"
+#include <stdio.h>
+using namespace std;
+
+extern "C" {
+	#include "libCylinder.h"
+	#include "hollow_cylinder.h"
+}
+
+HollowCylinderModel :: HollowCylinderModel() {
+	scale      = Parameter(1.0);
+	core_radius = Parameter(20.0, true);
+	core_radius.set_min(0.0);
+	shell_radius  = Parameter(30.0, true);
+	shell_radius.set_min(0.0);
+	length     = Parameter(400.0, true);
+	length.set_min(0.0);
+	contrast  = Parameter(5.3e-6);
+	background = Parameter(0.0);
+	axis_theta = Parameter(0.0, true);
+	axis_phi   = Parameter(0.0, true);
+}
+
+/**
+ * Function to evaluate 1D scattering function
+ * The NIST IGOR library is used for the actual calculation.
+ * @param q: q-value
+ * @return: function value
+ */
+double HollowCylinderModel :: operator()(double q) {
+	double dp[6];
+
+	dp[0] = scale();
+	dp[1] = core_radius();
+	dp[2] = shell_radius();
+	dp[3] = length();
+	dp[4] = contrast();
+	dp[5] = background();
+
+	// Get the dispersion points for the core radius
+	vector<WeightPoint> weights_core_radius;
+	core_radius.get_weights(weights_core_radius);
+
+	// Get the dispersion points for the shell radius
+	vector<WeightPoint> weights_shell_radius;
+	shell_radius.get_weights(weights_shell_radius);
+
+	// Get the dispersion points for the length
+	vector<WeightPoint> weights_length;
+	length.get_weights(weights_length);
+
+	// Perform the computation, with all weight points
+	double sum = 0.0;
+	double norm = 0.0;
+
+	// Loop over core radius weight points
+	for(int i=0; i< (int)weights_core_radius.size(); i++) {
+		dp[1] = weights_core_radius[i].value;
+
+		// Loop over length weight points
+		for(int j=0; j< (int)weights_length.size(); j++) {
+			dp[3] = weights_length[j].value;
+
+			// Loop over shell radius weight points
+			for(int k=0; k< (int)weights_shell_radius.size(); k++) {
+				dp[2] = weights_shell_radius[k].value;
+
+				sum += weights_core_radius[i].weight
+					* weights_length[j].weight
+					* weights_shell_radius[k].weight
+					* HollowCylinder(dp, q);
+				norm += weights_core_radius[i].weight
+				* weights_length[j].weight
+				* weights_shell_radius[k].weight;
+			}
+		}
+	}
+	return sum/norm + background();
+}
+
+/**
+ * Function to evaluate 2D scattering function
+ * @param q_x: value of Q along x
+ * @param q_y: value of Q along y
+ * @return: function value
+ */
+double HollowCylinderModel :: operator()(double qx, double qy) {
+	HollowCylinderParameters dp;
+	// Fill parameter array
+	dp.scale      = scale();
+	dp.core_radius     = core_radius();
+	dp.shell_radius  = shell_radius();
+	dp.length     = length();
+	dp.contrast   = contrast();
+	dp.background = background();
+	dp.axis_theta = axis_theta();
+	dp.axis_phi   = axis_phi();
+
+	// Get the dispersion points for the core radius
+	vector<WeightPoint> weights_core_radius;
+	core_radius.get_weights(weights_core_radius);
+
+	// Get the dispersion points for the shell radius
+	vector<WeightPoint> weights_shell_radius;
+	shell_radius.get_weights(weights_shell_radius);
+
+	// Get the dispersion points for the length
+	vector<WeightPoint> weights_length;
+	length.get_weights(weights_length);
+
+	// Get angular averaging for theta
+	vector<WeightPoint> weights_theta;
+	axis_theta.get_weights(weights_theta);
+
+	// Get angular averaging for phi
+	vector<WeightPoint> weights_phi;
+	axis_phi.get_weights(weights_phi);
+
+	// Perform the computation, with all weight points
+	double sum = 0.0;
+	double norm = 0.0;
+
+	// Loop over core radius weight points
+	for(int i=0; i<(int)weights_core_radius.size(); i++) {
+		dp.core_radius = weights_core_radius[i].value;
+
+
+		// Loop over length weight points
+		for(int j=0; j<(int)weights_length.size(); j++) {
+			dp.length = weights_length[j].value;
+
+			// Loop over shell radius weight points
+			for(int m=0; m< (int)weights_shell_radius.size(); m++) {
+				dp.shell_radius = weights_shell_radius[m].value;
+
+			// Average over theta distribution
+			for(int k=0; k< (int)weights_theta.size(); k++) {
+				dp.axis_theta = weights_theta[k].value;
+
+				// Average over phi distribution
+				for(int l=0; l< (int)weights_phi.size(); l++) {
+					dp.axis_phi = weights_phi[l].value;
+
+					double _ptvalue = weights_core_radius[i].weight
+						* weights_length[j].weight
+						* weights_shell_radius[m].weight
+						* weights_theta[k].weight
+						* weights_phi[l].weight
+						* hollow_cylinder_analytical_2DXY(&dp, qx, qy);
+					if (weights_theta.size()>1) {
+						_ptvalue *= sin(weights_theta[k].value);
+					}
+					sum += _ptvalue;
+
+					norm += weights_core_radius[i].weight
+						* weights_length[j].weight
+						* weights_shell_radius[m].weight
+						* weights_theta[k].weight
+						* weights_phi[l].weight;
+
+				}
+			}
+			}
+		}
+	}
+	// Averaging in theta needs an extra normalization
+	// factor to account for the sin(theta) term in the
+	// integration (see documentation).
+	if (weights_theta.size()>1) norm = norm / asin(1.0);
+	return sum/norm + background();
+}
+
+/**
+ * Function to evaluate 2D scattering function
+ * @param pars: parameters of the  cylinder
+ * @param q: q-value
+ * @param phi: angle phi
+ * @return: function value
+ */
+double HollowCylinderModel :: evaluate_rphi(double q, double phi) {
+	double qx = q*cos(phi);
+	double qy = q*sin(phi);
+	return (*this).operator()(qx, qy);
+}
Index: sansmodels/src/sans/models/c_models/models.hh
===================================================================
--- sansmodels/src/sans/models/c_models/models.hh	(revision 34c30203f24453aa528815f48e84a90b0bbd95be)
+++ sansmodels/src/sans/models/c_models/models.hh	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -463,4 +463,23 @@
 	double evaluate_rphi(double q, double phi);
 };
-
+class HollowCylinderModel{
+public:
+	// Model parameters
+	Parameter scale;
+	Parameter core_radius;
+	Parameter shell_radius;
+	Parameter length;
+	Parameter contrast;
+	Parameter background;
+	Parameter axis_theta;
+	Parameter axis_phi;
+	
+	//Constructor
+	HollowCylinderModel();
+	
+	//Operators to get I(Q)
+	double operator()(double q);
+	double operator()(double qx , double qy);
+	double evaluate_rphi(double q, double phi);
+};
 #endif
Index: sansmodels/src/sans/models/pluginmodel.py
===================================================================
--- sansmodels/src/sans/models/pluginmodel.py	(revision 996fd352037c03498202bc677a51d54a2dcbdc1b)
+++ sansmodels/src/sans/models/pluginmodel.py	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -31,4 +31,5 @@
         else:
             return self.function(x)
+        
    
     def runXY(self, x = 0.0):
Index: sansmodels/src/setup.py
===================================================================
--- sansmodels/src/setup.py	(revision 6b4decc9438c6a793ecb9da750c7da7af0877212)
+++ sansmodels/src/setup.py	(revision 27fea3fd73c362e927fb15e5806e0a587260c5f3)
@@ -11,4 +11,5 @@
 """
 import sys
+
 
 
@@ -132,4 +133,8 @@
         "sans/models/c_models/coreshellcylinder.cpp",
         srcdir+"/core_shell_cylinder.c",
+        #srcdir+"/CHollowCylinderModel.c",
+        "sans/models/c_models/CHollowCylinderModel.cpp",
+        "sans/models/c_models/hollowcylinder.cpp",
+        srcdir+"/hollow_cylinder.c",
         #srcdir+"/CCoreShellModel.c",
         #srcdir+"/core_shell.c",
