Index: sansmodels/src/sans/models/c_extensions/libmultifunc/libfunc.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/libmultifunc/libfunc.c	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
+++ sansmodels/src/sans/models/c_extensions/libmultifunc/libfunc.c	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
@@ -0,0 +1,51 @@
+#include <math.h>
+#include "libmultifunc/libfunc.h"
+#include <stdio.h>
+
+//used in Si func
+int factorial(int i)
+{
+	int k, j;
+	if (i<2){
+		return 1;
+	}
+	k=1;
+	for(j=1;j<i;j++)
+	{
+		k=k*(j+1);
+	}
+	return k;
+}
+
+// Used in pearl nec model
+//integral of sin(x)/x up to namx term nmax>10 looks fine.
+double Si(double x, int nmax )
+{
+	int i;
+	double out;
+	long double power;
+	if (x > 5.0){
+		double pi = 4.0*atan(1.0);
+		return pi/2.0;
+	}
+	out = 0.0;
+	for (i=0; i<nmax; i+=1)
+	{
+		if (i==0){
+			out += x;
+			continue;
+		}
+		power = pow(x,(2 * i + 1));
+		out += (double)pow(-1, i) * power / ((2.0 * (double)i + 1.0) * (double)factorial(2 * i + 1));
+		//printf ("Si=%g %g %d\n", x, out, i);
+	}
+	return out;
+}
+
+double sin_x(double x)
+{
+	if (x==0){
+		return 1.0;
+	}
+	return sin(x)/x;
+}
Index: sansmodels/src/sans/models/c_extensions/libmultifunc/libfunc.h
===================================================================
--- sansmodels/src/sans/models/c_extensions/libmultifunc/libfunc.h	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
+++ sansmodels/src/sans/models/c_extensions/libmultifunc/libfunc.h	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
@@ -0,0 +1,10 @@
+#if !defined(o_h)
+#define libfunc_h
+
+int factorial(int i);
+
+double Si(double x, int nmax );
+
+double sin_x(double x);
+
+#endif
Index: sansmodels/src/sans/models/c_extensions/pearlnecklace.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/pearlnecklace.c	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
+++ sansmodels/src/sans/models/c_extensions/pearlnecklace.c	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
@@ -0,0 +1,153 @@
+/**
+ * spheresld model
+ */
+#include <math.h>
+#include "pearlnecklace.h"
+#include "libmultifunc/libfunc.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+double pearl_necklace_kernel(double dp[], double q) {
+	// fit parameters
+	double scale = dp[0];
+	double radius = dp[1];
+	double edge_separation = dp[2];
+	double thick_string = dp[3];
+	double num_pearls = dp[4];
+	double sld_pearl = dp[5];
+	double sld_string = dp[6];
+	double sld_solv = dp[7];
+	double background = dp[8];
+
+	//relative slds
+	double contrast_pearl = sld_pearl - sld_solv;
+	double contrast_string = sld_string - sld_solv;
+
+	// number of string segments
+	double num_strings = num_pearls - 1.0;
+
+	//Pi
+	double pi = 4.0*atan(1.0);
+
+	// each volumes
+	double string_vol = edge_separation * pi * pow((thick_string / 2.0), 2);
+	double pearl_vol = 4.0 /3.0 * pi * pow(radius, 3);
+
+	//total volume
+	double tot_vol;
+	tot_vol = num_strings * string_vol;
+	tot_vol += num_pearls * pearl_vol;
+
+	//each masses
+	double m_r= contrast_string * string_vol;
+	double m_s= contrast_pearl * pearl_vol;
+
+	//sine functions of a pearl
+	double psi;
+	psi = sin(q*radius);
+	psi -= q * radius * cos(q * radius);
+	psi /= pow((q * radius), 3);
+	psi *= 3.0;
+
+	// Note take only 20 terms in Si series: 10 terms may be enough though.
+	double gamma;
+	gamma = Si(q* edge_separation, 6);
+	gamma /= (q* edge_separation);
+	double beta;
+	beta = Si(q * (edge_separation + radius), 6);
+	beta -= Si(q * radius, 6);
+	beta /= (q* edge_separation);
+
+	//form factors
+	double sss; //pearls
+	double srr; //strings
+	double srs; //cross
+	// center to center distance between the neighboring pearls
+	double A_s = edge_separation + 2.0 * radius;
+
+	// form factor for num_pearls
+	sss = 1.0 - pow(sin_x(q*A_s), (int)num_pearls );
+	sss /= pow((1.0-sin_x(q*A_s)), 2);
+	sss *= sin_x(q*A_s);
+	sss -= num_pearls/2.0;
+	sss += num_pearls/(1.0-sin_x(q*A_s));
+	sss *= 2.0 * pow((m_s*psi), 2);
+
+	// form factor for num_strings (like thin rods)
+	double srr_1;
+	srr_1 = -pow(sin_x(q*edge_separation/2.0), 2);
+	//printf ("sss %g, %g, %g\n",sss, srr_1, gamma);
+	srr_1 += 2.0 * gamma;
+	srr_1 *= num_strings;
+	double srr_2;
+	srr_2 = 2.0/(1.0-sin_x(q*A_s));
+	srr_2 *= num_strings;
+	srr_2 *= pow(beta, 2);
+	double srr_3;
+	srr_3 = 1.0 - pow(sin_x(q*A_s), (int)num_strings);
+	srr_3 /= pow((1.0-sin_x(q*A_s)), 2);
+	srr_3 *= pow(beta, 2);
+	srr_3 *= -2.0;
+
+	// total srr
+	srr = srr_1 + srr_2 + srr_3;
+	srr *= pow(m_r, 2);
+
+	// form factor for correlations
+	srs = -1.0;
+	srs -= pow(sin_x(q*A_s), (int)num_strings);
+	srs /= pow((1.0-sin_x(q*A_s)), 2);
+	srs *= sin_x(q*A_s);
+	srs += (num_strings/(1.0-sin_x(q*A_s)));
+	srs *= 4.0;
+	srs *= (m_r * m_s * beta * psi);
+
+	double form_factor;
+	form_factor = sss + srr + srs;
+	form_factor /= (tot_vol * 1.0e-8); // norm by volume and A^-1 to cm^-1
+
+	// scale and background
+	form_factor *= scale;
+	form_factor += background;
+
+    return (form_factor);
+}
+
+/**
+ * Function to evaluate pearlnecklace function
+ * @param pars: parameters of pearlnecklace
+ * @param q: q-value
+ * @return: function value
+ */
+
+double pearl_necklace_analytical_1D(PeralNecklaceParameters *pars, double q) {
+	double dp[9];
+
+	dp[0] = pars->scale;
+	dp[1] = pars->radius;
+	dp[2] = pars->edge_separation;
+	dp[3] = pars->thick_string;
+	dp[4] = pars->num_pearls;
+	dp[5] = pars->sld_pearl;
+	dp[6] = pars->sld_string;
+	dp[7] = pars->sld_solv;
+	dp[8] = pars->background;
+
+	return pearl_necklace_kernel(dp, q);
+}
+
+/**
+ * Function to evaluate pearl_necklace function
+ * @param pars: parameters of PeralNecklace
+ * @param q: q-value
+ * @return: function value
+ */
+double pearl_necklace_analytical_2D(PeralNecklaceParameters *pars, double q, double phi) {
+	return pearl_necklace_analytical_1D(pars,q);
+}
+
+double pearl_necklace_analytical_2DXY(PeralNecklaceParameters *pars, double qx, double qy){
+	return pearl_necklace_analytical_1D(pars,sqrt(qx*qx+qy*qy));
+}
+
Index: sansmodels/src/sans/models/c_extensions/pearlnecklace.h
===================================================================
--- sansmodels/src/sans/models/c_extensions/pearlnecklace.h	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
+++ sansmodels/src/sans/models/c_extensions/pearlnecklace.h	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
@@ -0,0 +1,66 @@
+#if !defined(o_h)
+#define pearl_necklace_h
+
+/**
+ * Structure definition for sphere parameters
+ */
+ //[PYTHONCLASS] = PearlNecklaceModel
+ //[DISP_PARAMS] = radius, edge_separation
+ //[DESCRIPTION] =<text>Calculate form factor for Pearl Necklace Model
+//				[Macromol. Symp. 2004, 211, 25-42]
+ //				Parameters:
+ //				background:background
+ //				scale: scale factor
+ //				sld_pearl: the SLD of the pearl spheres
+ //	            sld_string: the SLD of the strings
+ //				sld_solv: the SLD of the solvent
+ //				num_pearls: number of the pearls
+ //				radius: the radius of a pearl
+ //				edge_separation: the length of sring segment; surface to surface
+ //				thick_string: thickness (ie, diameter) of the string
+ //		</text>
+ //[FIXED]=  <text>radius.width; edge_separation.width</text>
+ //[NON_FITTABLE_PARAMS]= <text></text>
+ //[ORIENTATION_PARAMS]= <text> </text>
+
+typedef struct {
+    /// Scale factor
+    //  [DEFAULT]=scale= 1.0
+	double scale;
+    ///	radius [A]
+    //  [DEFAULT]=radius=80.0 [A]
+	double radius;
+	///	edge_separation
+	//  [DEFAULT]=edge_separation= 350 [A]
+	double edge_separation;
+	///	thick_string [A]
+	//  [DEFAULT]=thick_string= 2.5 [A]
+	double thick_string;
+	///	num_pearls
+	//  [DEFAULT]=num_pearls= 3
+	double num_pearls;
+	///	sld_pearl
+	//  [DEFAULT]=sld_pearl= 1.0e-06 [1/A^(2)]
+	double sld_pearl;
+	///	sld_string
+	//  [DEFAULT]=sld_string= 5.0e-06 [1/A^(2)]
+	double sld_string;
+	///	sld_solv
+	//  [DEFAULT]=sld_solv= 0.5e-06 [1/A^(2)]
+	double sld_solv;
+	/// Background
+	//  [DEFAULT]=background=0
+	double background;
+
+}PeralNecklaceParameters;
+
+double pearl_necklace_kernel(double dq[], double q);
+
+/// 1D scattering function
+double pearl_necklace_analytical_1D(PeralNecklaceParameters *pars, double q);
+
+/// 2D scattering function
+double pearl_necklace_analytical_2D(PeralNecklaceParameters *pars, double q, double phi);
+double pearl_necklace_analytical_2DXY(PeralNecklaceParameters *pars, double qx, double qy);
+
+#endif
Index: sansmodels/src/sans/models/c_models/c_models.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/c_models.cpp	(revision 59b9b67578f11772d51a4d61028e0dfc7097df5a)
+++ sansmodels/src/sans/models/c_models/c_models.cpp	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
@@ -20,4 +20,5 @@
 void addCSphereSLDModel(PyObject *module);
 void addCOnionModel(PyObject *module);
