diff --git a/src/finddd_descriptor.cpp b/src/finddd_descriptor.cpp
index 6a9187d65c9833ea00dc2e2ed35379e047322471..dbed46ac86049c0df3e0f15fa418d43a7799fd08 100755
--- a/src/finddd_descriptor.cpp
+++ b/src/finddd_descriptor.cpp
@@ -3,17 +3,16 @@
 
 #define PI 3.1415926535
 
-//helper fun
-inline 
-std::vector<float> get_bin_float_empty(int nb_bins)
+// Get empty normal voting histogram 
+inline std::vector<float> get_bin_float_empty(int nb_bins)
 {
   std::vector<float> val_bins;
   val_bins.resize(nb_bins,0);
   return val_bins;
 }
 
-inline 
-std::vector<float> get_bin_float_interp_xyz(float x, float y, float z, std::vector<float> &bin_centers_x, std::vector<float> &bin_centers_y, std::vector<float> &bin_centers_z, float radius_inf)
+// Get normal voting histogram *with* interpolation
+inline std::vector<float> get_bin_float_interp_xyz(float x, float y, float z, std::vector<float> &bin_centers_x, std::vector<float> &bin_centers_y, std::vector<float> &bin_centers_z, float radius_inf)
 {
   int nb_bins=bin_centers_x.size();
   std::vector<float> val_bins;
@@ -25,14 +24,15 @@ std::vector<float> get_bin_float_interp_xyz(float x, float y, float z, std::vect
     float dy=(y-bin_centers_y[ith]);
     float dz=(z-bin_centers_z[ith]);
     float dist = sqrt(dx*dx+dy*dy+dz*dz);
+    //weight based on one unit of histogram distance
     float vote = std::max(1-dist/radius_inf, (float)0.0);
     val_bins[ith] = vote;
   }
   return val_bins;
 }
 
-inline 
-std::vector<float> get_bin_float_xyz(float x, float y, float z, std::vector<float> &bin_centers_x, std::vector<float> &bin_centers_y, std::vector<float> &bin_centers_z)
+// Get normal voting histogram *without* interpolation
+inline std::vector<float> get_bin_float_xyz(float x, float y, float z, std::vector<float> &bin_centers_x, std::vector<float> &bin_centers_y, std::vector<float> &bin_centers_z)
 {
   int nb_bins=bin_centers_x.size();
   std::vector<float> val_bins;
@@ -53,14 +53,16 @@ std::vector<float> get_bin_float_xyz(float x, float y, float z, std::vector<floa
       dist_best_match = dist;
     }
   }
+  //vote weight = 1
   val_bins[best_match] = 1;
 
   return val_bins;
 }
 
+// Compute pointcloud normals fast using integral images
 void compute_normals_integral(pcl::PointCloud<pcl::Normal> &pcl_normals, pcl::PointCloud<pcl::PointXYZ>& cloud)
 {
-  //compute normal
+  //compute normals
   pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimator;
   normal_estimator.setNormalEstimationMethod (normal_estimator.AVERAGE_3D_GRADIENT);
   normal_estimator.setMaxDepthChangeFactor(0.02f);
@@ -70,6 +72,7 @@ void compute_normals_integral(pcl::PointCloud<pcl::Normal> &pcl_normals, pcl::Po
   //For debug: pcl::io::savePCDFileASCII("/tmp/cloud_pointnormals.pcd", pcl_normals);
 }
 
+// Compute pointcloud normals without using integral images
 void compute_normals(pcl::PointCloud<pcl::Normal> &pcl_normals, pcl::PointCloud<pcl::PointXYZ>& cloud)
 {
   //compute normal
@@ -81,6 +84,7 @@ void compute_normals(pcl::PointCloud<pcl::Normal> &pcl_normals, pcl::PointCloud<
   normal_estimator.compute (pcl_normals);
 }
 
+/***************************************************************************************/
 // Simple Integral Images class
 class IIf
 {
@@ -147,6 +151,7 @@ public:
     }
   }
 
+  //get sum of rectangular sub-region
   std::vector<float> get_sub_rect(unsigned int tu, unsigned int tv, unsigned int bu, unsigned int bv)
   {
     std::vector<float> ret(this->bins_);
@@ -157,14 +162,12 @@ public:
 	ret[b]=0;
       }
     }
