diff --git a/xfibres.cc b/xfibres.cc
index 24539d939f866f562bcf0f8f932a63763bae6898..c68a14c583a54aae0c34565d55328452c951d67d 100644
--- a/xfibres.cc
+++ b/xfibres.cc
@@ -6,6 +6,10 @@
 
 /*  CCOPYRIGHT  */
 
+#ifndef EXPOSE_TREACHEROUS
+#define EXPOSE_TREACHEROUS
+#endif
+
 #include <iostream>
 #include <fstream>
 #include <iomanip>
@@ -760,6 +764,54 @@ public:
 };
 
 
+//Get the scale-free Qform matrix to rotate bvecs back to scanner's coordinate system 
+//After applying this matrix, make sure to sign flip the x coordinate of the resulted bvecs!
+//If you apply the inverse of the matrix, sign flip the x coordinate of the input bvecs
+void Return_Qform(const Matrix& qform_mat, Matrix& QMat, const float xdim, const float ydim, const float zdim){ 
+  Matrix QMat_tmp; DiagonalMatrix Scale(3);
+   
+  QMat_tmp=qform_mat.SubMatrix(1,3,1,3);
+  Scale(1)=xdim; Scale(2)=ydim; Scale(3)=zdim;
+  QMat_tmp=Scale.i()*QMat_tmp;
+  QMat=QMat_tmp;
+}
+
+
+
+//Correct bvals/bvecs accounting for Gradient Nonlinearities
+//ColumnVector grad_nonlin has 9 entries, corresponding to the 3 components of each of the x,y and z gradient deviation
+void correct_bvals_bvecs(const Matrix& bvals,const Matrix& bvecs, const ColumnVector& grad_nonlin, const Matrix& Qform, const Matrix& Qform_inv, Matrix& bvals_c, Matrix& bvecs_c){
+  bvals_c=bvals; bvecs_c=bvecs;
+  Matrix L(3,3);  //gradient coil tensor
+  float mag;
+  L(1,1)=grad_nonlin(1);  L(1,2)=grad_nonlin(4);  L(1,3)=grad_nonlin(7);
+  L(2,1)=grad_nonlin(2);  L(2,2)=grad_nonlin(5);  L(2,3)=grad_nonlin(8);
+  L(3,1)=grad_nonlin(3);  L(3,2)=grad_nonlin(6);  L(3,3)=grad_nonlin(9);
+
+  IdentityMatrix Id(3);
+  
+  for (int l=1; l<=bvals.Ncols(); l++){
+    if (bvals(1,l)>0){ //do not correct b0s
+      //Rotate bvecs to scanner's coordinate system
+      ColumnVector bvec_tmp(3);
+      bvec_tmp=Qform*bvecs.Column(l);
+      bvec_tmp(1)=-bvec_tmp(1); //Sign-flip X coordinate
+
+      //Correct for grad-nonlin in scanner's coordinate system
+      bvecs_c.Column(l)=(Id+L)*bvec_tmp;//bvecs.Column(l);
+      mag=sqrt(bvecs_c(1,l)*bvecs_c(1,l)+bvecs_c(2,l)*bvecs_c(2,l)+bvecs_c(3,l)*bvecs_c(3,l));
+      if (mag!=0)
+	bvecs_c.Column(l)=bvecs_c.Column(l)/mag;
+      bvals_c(1,l)=mag*mag*bvals(1,l);
+      bvec_tmp=bvecs_c.Column(l);
+
+      //Rotate corrected bvecs back to voxel coordinate system
+      bvec_tmp(1)=-bvec_tmp(1); //Sign-flip X coordinate
+      bvecs_c.Column(l)=Qform_inv*bvec_tmp;
+    }
+  }
+}
+
 
 
 ////////////////////////////////////////////
@@ -790,30 +842,52 @@ int main(int argc, char *argv[])
 	bvecs(3,i)=bvecs(3,i)/tmpsum;
       }  
     }
-    
+
     volume4D<float> data;
     read_volume4D(data,opts.datafile.value());
     read_volume(mask,opts.maskfile.value());
     datam=data.matrix(mask); 
     matrix2volkey=data.matrix2volkey(mask);
     vol2matrixkey=data.vol2matrixkey(mask);
- 
-    Matrix Amat;
-    ColumnVector alpha, beta;
+    Samples samples(vol2matrixkey,matrix2volkey,datam.Ncols(),datam.Nrows());
+
+    //Read Gradient Non_linearity Maps if provided
+    volume4D<float> grad; Matrix gradm, Qform, Qform_inv;
+    if (opts.grad_file.set()){
+      read_volume4D(grad,opts.grad_file.value());
+      gradm=grad.matrix(mask);
+      //Get the scale-free Qform matrix to rotate bvecs back to scanner's coordinate system 
+      Return_Qform(data.qform_mat(), Qform, data.xdim(), data.ydim(), data.zdim());
+      Qform_inv=Qform.i();
+    }
+
+    Matrix Amat; ColumnVector alpha, beta;
     Amat=form_Amat(bvecs,bvals);
     cart2sph(bvecs,alpha,beta);
-    Samples samples(vol2matrixkey,matrix2volkey,datam.Ncols(),datam.Nrows());
   
     if(opts.rician.value() && !opts.nonlin.value()) 
       cout<<"Rician noise model requested. Non-linear parameter initialization will be performed, overriding other initialization options!"<<endl;
-  
+
     for(int vox=1;vox<=datam.Ncols();vox++){
       cout <<vox<<"/"<<datam.Ncols()<<endl;
-      xfibresVoxelManager  vm(datam.Column(vox),alpha,beta,bvecs,bvals,samples,vox);
-      vm.initialise(Amat);
-      vm.runmcmc();
+      if (!opts.grad_file.set()){
+	xfibresVoxelManager  vm(datam.Column(vox),alpha,beta,bvecs,bvals,samples,vox);
+	vm.initialise(Amat);
+	vm.runmcmc();
+      }
+      else{ //Correct for each voxel the respective bvals/bvecs
+	Matrix Amat_c, bvals_c, bvecs_c;
+	ColumnVector alpha_c, beta_c;
+	
+	correct_bvals_bvecs(bvals,bvecs, gradm.Column(vox),Qform,Qform_inv,bvals_c,bvecs_c); //correct for gradient nonlinearities
+	Amat_c=form_Amat(bvecs_c,bvals_c);
+	cart2sph(bvecs_c,alpha_c,beta_c);
+	xfibresVoxelManager  vm(datam.Column(vox),alpha_c,beta_c,bvecs_c,bvals_c,samples,vox);
+	vm.initialise(Amat_c);
+	vm.runmcmc();
+      }
     }
-    
+
     samples.save(mask);
 
   }