diff --git a/xfibres_pred.cc b/xfibres_pred.cc
new file mode 100755
index 0000000000000000000000000000000000000000..e6df0b40f121fe8c62123d93374eafd209b6474b
--- /dev/null
+++ b/xfibres_pred.cc
@@ -0,0 +1,159 @@
+/*  Copyright (C) 2010 University of Oxford  */
+/* Stam Sotiropoulos    */
+/*  CCOPYRIGHT  */
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <string>
+#include <cmath>
+#include "newimage/newimageall.h"
+
+using namespace std;
+using namespace NEWIMAGE;
+using namespace NEWMAT;
+
+//Computes the model 1 predicted signal from the mode of the bedpostx samples
+//An f0 compartment could also be included in the model   
+int main ( int argc, char *argv[]){
+  if(argc<6 || argc>7){
+    cerr<<" "<<endl;
+    cerr<<"usage: xfibres_pred data_dir samples_dir fibres_num f0(0 or 1) [brain_mask] ouput"<<endl;
+    cerr<<" "<<endl;
+    exit(1);
+  }
+  
+  Matrix bvecs,bvals;   //Read Input 
+  volume<float> mask; int num_fibres;
+  volume<float> d,S0,f0, temp;
+  volume4D<float> temp4D;
+  vector< volume<float> > f;  
+  vector< volume4D<float> > dyads;  
+  
+  string dir_name=argv[1], temp_name;
+  temp_name=dir_name+"/bvals";
+  bvals=read_ascii_matrix(temp_name);
+  temp_name=dir_name+"/bvecs";
+  bvecs=read_ascii_matrix(temp_name);
+  temp_name=argv[3];
+  num_fibres=atoi(temp_name.c_str());
+  
+  if(bvecs.Nrows()>3) bvecs=bvecs.t();   //Make sure the bvecs entries are normalized unit vectors
+  if(bvals.Nrows()>1) bvals=bvals.t();
+  for(int i=1;i<=bvecs.Ncols();i++){
+    float tmpsum=sqrt(bvecs(1,i)*bvecs(1,i)+bvecs(2,i)*bvecs(2,i)+bvecs(3,i)*bvecs(3,i));
+    if(tmpsum!=0){
+      bvecs(1,i)=bvecs(1,i)/tmpsum;
+      bvecs(2,i)=bvecs(2,i)/tmpsum;
+      bvecs(3,i)=bvecs(3,i)/tmpsum;
+    }  
+  }
+  
+  dir_name=argv[2]; 
+  temp_name=dir_name+"/mean_dsamples";   //Read bedpostx results 
+  if (!fsl_imageexists(temp_name)){
+    cout<<"No mean_dsamples file exists!"<<endl;
+    exit(1); 
+  }
+  else read_volume(d,temp_name);
+ 
+  temp_name=dir_name+"/mean_S0samples";   //In case no S0samples is saved, use the mean b=0 from the data
+  if (!fsl_imageexists(temp_name)){
+    string dir_name2=argv[1];
+    temp_name=dir_name2+"/data"; 
+    if (!fsl_imageexists(temp_name)){
+      cerr<<"No mean_S0samples file exists or data file exists!"<<endl;
+      exit(1);
+    }
+    else{
+      cout<<"No mean_SOsamples found, getting the average of b=0's from data..."<<endl;
+      volume4D<float> data;
+      read_volume4D(data,temp_name);
+      S0.reinitialize(data.xsize(),data.ysize(),data.zsize());
+      S0=0;
+      int b0count=0;
+      for (int l=1; l<=bvals.Ncols(); l++)
+	if (bvals(1,l)==0){
+	  S0+=data[l-1];
+	  b0count++;
+	}
+      S0/=b0count;
+    }
+  }
+  else read_volume(S0,temp_name);
+  
+  for (int n=0; n<num_fibres; n++){   //Read dyads
+    temp_name=dir_name+"/dyads"+num2str(n+1);
+    if (!fsl_imageexists(temp_name)){
+      cerr<<"No dyads"<<n+1<<" file exists!"<<endl;
+      exit(1); }
+    else{
+      read_volume4D(temp4D,temp_name);
+      dyads.push_back(temp4D);
+    }
+    temp_name=dir_name+"/mean_f"+num2str(n+1)+"samples";
+    if (!fsl_imageexists(temp_name)){
+      cerr<<"No mean_f"<<n+1<<"samples file exists!"<<endl;
+      exit(1); }
+    else{
+      read_volume(temp,temp_name);
+      f.push_back(temp);
+    }
+  }
+  string argv4=argv[4];
+
+  if (argv4=="1"){                     //Read f0
+    temp_name=dir_name+"/mean_f0samples";    
+    if (!fsl_imageexists(temp_name)){
+      cout<<"No mean_f0samples file exists!"<<endl;
+      exit(1); 
+    }
+    else read_volume(f0,temp_name);   
+  }
+
+  if (argc==7)   //Read Brain Mask
+    read_volume(mask,argv[5]);
+  else{ 
+    mask.reinitialize(d.xsize(),d.ysize(),d.zsize());
+    mask=1;
+  }
+  
+  volume4D<float> output;
+  copybasicproperties(d,output);
+  output.reinitialize(d.xsize(),d.ysize(),d.zsize(),bvals.Ncols());
+  output=0;
+
+  for(int z=d.minz();z<=d.maxz();z++){   //Compute predicted signal for each voxel
+    for(int y=d.miny();y<=d.maxy();y++){
+      for(int x=d.minx();x<=d.maxx();x++){
+	if (mask(x,y,z)!=0){
+	  for (int l=0; l<bvals.Ncols(); l++){
+	    float sumf=0;
+	    for (int n=0; n<num_fibres; n++){
+	      sumf+=f[n](x,y,z);
+	      float angp=dyads[n](x,y,z,0)*bvecs(1,l+1)+dyads[n](x,y,z,1)*bvecs(2,l+1)+dyads[n](x,y,z,2)*bvecs(3,l+1);
+	      output(x,y,z,l)+=f[n](x,y,z)*exp(-bvals(1,l+1)*d(x,y,z)*angp*angp);
+	    }
+	    if (argv4=="1")
+	      output(x,y,z,l)+=(f0(x,y,z)+(1-sumf-f0(x,y,z))*exp(-bvals(1,l+1)*d(x,y,z)));
+	    else  
+	      output(x,y,z,l)+=(1-sumf)*exp(-bvals(1,l+1)*d(x,y,z));
+	    output(x,y,z,l)*=S0(x,y,z); 
+	  }
+	}
+      }
+    }
+    cout<<z+1<<" slices processed"<<endl;
+  }
+  save_volume4D(output,argv[argc-1]); 
+  return 0;
+}
+
+
+
+
+
+
+
+
+