-
     return ret;
   }
 };
+/***************************************************************************************/
 
-///////////////////////////////////////////////////////////////////////////////////////////
-
-
+// Constructor
 FindddAlgorithm::FindddAlgorithm(void)
 {
   //default values
@@ -189,6 +192,7 @@ FindddAlgorithm::~FindddAlgorithm(void)
 {
 }
 
+// Construct with config
 FindddAlgorithm::FindddAlgorithm(FindddConfig new_cfg)
 {
   this->set_num_side_spatial_bins(new_cfg.num_spatial_bins);
@@ -203,8 +207,7 @@ FindddAlgorithm::FindddAlgorithm(FindddConfig new_cfg)
   this->update_pca_matrix(new_cfg.pca_file);
 }
 
-// FindddAlgorithm Public API
-
+// Main function to compute FINDDD descriptors
 void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCloud<pcl::PointXYZ>& cloud, DescriptorSet &descriptor_set)
 {
 
@@ -214,11 +217,11 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
     std::cout<<"II with interpolation method."<<std::endl;
     std::cout<<"PointCloud received"<<std::endl;
   }
-  //compute normal
+  //compute normals
   pcl::PointCloud<pcl::Normal> pcl_normals; 
   compute_normals_integral(pcl_normals, cloud);
 
-  //compute descriptors
+  //set up object to hold descriptors
   descriptor_set.descriptors.clear();
   descriptor_set.len    = this->desc_num_total_bins_;
   descriptor_set.width  = pcl_normals.width;
@@ -226,45 +229,28 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
   descriptor_set.num_orient_bins = this->orient_bin_centers_x_.size();
   descriptor_set.num_spa_bins = this->desc_num_side_spatial_bins_;
 
-  //Compile all normal orientations and add them to the II
+  //Init II
   std::vector<std::vector<float> > binned(cloud.width*cloud.height);
 
