docs: void computeCellHistogram(int pixelX0 , int pixelY0 ,
  							  int cellX , int cellY ) {
  
  		float angleBinSize = GrlConstants.F_PI/orientationBins;
  
  		for (int i = 0; i < pixelsPerCell; i++) {
  			int indexPixel = (pixelY0+i)*derivX.stride + pixelX0;
  			int indexBlock = (cellY*pixelsPerCell+i)*pixelsPerCell*cellsPerBlockX + cellX*pixelsPerCell;
  
  			// Use center point of this cell to compute interpolation weights - bilinear interpolation
  			double spatialWeightY0,spatialWeightY1,spatialWeightY2;
  
  			if( i <= pixelsPerCell/2 ) {
  				spatialWeightY1 = (i + pixelsPerCell/2.0)/pixelsPerCell;
  				spatialWeightY0 = 1.0 - spatialWeightY1;
  				spatialWeightY2 = 0;
  			} else {
  				spatialWeightY0 = 0;
  				spatialWeightY2 = (i - pixelsPerCell/2.0)/pixelsPerCell;
  				spatialWeightY1 = 1.0 - spatialWeightY2;
  			}
  
  			for (int j = 0; j < pixelsPerCell; j++, indexPixel++, indexBlock++ ) {
  				// Use center point of this cell to compute interpolation weights - bilinear interpolation
  				double spatialWeightX0,spatialWeightX1,spatialWeightX2;
  
  				if( j <= pixelsPerCell/2 ) {
  					spatialWeightX1 = (j + pixelsPerCell/2.0)/pixelsPerCell;
  					spatialWeightX0 = 1.0 - spatialWeightX1;
  					spatialWeightX2 = 0;
  				} else {
  					spatialWeightX0 = 0;
  					spatialWeightX2 = (j - pixelsPerCell/2.0)/pixelsPerCell;
  					spatialWeightX1 = 1.0 - spatialWeightX2;
  				}
  
  				// angle from 0 to pi radians
  				float angle = this.orientation.data[indexPixel];
  
  				// gradient magnitude
  				double magnitude = this.magnitude.data[indexPixel];
  
  				// Apply spatial weighting to magnitude
  				magnitude *= this.weights[ indexBlock ];
  
  				// Add the weighted gradient using linear interpolation to angle bins
  				float findex0 = angle/angleBinSize;
  				int index0 = (int)findex0;
  				double oriWeight1 = findex0-index0;
  				index0 %= orientationBins;
  				int index1 = (index0+1)%orientationBins;
  
  
  				// spatial bilinear interpolation + orientation linear interpolation
  				// + gaussian weighting (previously applied)
  				addToHistogram( cellX-1, cellY-1 , index0, (1.0-oriWeight1)*magnitude*spatialWeightX0*spatialWeightY0);
  				addToHistogram( cellX-1, cellY-1 , index1, oriWeight1*magnitude*spatialWeightX0*spatialWeightY0);
  
  				addToHistogram( cellX, cellY-1 , index0, (1.0-oriWeight1)*magnitude*spatialWeightX1*spatialWeightY0);
  				addToHistogram( cellX, cellY-1 , index1, oriWeight1*magnitude*spatialWeightX1*spatialWeightY0);
  
  				addToHistogram( cellX+1, cellY-1 , index0, (1.0-oriWeight1)*magnitude*spatialWeightX2*spatialWeightY0);
  				addToHistogram( cellX+1, cellY-1 , index1, oriWeight1*magnitude*spatialWeightX2*spatialWeightY0);
  
  				addToHistogram( cellX-1, cellY , index0, (1.0-oriWeight1)*magnitude*spatialWeightX0*spatialWeightY1);
  				addToHistogram( cellX-1, cellY , index1, oriWeight1*magnitude*spatialWeightX0*spatialWeightY1);
  
  				addToHistogram( cellX, cellY , index0, (1.0-oriWeight1)*magnitude*spatialWeightX1*spatialWeightY1);
  				addToHistogram( cellX, cellY , index1, oriWeight1*magnitude*spatialWeightX1*spatialWeightY1);
  
  				addToHistogram( cellX+1, cellY , index0, (1.0-oriWeight1)*magnitude*spatialWeightX2*spatialWeightY1);
  				addToHistogram( cellX+1, cellY , index1, oriWeight1*magnitude*spatialWeightX2*spatialWeightY1);
  
  				addToHistogram( cellX-1, cellY+1 , index0, (1.0-oriWeight1)*magnitude*spatialWeightX0*spatialWeightY2);
  				addToHistogram( cellX-1, cellY+1 , index1, oriWeight1*magnitude*spatialWeightX0*spatialWeightY2);
  
  				addToHistogram( cellX, cellY+1 , index0, (1.0-oriWeight1)*magnitude*spatialWeightX1*spatialWeightY2);
  				addToHistogram( cellX, cellY+1 , index1, oriWeight1*magnitude*spatialWeightX1*spatialWeightY2);
  
  				addToHistogram( cellX+1, cellY+1 , index0, (1.0-oriWeight1)*magnitude*spatialWeightX2*spatialWeightY2);
  				addToHistogram( cellX+1, cellY+1 , index1, oriWeight1*magnitude*spatialWeightX2*spatialWeightY2);
  
  			}
  		}
  	}