+void addCPearlNecklaceModel(PyObject *module);
 void addCReflModel(PyObject *module);
 void addCReflAdvModel(PyObject *module);
@@ -282,7 +283,5 @@
 	addCDiamCylFunc(m);
 	addCSLDCalFunc(m);
-
-//	addCOblateModel(m);
-//	addCProlateModel(m);
+	addCPearlNecklaceModel(m);
 	addCLamellarModel(m);
 	addCLamellarFFHGModel(m);
Index: sansmodels/src/sans/models/c_models/models.hh
===================================================================
--- sansmodels/src/sans/models/c_models/models.hh	(revision 96656e3ad6cdb9f8256e2118c60bac29635136af)
+++ sansmodels/src/sans/models/c_models/models.hh	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
@@ -562,4 +562,27 @@
 
 
+class PearlNecklaceModel{
+public:
+	// Model parameters
+	Parameter scale;
+	Parameter radius;
+	Parameter edge_separation;
+	Parameter thick_string;
+	Parameter num_pearls;
+	Parameter sld_pearl;
+	Parameter sld_string;
+	Parameter sld_solv;
+	Parameter background;
+
+	// Constructor
+	PearlNecklaceModel();
+
+	// Operators to get I(Q)
+	double operator()(double q);
+	double operator()(double qx, double qy);
+	double calculate_ER();
+	double evaluate_rphi(double q, double phi);
+};
+
 class FCCrystalModel{
 public:
Index: sansmodels/src/sans/models/c_models/pearlnecklace.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/pearlnecklace.cpp	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
+++ sansmodels/src/sans/models/c_models/pearlnecklace.cpp	(revision 8c8cb057f0c1e50cdc80f9ebce08f129f6f1ed26)
@@ -0,0 +1,177 @@
+
+#include <math.h>
+#include "models.hh"
+#include "parameters.hh"
+#include <stdio.h>
+using namespace std;
+
+extern "C" {
+	#include "pearlnecklace.h"
+}
+
+PearlNecklaceModel :: PearlNecklaceModel() {
+	scale = Parameter(1.0);
+	radius = Parameter(80.0, true);
+	radius.set_min(0.0);
+	edge_separation = Parameter(350.0, true);
+	edge_separation.set_min(0.0);
+	thick_string = Parameter(2.5, true);
+	thick_string.set_min(0.0);
+	num_pearls = Parameter(3);
+	num_pearls.set_min(0.0);
+	sld_pearl = Parameter(1.0e-06);
+	sld_string = Parameter(5.0e-06);
+	sld_solv = Parameter(0.5e-06);
+    background = Parameter(0.0);
+
+}
+
+/**
+ * Function to evaluate 1D PearlNecklaceModel function
+ * @param q: q-value
+ * @return: function value
+ */
+double PearlNecklaceModel :: operator()(double q) {
+	double dp[9];
+	// Fill parameter array for IGOR library
+	// Add the background after averaging
+	dp[0] = scale();
+	dp[1] = radius();
+	dp[2] = edge_separation();
+	dp[3] = thick_string();
+	dp[4] = num_pearls();
+	dp[5] = sld_pearl();
+	dp[6] = sld_string();
+	dp[7] = sld_solv();
+	dp[8] = 0.0;
+	double pi = 4.0*atan(1.0);
+	// No polydispersion supported in this model.
+	// Get the dispersion points for the radius
+	vector<WeightPoint> weights_radius;
+	radius.get_weights(weights_radius);
+	vector<WeightPoint> weights_edge_separation;
+	edge_separation.get_weights(weights_edge_separation);
+	// Perform the computation, with all weight points
+	double sum = 0.0;
+	double norm = 0.0;
+	double vol = 0.0;
+	double string_vol = 0.0;
+	double pearl_vol = 0.0;
+	double tot_vol = 0.0;
+	// Loop over core weight points
+	for(int i=0; i<weights_radius.size(); i++) {
+		dp[1] = weights_radius[i].value;
+		// Loop over thick_inter0 weight points
+		for(int j=0; j<weights_edge_separation.size(); j++) {
+			dp[2] = weights_edge_separation[j].value;
+			pearl_vol = 4.0 /3.0 * pi * pow(dp[1], 3);
+			string_vol =dp[2] * pi * pow((dp[3] / 2.0), 2);
+			tot_vol = (dp[4] - 1.0) * string_vol;
+			tot_vol += dp[4] * pearl_vol;
+			//Un-normalize Sphere by volume
+			sum += weights_radius[i].weight * weights_edge_separation[j].weight
+				* pearl_necklace_kernel(dp,q) * tot_vol;
+			//Find average volume
+			vol += weights_radius[i].weight * weights_edge_separation[j].weight
+				* tot_vol;
+			norm += weights_radius[i].weight * weights_edge_separation[j].weight;
+		}
+	}
+
+	if (vol != 0.0 && norm != 0.0) {
+		//Re-normalize by avg volume
+		sum = sum/(vol/norm);}
+
+	return sum/norm + background();
+}
+
+/**
+ * Function to evaluate 2D PearlNecklaceModel function
+ * @param q_x: value of Q along x
+ * @param q_y: value of Q along y
+ * @return: function value
+ */
+double PearlNecklaceModel :: operator()(double qx, double qy) {
+	double q = sqrt(qx*qx + qy*qy);
+	return (*this).operator()(q);
+}
+
+/**
+ * Function to evaluate PearlNecklaceModel function
+ * @param pars: parameters of the PearlNecklaceModel
+ * @param q: q-value
+ * @param phi: angle phi
+ * @return: function value
+ */
+double PearlNecklaceModel :: evaluate_rphi(double q, double phi) {
+	return (*this).operator()(q);
+}
+
+/**
+ * Function to calculate TOTAL radius
+ * Todo: decide whether or not we keep this calculation
+ * @return: effective radius value
+ */
+// No polydispersion supported in this model.
+// Calculate max radius assumming max_radius = effective radius
+// Note that this max radius is not affected by sld of layer, sld of interface, or
+// sld of solvent.
+double PearlNecklaceModel :: calculate_ER() {
+	PeralNecklaceParameters dp;
+
+	dp.scale = scale();
+	dp.radius = radius();
+	dp.edge_separation = edge_separation();
+	dp.thick_string = thick_string();
+	dp.num_pearls = num_pearls();
+
+	double rad_out = 0.0;
+	// Perform the computation, with all weight points
+	double sum = 0.0;
+	double norm = 0.0;
+	double pi = 4.0*atan(1.0);
+	// No polydispersion supported in this model.
+	// Get the dispersion points for the radius
+	vector<WeightPoint> weights_radius;
+	radius.get_weights(weights_radius);
+	vector<WeightPoint> weights_edge_separation;
+	edge_separation.get_weights(weights_edge_separation);
+	// Perform the computation, with all weight points
+	double string_vol = 0.0;
+	double pearl_vol = 0.0;
+	double tot_vol = 0.0;
+	// Loop over core weight points
+	for(int i=0; i<weights_radius.size(); i++) {
+		dp.radius = weights_radius[i].value;
+		// Loop over thick_inter0 weight points
+		for(int j=0; j<weights_edge_separation.size(); j++) {
+			dp.edge_separation = weights_edge_separation[j].value;
+			pearl_vol = 4.0 /3.0 * pi * pow(dp.radius , 3);
+			string_vol =dp.edge_separation * pi * pow((dp.thick_string / 2.0), 2);
+			tot_vol = (dp.num_pearls - 1.0) * string_vol;
+			tot_vol += dp.num_pearls * pearl_vol;
+			//Find  volume
+			// This may be a too much approximation
+			//Todo: decided whether or not we keep this calculation
+			sum += weights_radius[i].weight * weights_edge_separation[j].weight
+				* pow(3.0*tot_vol/4.0/pi,0.333333);
+			norm += weights_radius[i].weight * weights_edge_separation[j].weight;
+		}
+	}
+
+	if (norm != 0){
+		//return the averaged value
+		rad_out =  sum/norm;}
+	else{
+		//return normal value
+		pearl_vol = 4.0 /3.0 * pi * pow(dp.radius , 3);
+		string_vol =dp.edge_separation * pi * pow((dp.thick_string / 2.0), 2);
+		tot_vol = (dp.num_pearls - 1.0) * string_vol;
+		tot_vol += dp.num_pearls * pearl_vol;
+
+		rad_out =  pow((3.0*tot_vol/4.0/pi), 0.33333);
+		}
+
+	return rad_out;
+
+}