-  if(this->use_soft_voting_)
-  {
-    for(uint v=0;v<cloud.height;v++)
-    {
-      for(uint u=0;u<cloud.width;u++)
-      {
+  //Compile all normal orientations and add them to the II
+  //soft-voting vs not-soft-voting checked here for efficiency to avoid if in a loop.
+  //(sorry for the ugly code).
+  if(this->use_soft_voting_) {
+    for(uint v=0;v<cloud.height;v++) {
+      for(uint u=0;u<cloud.width;u++)  {
 	if(isnan(pcl_normals(u,v).normal_x) || isnan(pcl_normals(u,v).normal_y) || isnan(pcl_normals(u,v).normal_z))
 	  binned[u+cloud.width*v]=get_bin_float_empty(this->orient_bin_centers_x_.size()); // empty vector
-	else
-	{
-	  binned[u+cloud.width*v] = 
-	    get_bin_float_interp_xyz(
-	      pcl_normals(u,v).normal_x, pcl_normals(u,v).normal_y, pcl_normals(u,v).normal_z, 
-	      this->orient_bin_centers_x_, this->orient_bin_centers_y_, this->orient_bin_centers_z_,
-	      this->radius_inf_);
-	}
-      }
-    }
-  }
-  else
-  {
-    for(uint v=0;v<cloud.height;v++)
-    {
-      for(uint u=0;u<cloud.width;u++)
-      {
+	else {
+	  binned[u+cloud.width*v] = get_bin_float_interp_xyz(pcl_normals(u,v).normal_x, pcl_normals(u,v).normal_y, pcl_normals(u,v).normal_z, this->orient_bin_centers_x_, this->orient_bin_centers_y_, this->orient_bin_centers_z_, this->radius_inf_);
+	} } } } 
+  else {
+    for(uint v=0;v<cloud.height;v++) {
+      for(uint u=0;u<cloud.width;u++) {
 	if(isnan(pcl_normals(u,v).normal_x) || isnan(pcl_normals(u,v).normal_y) || isnan(pcl_normals(u,v).normal_z))
-	  binned[u+cloud.width*v]=get_bin_float_empty(this->orient_bin_centers_x_.size()); // empty vector
-	else
-	{
-	  binned[u+cloud.width*v] = 
-	    get_bin_float_xyz(
-	      pcl_normals(u,v).normal_x, pcl_normals(u,v).normal_y, pcl_normals(u,v).normal_z, 
-	      this->orient_bin_centers_x_, this->orient_bin_centers_y_, this->orient_bin_centers_z_);
-	}
-      }
-    }
+	  binned[u+cloud.width*v] = get_bin_float_empty(this->orient_bin_centers_x_.size()); // empty vector
+	else {
+	  binned[u+cloud.width*v] = get_bin_float_xyz(pcl_normals(u,v).normal_x, pcl_normals(u,v).normal_y, pcl_normals(u,v).normal_z, this->orient_bin_centers_x_, this->orient_bin_centers_y_, this->orient_bin_centers_z_);
+	} } }
   }
 
   //Build II
@@ -276,14 +262,14 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
   unsigned int spatial_bin_size    = (2*this->desc_patch_radius_+1)/this->desc_num_side_spatial_bins_;
   unsigned int spatial_bin_orients = this->desc_num_orient_bins_;
 
-  //If no positions given, generate standard positions
+  //If no positions file given, generate standard positions
   if(this->desc_compute_positionsX_.size()==0)
   {
     if(this->verbose_level_>=2)
       std::cout<<"Generating default positions"<<std::endl;
-    for(unsigned int v=this->desc_patch_radius_;v<cloud.height-this->desc_patch_radius_-1;v+=this->sample_each_)
+    for(unsigned int v = this->desc_patch_radius_;v<cloud.height-this->desc_patch_radius_-1;v+=this->sample_each_)
     {
-      for(unsigned int u=this->desc_patch_radius_;u<cloud.width-this->desc_patch_radius_-1;u+=this->sample_each_)
+      for(unsigned int u = this->desc_patch_radius_;u<cloud.width-this->desc_patch_radius_-1;u+=this->sample_each_)
       {      
 	this->desc_compute_positionsX_.push_back(u);
 	this->desc_compute_positionsY_.push_back(v);
@@ -297,6 +283,7 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
     unsigned int u=this->desc_compute_positionsX_[i_pos];
     unsigned int v=this->desc_compute_positionsY_[i_pos];
 
+    //skip invalid margin positions
     if( v<this->desc_patch_radius_ || 
 	u<this->desc_patch_radius_ || 
         u>=cloud.width-this->desc_patch_radius_-1 || 
@@ -314,7 +301,7 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
     desc.v=v;
     
     desc.descriptor.resize(this->desc_num_total_bins_,0);
-    float total_votes=0; // for normalization
+    //float total_votes=0; // for normalization
     
     unsigned int absolute_top  = v-this->desc_patch_radius_;
     //int absolute_bottom = v+this->desc_patch_radius_;
@@ -336,27 +323,33 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
 	  unsigned int offset_full_rows = l*this->desc_num_side_spatial_bins_*spatial_bin_orients;
 	  unsigned int offset_this_row  = k*spatial_bin_orients;
 	  desc.descriptor[offset_full_rows + offset_this_row + i]=tmp[i];
-	  total_votes+=tmp[i];
+	  //total_votes+=tmp[i];
 	}
       }
     }
  
+    //normalize desc if required
     if(this->normalize_desc_ != 0)
     {
       float sum=0;
       for(int iii=0; iii<desc.descriptor.size(); iii++)
       {
-	if((this->normalize_desc_==1) || (this->normalize_desc_==3)) sum+=desc.descriptor[iii];
-	else if(this->normalize_desc_==2) sum+=desc.descriptor[iii]*desc.descriptor[iii];
+	if((this->normalize_desc_==1) || (this->normalize_desc_==3)) 
+	  sum += desc.descriptor[iii];
+	else if(this->normalize_desc_==2) 
+	  sum += desc.descriptor[iii]*desc.descriptor[iii];
       }
-      if(this->normalize_desc_==2) sum=sqrt(sum);
+      if(this->normalize_desc_==2) 
+	sum=sqrt(sum);
       for(int iii=0; iii<desc.descriptor.size(); iii++)
       {
-	if((this->normalize_desc_==1) || (this->normalize_desc_==2)) desc.descriptor[iii] /= sum;
-	else if(this->normalize_desc_==3) desc.descriptor[iii] = sqrt(desc.descriptor[iii])/sqrt(sum);
+	if((this->normalize_desc_==1) || (this->normalize_desc_==2)) 
+	  desc.descriptor[iii] /= sum;
+	else if(this->normalize_desc_==3) 
+	  desc.descriptor[iii] = sqrt(desc.descriptor[iii])/sqrt(sum);
       }
     }
-    //project w\ PCA if necessary
+    //project w\ PCA if required
     if(this->pca_file_!="")
     {
       desc.descriptor = this->project_vector_pca(desc.descriptor, this->pca_matrix_, this->pca_mean_);
@@ -370,14 +363,16 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
     std::cout<<"Computed "<<descriptor_set.num<<" descriptors, in "<<(clock()-start)/(float)CLOCKS_PER_SEC<< "s"<<std::endl;
 }
 
+//method parameters help
 void about()
 {
-  std::cout<<"Usage:\n  finddd -pcd <file_path> -centroids_file <centroids_path> -descfile <output_descfile_path> [-use_soft_voting <bool>] [-sample_each <step>] [-normalize_desc] [-desc_patch_radius <radius>] [-num_spatial_bins <num_bins_per_side>] [-positions_file <positions_file_path>] [-keep_nan] [-pca_file <file_path>]"<<std::endl;
+  std::cout<<"Usage:\n  finddd_descriptor -pcd <file_path> -centroids_file <centroids_path> -descfile <output_descfile_path> [-use_soft_voting <bool>] [-sample_each <step>] [-normalize_desc] [-desc_patch_radius <radius>] [-num_spatial_bins <num_bins_per_side>] [-positions_file <positions_file_path>] [-keep_nan] [-pca_file <file_path>]"<<std::endl;
   std::cout<<"Parameters:\n  -pcd <filename>              Input pcd file path.\n  -use_soft_voting <bool>      Disable soft-voting.\n  -sample_each <num_pix>       Density of descriptor sampling.\n  -normalize_desc <norm>       0=none 1=L1 2=L2 3=sqrt+L2.\n  -desc_patch_radius <num_pix> Radius of the local patch.\n  -num_spatial_bins <num_bins> Number of local bins per side (sqrt of total bins).\n  -centroids_file <filename>   Input centroid file path.\n  -positions_file <filename>   Input locations file path.\n  -descfile <filename>         Output descriptor file path.\n  -pca_file <filename>         PCA matrix filename\n";
 }
 
 bool parse_args(int argc, char* argv[], FindddConfig& new_conf)
 {
+  bool valid_args=true;
   for(int i=1; i<argc; i++)
   {
     std::string arg(argv[i]);
@@ -408,33 +403,55 @@ bool parse_args(int argc, char* argv[], FindddConfig& new_conf)
       return false;
     }
   }
-  if (new_conf.centroids_file=="" || new_conf.geofvecs_file=="" || new_conf.pcd_file=="")
+  if(new_conf.pcd_file=="")
   {
-    std::cerr<<"Incorrect parameters."<<std::endl;
-    about();
-    return false;
+    std::cerr<<"Missing input pcd file."<<std::endl;
+    valid_args=false;
+  }
+  if (new_conf.centroids_file=="")
+  {
+    std::cerr<<"Missing centroids file."<<std::endl;
+    valid_args=false;
+  }
+  if(new_conf.geofvecs_file=="")
+  {
+    std::cerr<<"Missing output descriptorsfile."<<std::endl;
+    valid_args=false;    
   }
-  return true;
+  if(valid_args==true)
+    return true;
+  else
+    return false;
 }
 
+//save descs in fvec format (see the yael library for more details. https://gforge.inria.fr/projects/yael/)
 void write_point_fvec(FILE *pf, const Descriptor &point)
 {
   int dim=point.descriptor.size();
   float f;
   dim+=2; //adding x,y coord
-  if (fwrite (&(dim), sizeof (int), 1, pf) != 1){
-    fprintf(stderr, "Error writting to file\n"); exit(-1);}
+  if (fwrite (&(dim), sizeof (int), 1, pf) != 1)
+  {
+    fprintf(stderr, "Error writting to file\n"); exit(-1);
+  }
   f=point.u;
-  if (fwrite (&f, sizeof (float), 1, pf) != 1){
-    fprintf(stderr, "Error writting to file\n"); exit(-1);}
+  if (fwrite (&f, sizeof (float), 1, pf) != 1)
+  {
+    fprintf(stderr, "Error writting to file\n"); exit(-1);
+  }
   f=point.v;
-  if (fwrite (&f, sizeof (float), 1, pf) != 1){
-    fprintf(stderr, "Error writting to file\n"); exit(-1);}
+  if (fwrite (&f, sizeof (float), 1, pf) != 1)
+  {
+    fprintf(stderr, "Error writting to file\n"); exit(-1);
+  }
   for(unsigned int j=0;j<dim-2;j++)
-    if (fwrite (&(point.descriptor[j]), sizeof (float), 1, pf) != 1){
-      fprintf(stderr, "Error writting to file\n"); exit(-1);}
+    if (fwrite (&(point.descriptor[j]), sizeof (float), 1, pf) != 1)
+    {
+      fprintf(stderr, "Error writting to file\n"); exit(-1);
+    }
 }
 
+//save valid descriptors to disk
 void write_feats(std::string &output_file, DescriptorSet &descriptor_set, FindddConfig &conf)
 {
   FILE* pf=fopen(output_file.c_str(),"wb");
diff --git a/src/finddd_descriptor.hpp b/src/finddd_descriptor.hpp
index 47aa5bfb07636c94a947fad8897164b8a0e76881..372b88994426635be3273c31d0c280bac17aa546 100644
--- a/src/finddd_descriptor.hpp
+++ b/src/finddd_descriptor.hpp
@@ -16,7 +16,7 @@
 #include <iostream>
 #include <fstream>
 
-
+// util
 template <class T>
 inline std::string to_string (const T& t)
 {
@@ -25,6 +25,9 @@ inline std::string to_string (const T& t)
   return ss.str();
 }
 
+/** \brief Class for 3D point
+ *  Very simple class to hold 3D point position information.
+ */
 class P3D
 {
 public:
@@ -37,6 +40,10 @@ public:
   
 };
 
+/** \brief Class to hold one FINDDD descriptor
+ *  This class holds each one of the FINDDD descriptors in a set. 
+ *  Descriptor data is stored in a vector<float>.
+ */
 class Descriptor
 {
 public:
@@ -47,7 +54,11 @@ public:
   std::vector<float> descriptor;
 };
 
-
+/** \brief Class to hold FINDDD computation parameters
+ *  This class holds a set (vector) of FINDDD descriptors as well as 
+ *  parameters of the descriptors and the set and sizes of the original
+ *  range image.
+ */
 class DescriptorSet
 {
 public:
@@ -71,6 +82,10 @@ public:
 };
 
 
+/** \brief Class to hold FINDDD computation parameters
+ *  This class holds all parameters related to FINDDD computation, and is 
+ *  used to update the FindddAlgorithm class with user-defined parameters.
+ */
 class FindddConfig
 {
 public:
@@ -104,6 +119,10 @@ public:
   }
 };
 
+/** \brief Main class to compute FINDDD descriptors
+ * This class contains all the methods necessary to compute FINDDD
+ * descriptors for a range image.
+ */
 class FindddAlgorithm
 {
 protected: