diff --git a/fibre.h b/fibre.h
index 8aca32d8401f61909a717b44dbc1053ae8c938d2..93d0bd137c59d18503351ba79c6154e2f0af0ccf 100644
--- a/fibre.h
+++ b/fibre.h
@@ -59,16 +59,17 @@ namespace FIBRE{
     ColumnVector m_Signal; 
     ColumnVector m_Signal_old; 
     const float& m_d;
+    const float& m_d_std; //second d param in multi-shell model - std in gamma dist of diffusivities
     const ColumnVector& m_alpha;
     const ColumnVector& m_beta;
     const Matrix& m_bvals;
+    const int& m_modelnum; 
  public:
     //constructors::
 
     Fibre( const ColumnVector& alpha, const ColumnVector& beta, 
-	   const Matrix& bvals,const float& d,const float& ardfudge=1):
-     m_ardfudge(ardfudge), m_d(d), m_alpha(alpha), m_beta(beta), m_bvals(bvals){
-
+	   const Matrix& bvals,const float& d,const float& ardfudge=1,const int& modelnum=1, const float& d_std=0.01):
+      m_ardfudge(ardfudge), m_d(d),m_d_std(d_std), m_alpha(alpha), m_beta(beta), m_bvals(bvals), m_modelnum(modelnum){
 	m_th=M_PI/2;
 	m_th_old=m_th;
 	m_ph=0;
@@ -112,10 +113,10 @@ namespace FIBRE{
     Fibre(const ColumnVector& alpha, 
 	  const ColumnVector& beta, const Matrix& bvals, const float& d, const float& ardfudge,
 	  const float& th, const float& ph, const float& f, 
-	  const float& lam, const bool lam_jump=true) : 
-      m_th(th), m_ph(ph), m_f(f), m_lam(lam), m_ardfudge(ardfudge),m_lam_jump(lam_jump),  m_d(d),
-      m_alpha(alpha), m_beta(beta), m_bvals(bvals)
-     {
+	  const float& lam, const bool lam_jump=true, const int& modelnum=1, const float& d_std=0.01) : 
+      m_th(th), m_ph(ph), m_f(f), m_lam(lam), m_ardfudge(ardfudge),m_lam_jump(lam_jump),  m_d(d), m_d_std(d_std), m_alpha(alpha), m_beta(beta), m_bvals(bvals), m_modelnum(modelnum)
+    {
+      
       m_th_old=m_th;
       m_ph_old=m_ph;
       m_f_old=m_f;
@@ -127,7 +128,7 @@ namespace FIBRE{
       
       m_th_prior=0;
       compute_th_prior();
-
+      
       m_ph_prior=0;
       compute_ph_prior();
       
@@ -137,7 +138,7 @@ namespace FIBRE{
       //cc      OUT(m_ardfudge);
       m_lam_prior=0;
       compute_lam_prior();
-
+      
 
       m_Signal.ReSize(alpha.Nrows());
       m_Signal=0;
@@ -153,7 +154,7 @@ namespace FIBRE{
      
     }
     Fibre(const Fibre& rhs): 
-      m_d(rhs.m_d), m_alpha(rhs.m_alpha), m_beta(rhs.m_beta), m_bvals(rhs.m_bvals){
+      m_d(rhs.m_d), m_d_std(rhs.m_d_std), m_alpha(rhs.m_alpha), m_beta(rhs.m_beta), m_bvals(rhs.m_bvals), m_modelnum(rhs.m_modelnum){
       *this=rhs;
     }
 
@@ -224,6 +225,7 @@ namespace FIBRE{
     }
 
     inline float get_prior() const{ return m_prior_en;}
+    inline float get_modelnum() const{ return m_modelnum;}
     
 
     inline void update_proposals(){
@@ -312,12 +314,25 @@ namespace FIBRE{
        for (int i = 1; i <= m_alpha.Nrows(); i++){
  	float angtmp=cos(m_ph-m_beta(i))*sin(m_alpha(i))*sin(m_th) + cos(m_alpha(i))*cos(m_th);
  	angtmp=angtmp*angtmp;
- 	m_Signal(i)=exp(-m_d*m_bvals(1,i)*angtmp);
+	if(m_modelnum==1){
+	  m_Signal(i)=exp(-m_d*m_bvals(1,i)*angtmp);
+	  //	  cout<<"here"<<endl;
+	}
+	else if(m_modelnum==2){
+	  float dalpha=m_d*m_d/(m_d_std*m_d_std);
+	  float dbeta=m_d/(m_d_std*m_d_std);
+	  m_Signal(i)=exp( log(dbeta/(dbeta + m_bvals(1,i)*angtmp)) *dalpha ); //gamma distribution of diffusivities - params alpha (m_d) and beta (m_d_beta): Expected signal is (beta./(beta+b*g(th,ph))).^alpha;
+	  //cout<<i<<" "<<angtmp<<" "<<m_d_std<<" "<<m_d<<endl;
+	  //cout<<"balh "<<m_Signal(i)<<endl;
+
+	}
+
        }
      }
 
 
     inline bool propose_th(){
+      //cout<<"th"<<endl;
       m_th_old=m_th;
       m_th+=normrnd().AsScalar()*m_th_prop;
       bool rejflag=compute_th_prior();//inside this it stores the old prior
@@ -339,6 +354,7 @@ namespace FIBRE{
     }
     
     inline bool propose_ph(){
+      //cout<<"ph"<<endl;
       m_ph_old=m_ph;
       m_ph+=normrnd().AsScalar()*m_ph_prop;
        bool rejflag=compute_ph_prior();//inside this it stores the old prior
@@ -362,6 +378,7 @@ namespace FIBRE{
     
     bool propose_th_ph(float th,float ph){
       //m_th_old=m_th;m_ph_old=m_ph;
+      //cout<<"thph"<<endl;
       m_th=th;m_ph=ph;
       bool rejflag_th=compute_th_prior();//inside this it stores the old prior
       bool rejflag_ph=compute_ph_prior();
@@ -390,6 +407,7 @@ namespace FIBRE{
     }
 
     inline bool propose_f( bool can_use_ard=true){
+      //cout<<"f"<<endl;
       m_f_old=m_f;
       m_f+=normrnd().AsScalar()*m_f_prop;
       bool rejflag=compute_f_prior(can_use_ard);
@@ -409,6 +427,7 @@ namespace FIBRE{
     }
     
     inline bool propose_lam(){
+      //cout<<"lam"<<endl;
       if(m_lam_jump){
 	m_lam_old=m_lam;
 	m_lam+=normrnd().AsScalar()*m_lam_prop;
@@ -489,6 +508,13 @@ namespace FIBRE{
     float m_d_old_prior;
     float m_d_acc;
     float m_d_rej;
+    float m_d_std; //second d param in multi-shell model - std in gamma dist of diffusivities - to get non-monoexponential decay. 
+    float m_d_std_old;
+    float m_d_std_prop;
+    float m_d_std_prior; 
+    float m_d_std_old_prior;
+    float m_d_std_acc;
+    float m_d_std_rej;
     float m_S0;
     float m_S0_old;
     float m_S0_prop;
@@ -508,14 +534,17 @@ namespace FIBRE{
     const ColumnVector& m_alpha;
     const ColumnVector& m_beta;
     const Matrix& m_bvals;
+    const int& m_modelnum;
     
+
   public:
     // empty constructor
 
     Multifibre(const ColumnVector& data,const ColumnVector& alpha, 
-	       const ColumnVector& beta, const Matrix& b, int N ,float ardfudge=1):
-      m_ardfudge(ardfudge),m_data(data), m_alpha(alpha), m_beta(beta), m_bvals(b){
+	       const ColumnVector& beta, const Matrix& b, int N ,float ardfudge=1, int modelnum=1):
+      m_ardfudge(ardfudge),m_data(data), m_alpha(alpha), m_beta(beta), m_bvals(b), m_modelnum(modelnum){
       //      initialise(Amat,N);
+
     }
     
     ~Multifibre(){}
@@ -528,17 +557,19 @@ namespace FIBRE{
     }
     
     void addfibre(const float th, const float ph, const float f,const float lam, const bool lam_jump=true){
-      Fibre fib(m_alpha,m_beta,m_bvals,m_d,m_ardfudge,th,ph,f,lam,lam_jump);
+      Fibre fib(m_alpha,m_beta,m_bvals,m_d,m_ardfudge,th,ph,f,lam,lam_jump,m_modelnum,m_d_std);
       m_fibres.push_back(fib);
     }
 
     void addfibre(){
-      Fibre fib(m_alpha,m_beta,m_bvals,m_d,m_ardfudge);
+      Fibre fib(m_alpha,m_beta,m_bvals,m_d,m_ardfudge,m_modelnum,m_d_std);
       m_fibres.push_back(fib);
     }
     
     void initialise_energies(){
       compute_d_prior();
+      if(m_modelnum==2)
+	compute_d_std_prior();
       compute_S0_prior();
       m_prior_en=0;
       compute_prior();
@@ -550,11 +581,15 @@ namespace FIBRE{
     void initialise_props(){
       m_S0_prop=m_S0/10; //must have set inital values before this is called;
       m_d_prop=m_d/10;
+      m_d_std_prop=m_d_std/10;
     }
     
     inline float get_d() const{ return m_d;}
     inline void set_d(const float d){ m_d=d; }
 
+    inline float get_d_std() const{ return m_d_std;}
+    inline void set_d_std(const float d_std){ m_d_std=d_std; }
+
     inline int get_nfibre(){return m_fibres.size();}
     
     inline float get_energy() const { return m_likelihood_en+m_prior_en;}
@@ -572,6 +607,13 @@ namespace FIBRE{
       OUT(m_d_old_prior);
       OUT(m_d_acc);
       OUT(m_d_rej);
+      OUT(m_d_std);
+      OUT(m_d_std_old);
+      OUT(m_d_std_prop);
+      OUT(m_d_std_prior); 
+      OUT(m_d_std_old_prior);
+      OUT(m_d_std_acc);
+      OUT(m_d_std_rej);
       OUT(m_S0);
       OUT(m_S0_old);
       OUT(m_S0_prop);
@@ -598,6 +640,16 @@ namespace FIBRE{
 	return false;
       }
     }
+
+    inline bool compute_d_std_prior(){
+      m_d_std_old_prior=m_d_std_prior;
+      if(m_d_std<0)
+	return true;
+      else{
+	m_d_std_prior=0;
+	return false;
+      }
+    }
     
     inline bool compute_S0_prior(){
       m_S0_old_prior=m_S0_prior;
@@ -620,6 +672,8 @@ namespace FIBRE{
     inline void compute_prior(){
       m_old_prior_en=m_prior_en;
       m_prior_en=m_d_prior+m_S0_prior;
+      if(m_modelnum==2)
+	m_prior_en=m_prior_en+m_d_std_prior;
       for(unsigned int f=0;f<m_fibres.size(); f++){
 	m_prior_en=m_prior_en+m_fibres[f].get_prior();
       } 
@@ -635,16 +689,21 @@ namespace FIBRE{
 	pred=pred+m_fibres[f].get_f()*m_fibres[f].getSignal();
 	fsum+=m_fibres[f].get_f();
       }
+
       for(int i=1;i<=pred.Nrows();i++){
-	pred(i)=pred(i)+(1-fsum)*exp(-m_d*m_bvals(1,i));
+	if(m_modelnum==1)
+	  pred(i)=pred(i)+(1-fsum)*exp(-m_d*m_bvals(1,i));
+	else if(m_modelnum==2){
+	  float dalpha=m_d*m_d/(m_d_std*m_d_std);
+	  float dbeta=m_d/(m_d_std*m_d_std);
+	  pred(i)=pred(i)+(1-fsum)*exp(log(dbeta/(dbeta+m_bvals(1,i)))*dalpha);
+	}
       }
       pred=pred*m_S0;
       
-
-
       float sumsquares=(m_data-pred).SumSquare();
       m_likelihood_en=(m_data.Nrows()/2)*log(sumsquares/2);
-     
+      
     }
     
   
@@ -673,6 +732,7 @@ namespace FIBRE{
 
     bool test_energy(){
       float tmp=exp(m_old_energy-m_energy);
+      //cout<<m_old_energy<< " " << m_energy <<endl;
       return (tmp>unifrnd().AsScalar());
     }
     
@@ -688,6 +748,7 @@ namespace FIBRE{
     }
 
     inline bool propose_d(){
+      //cout<<"d"<<endl;
       m_d_old=m_d;
       m_d+=normrnd().AsScalar()*m_d_prop;
       bool rejflag=compute_d_prior();//inside this it stores the old prior
@@ -708,8 +769,31 @@ namespace FIBRE{
 	m_fibres[f].restoreSignal();
       m_d_rej++;
     }
+    inline bool propose_d_std(){
+      //cout<<"d_std"<<endl;
+      m_d_std_old=m_d_std;
+      m_d_std+=normrnd().AsScalar()*m_d_std_prop;
+      bool rejflag=compute_d_std_prior();//inside this it stores the old prior
+      for(unsigned int f=0;f<m_fibres.size();f++)
+	m_fibres[f].compute_signal();
+      return rejflag;
+    };
+    
+    inline void accept_d_std(){
+      m_d_std_acc++;      
+    }
+    
+    inline void reject_d_std(){      
+      m_d_std=m_d_std_old;
+      m_d_std_prior=m_d_std_old_prior;
+      m_prior_en=m_old_prior_en;
+      for(unsigned int f=0;f<m_fibres.size();f++)
+	m_fibres[f].restoreSignal();
+      m_d_std_rej++;
+    }
     
     inline bool propose_S0(){
+      //cout<<"S0"<<endl;
       m_S0_old=m_S0;
       m_S0+=normrnd().AsScalar()*m_S0_prop;
       bool rejflag=compute_S0_prior();//inside this it stores the old prior
@@ -730,6 +814,12 @@ namespace FIBRE{
     inline void update_proposals(){
       m_d_prop*=sqrt(float(m_d_acc+1)/float(m_d_rej+1));
       m_d_prop=min(m_d_prop,maxfloat);
+      if(m_modelnum==2){
+	m_d_std_prop*=sqrt(float(m_d_std_acc+1)/float(m_d_std_rej+1));
+	m_d_std_prop=min(m_d_std_prop,maxfloat);
+	m_d_std_acc=0; 
+	m_d_std_rej=0;
+      }
       m_S0_prop*=sqrt(float(m_S0_acc+1)/float(m_S0_rej+1));
       m_S0_prop=min(m_S0_prop,maxfloat);
       m_d_acc=0; 
@@ -747,7 +837,9 @@ namespace FIBRE{
     
 
     void jump( bool can_use_ard=true ){
-      
+      //       cout<<"modelnum "<<m_modelnum<<endl;
+      //       cout<<"fmodelnum "<<m_fibres[0].get_modelnum()<<endl;
+      //       cout<<"fmodelnum2 "<<m_fibres[1].get_modelnum()<<endl;
       if(!propose_d()){
 	compute_prior();
 	compute_likelihood();
@@ -764,6 +856,23 @@ namespace FIBRE{
 	reject_d();
       }
       
+      if(m_modelnum==2){
+	if(!propose_d_std()){
+	  compute_prior();
+	  compute_likelihood();
+	  compute_energy();
+	  if(test_energy()){
+	    accept_d_std();
+	  }
+	  else{
+	    reject_d_std();
+	    restore_energy();
+	  }
+	}
+	else{ 
+	  reject_d_std();
+	}
+      }
       if(!propose_S0()){
 	compute_prior();
 	compute_likelihood();
@@ -780,8 +889,8 @@ namespace FIBRE{
       } 
       
       for(unsigned int f=0;f<m_fibres.size();f++){
-	//cout<<"pre th"<<m_fibres[f].get_th()<<endl;	
-	//	cout << m_fibres[f].getSignal()<<endl;
+	//cout<<"pre th "<<m_fibres[f].get_th()<<endl;	
+	//cout << m_fibres[f].getSignal()<<endl;
 	//cout<<"prior"<<m_prior_en<<endl;
 	//cout<<"lik"<<m_likelihood_en<<endl;
 	//cout<<"energy"<<m_energy<<endl;
@@ -791,15 +900,17 @@ namespace FIBRE{
 	  compute_prior();
 	  compute_likelihood();
 	  compute_energy();
-	  //cout<<"pre th"<<m_fibres[f].get_th()<<endl;	
-	  //	cout << m_fibres[f].getSignal()<<endl;
+
+	  //cout<<"post th "<<m_fibres[f].get_th()<<endl;	
+	  //cout<< m_d<< " " <<m_d_std<<endl;
+	  //cout << m_fibres[f].getSignal()<<endl;
 	  //cout<<"prior"<<m_prior_en<<endl;
 	  //cout<<"lik"<<m_likelihood_en<<endl;
 	  //cout<<"energy"<<m_energy<<endl;
 	  	  
 	  if(test_energy()){
 	    m_fibres[f].accept_th();
-	  //cout<<"accepted"<<endl;}
+	  //cout<<"Accepted"<<endl;}
 	  }
 	  else{
 	    m_fibres[f].reject_th();
@@ -879,6 +990,13 @@ namespace FIBRE{
       m_d_old_prior=rhs.m_d_old_prior;
       m_d_acc=rhs.m_d_acc;
       m_d_rej=rhs.m_d_rej;
+      m_d_std=rhs.m_d_std;
+      m_d_std_old=rhs.m_d_std_old;
+      m_d_std_prop=rhs.m_d_std_prop;
+      m_d_std_prior=rhs.m_d_std_prior; 
+      m_d_std_old_prior=rhs.m_d_std_old_prior;
+      m_d_std_acc=rhs.m_d_std_acc;
+      m_d_std_rej=rhs.m_d_std_rej;
       m_S0=rhs.m_S0;
       m_S0_old=rhs.m_S0_old;
       m_S0_prop=rhs.m_S0_prop;
@@ -893,7 +1011,7 @@ namespace FIBRE{
       m_energy=rhs.m_energy;
       m_old_energy=rhs.m_old_energy;
       m_ardfudge=rhs.m_ardfudge;
-
+      
       return *this;
     }
     
diff --git a/xfibresoptions.h b/xfibresoptions.h
index 0e431453c4bc4538fc6561cb534b0a4ff344133a..0b0ad776b5776a647b85b2f5cbd7f2b185df7e7a 100644
--- a/xfibresoptions.h
+++ b/xfibresoptions.h
@@ -36,6 +36,7 @@ class xfibresOptions {
   Option<string> bvecsfile;
   Option<string> bvalsfile;
   Option<int> nfibres;
+  Option<int> modelnum;
   Option<float> fudge;
   Option<int> njumps;
   Option<int> nburn;
@@ -46,6 +47,7 @@ class xfibresOptions {
   Option<bool> no_ard;
   Option<bool> all_ard;
   Option<bool> localinit;
+  Option<bool> nonlin;
   void parse_command_line(int argc, char** argv,  Log& logger);
   
  private:
@@ -92,17 +94,20 @@ class xfibresOptions {
   nfibres(string("--nf,--nfibres"),1,
 	 string("Maximum nukmber of fibres to fit in each voxel (default 1)"),
 	 false,requires_argument),
+  modelnum(string("--model"),1,
+	 string("Which model to use. 1=mono-exponential (default and required for single shell). 2=continous exponential (for multi-shell experiments)"),
+	 false,requires_argument),
   fudge(string("--fudge"),1,
 	 string("ARD fudge factor"),
 	 false,requires_argument),
   njumps(string("--nj,--njumps"),5000,
 	 string("Num of jumps to be made by MCMC (default is 5000)"),
 	 false,requires_argument),
-  nburn(string("--bi,--burnin"),1,
-	string("Total num of jumps at start of MCMC to be discarded"),
+  nburn(string("--bi,--burnin"),0,
+	string("Total num of jumps at start of MCMC to be discarded (default is 0)"),
 	false,requires_argument),
   nburn_noard(string("--bn,--burnin_noard"),0,
-	string("num of burnin jumps before the ard is imposed"),
+	string("num of burnin jumps before the ard is imposed (default is 0)"),
 	false,requires_argument),
   sampleevery(string("--se,--sampleevery"),1,
 	string("Num of jumps for each sample (MCMC) (default is 1)"),
@@ -118,7 +123,9 @@ class xfibresOptions {
        false,no_argument),
   localinit(string("--nospat"),false,string("Initialise with tensor, not spatially"),
        false,no_argument),
-   options("xfibres v1.11", "xfibres -k <filename>\n xfibres --verbose\n")
+  nonlin(string("--nonlinear"),false,string("Initialise with nonlinear fitting"),
+       false,no_argument),
+   options("xfibres v1.11", "xfibres --help (for list of options)\n")
    {
      
     
@@ -132,6 +139,7 @@ class xfibresOptions {
        options.add(bvecsfile);
        options.add(bvalsfile);
        options.add(nfibres);
+       options.add(modelnum);
        options.add(fudge);
        options.add(njumps);
        options.add(nburn);
@@ -142,6 +150,7 @@ class xfibresOptions {
        options.add(no_ard);
        options.add(all_ard);
        options.add(localinit);
+       options.add(nonlin);
      }
      catch(X_OptionError& e) {
        options.usage();