Program: 11407
Project: 11407
Buggy source:
/** 
 * Create 30 initial clusters in each of the 3 categories (vol, dbl and surf). The pixels are first classified into 4 categories (vol, dbl, urf and mixed) based on its Freeman-Durder decomposition result. Then pixels in each category (not include mixed) are grouped into 30 clusters based on their power values.
 * @param srcBandList    the input bands
 * @param tileRectangles Array of rectangles for all source tiles of the image
 * @param op             the operator
 */
private void createInitialClusters(final double[][] fdd,final PolBandUtils.PolSourceBand srcBandList,final Rectangle[] tileRectangles,final PolarimetricClassificationOp op){
  final StatusProgressMonitor status=new StatusProgressMonitor(StatusProgressMonitor.TYPE.SUBTASK);
  status.beginTask("String_Node_Str",tileRectangles.length);
  final int[] counter=new int[4];
  final ThreadManager threadManager=new ThreadManager();
  final double[] pv=new double[srcHeight * srcWidth];
  final double[] pd=new double[srcHeight * srcWidth];
  final double[] ps=new double[srcHeight * srcWidth];
  try {
    for (    final Rectangle rectangle : tileRectangles) {
      op.checkIfCancelled();
      final Thread worker=new Thread(){
        final Tile[] sourceTiles=new Tile[srcBandList.srcBands.length];
        final ProductData[] dataBuffers=new ProductData[srcBandList.srcBands.length];
        final double[][] Cr=new double[3][3];
        final double[][] Ci=new double[3][3];
        @Override public void run(){
          final int x0=rectangle.x;
          final int y0=rectangle.y;
          final int w=rectangle.width;
          final int h=rectangle.height;
          final int xMax=x0 + w;
          final int yMax=y0 + h;
          final Rectangle sourceRectangle=getSourceRectangle(x0,y0,w,h);
          for (int i=0; i < sourceTiles.length; ++i) {
            sourceTiles[i]=op.getSourceTile(srcBandList.srcBands[i],sourceRectangle);
            dataBuffers[i]=sourceTiles[i].getDataBuffer();
          }
          for (int y=y0; y < yMax; ++y) {
            for (int x=x0; x < xMax; ++x) {
              PolOpUtils.getMeanCovarianceMatrix(x,y,halfWindowSizeX,halfWindowSizeY,sourceProductType,sourceTiles,dataBuffers,Cr,Ci);
              final FreemanDurden.FDD data=FreemanDurden.getFreemanDurdenDecomposition(Cr,Ci);
synchronized (counter) {
                if (!Double.isNaN(data.pv) && !Double.isNaN(data.pd) && !Double.isNaN(data.ps)) {
                  Categories cat=getCategory(data.pv,data.pd,data.ps,mixedCategoryThreshold);
                  if (cat == Categories.vol) {
                    mask[y][x]=-128;
                    fdd[y][x]=data.pv;
                    pv[counter[0]]=data.pv;
                    counter[0]+=1;
                  }
 else                   if (cat == Categories.dbl) {
                    mask[y][x]=-64;
                    fdd[y][x]=data.pd;
                    pd[counter[1]]=data.pd;
                    counter[1]+=1;
                  }
 else                   if (cat == Categories.suf) {
                    mask[y][x]=0;
                    fdd[y][x]=data.ps;
                    ps[counter[2]]=data.ps;
                    counter[2]+=1;
                  }
 else {
                    mask[y][x]=64;
                    fdd[y][x]=(data.pv + data.pd + data.ps) / 3.0;
                    counter[3]+=1;
                  }
                }
              }
            }
          }
        }
      }
;
      threadManager.add(worker);
      status.worked(1);
    }
    threadManager.finish();
  }
 catch (  Throwable e) {
    OperatorUtils.catchOperatorException(op.getId() + "String_Node_Str",e);
  }
 finally {
    status.done();
  }
  final int pvClusterSize=counter[0] / numInitialClusters;
  final int pdClusterSize=counter[1] / numInitialClusters;
  final int psClusterSize=counter[2] / numInitialClusters;
  if (pvClusterSize > 0) {
    Arrays.sort(pv,0,counter[0] - 1);
  }
  if (pdClusterSize > 0) {
    Arrays.sort(pd,0,counter[1] - 1);
  }
  if (psClusterSize > 0) {
    Arrays.sort(ps,0,counter[2] - 1);
  }
  final double[] pvThreshold=new double[numInitialClusters - 1];
  final double[] pdThreshold=new double[numInitialClusters - 1];
  final double[] psThreshold=new double[numInitialClusters - 1];
  for (int i=0; i < numInitialClusters - 1; i++) {
    pvThreshold[i]=pv[(i + 1) * pvClusterSize];
    pdThreshold[i]=pd[(i + 1) * pdClusterSize];
    psThreshold[i]=ps[(i + 1) * psClusterSize];
  }
  int clusterIdx=-1;
  for (int y=0; y < srcHeight; y++) {
    for (int x=0; x < srcWidth; x++) {
      if (mask[y][x] == -128) {
        clusterIdx=computePixelClusterIdx(fdd[y][x],pvThreshold,numInitialClusters);
        mask[y][x]+=clusterIdx;
      }
 else       if (mask[y][x] == -64) {
        clusterIdx=computePixelClusterIdx(fdd[y][x],pdThreshold,numInitialClusters);
        mask[y][x]+=clusterIdx;
      }
 else       if (mask[y][x] == 0) {
        clusterIdx=computePixelClusterIdx(fdd[y][x],psThreshold,numInitialClusters);
        mask[y][x]+=clusterIdx;
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * Create 30 initial clusters in each of the 3 categories (vol, dbl and surf). The pixels are first classified into 4 categories (vol, dbl, urf and mixed) based on its Freeman-Durden decomposition result. Then pixels in each category (not include mixed) are grouped into 30 clusters based on their power values.
 * @param srcBandList    the input bands
 * @param tileRectangles Array of rectangles for all source tiles of the image
 * @param op             the operator
 */
private void createInitialClusters(final double[][] fdd,final PolBandUtils.PolSourceBand srcBandList,final Rectangle[] tileRectangles,final PolarimetricClassificationOp op){
  final StatusProgressMonitor status=new StatusProgressMonitor(StatusProgressMonitor.TYPE.SUBTASK);
  status.beginTask("String_Node_Str",tileRectangles.length);
  final int[] counter=new int[4];
  final ThreadManager threadManager=new ThreadManager();
  final double[] pv=new double[srcHeight * srcWidth];
  final double[] pd=new double[srcHeight * srcWidth];
  final double[] ps=new double[srcHeight * srcWidth];
  try {
    for (    final Rectangle rectangle : tileRectangles) {
      op.checkIfCancelled();
      final Thread worker=new Thread(){
        final Tile[] sourceTiles=new Tile[srcBandList.srcBands.length];
        final ProductData[] dataBuffers=new ProductData[srcBandList.srcBands.length];
        final double[][] Cr=new double[3][3];
        final double[][] Ci=new double[3][3];
        @Override public void run(){
          final int x0=rectangle.x;
          final int y0=rectangle.y;
          final int w=rectangle.width;
          final int h=rectangle.height;
          final int xMax=x0 + w;
          final int yMax=y0 + h;
          final Rectangle sourceRectangle=getSourceRectangle(x0,y0,w,h);
          for (int i=0; i < sourceTiles.length; ++i) {
            sourceTiles[i]=op.getSourceTile(srcBandList.srcBands[i],sourceRectangle);
            dataBuffers[i]=sourceTiles[i].getDataBuffer();
          }
          for (int y=y0; y < yMax; ++y) {
            for (int x=x0; x < xMax; ++x) {
              PolOpUtils.getMeanCovarianceMatrix(x,y,halfWindowSizeX,halfWindowSizeY,sourceProductType,sourceTiles,dataBuffers,Cr,Ci);
              final FreemanDurden.FDD data=FreemanDurden.getFreemanDurdenDecomposition(Cr,Ci);
synchronized (counter) {
                if (!Double.isNaN(data.pv) && !Double.isNaN(data.pd) && !Double.isNaN(data.ps)) {
                  category[y][x]=getCategory(data.pv,data.pd,data.ps,mixedCategoryThreshold);
                  if (category[y][x] == Categories.vol) {
                    fdd[y][x]=data.pv;
                    pv[counter[0]]=data.pv;
                    counter[0]+=1;
                  }
 else                   if (category[y][x] == Categories.dbl) {
                    fdd[y][x]=data.pd;
                    pd[counter[1]]=data.pd;
                    counter[1]+=1;
                  }
 else                   if (category[y][x] == Categories.suf) {
                    fdd[y][x]=data.ps;
                    ps[counter[2]]=data.ps;
                    counter[2]+=1;
                  }
 else {
                    fdd[y][x]=(data.pv + data.pd + data.ps) / 3.0;
                    counter[3]+=1;
                  }
                }
              }
            }
          }
        }
      }
;
      threadManager.add(worker);
      status.worked(1);
    }
    threadManager.finish();
  }
 catch (  Throwable e) {
    OperatorUtils.catchOperatorException(op.getId() + "String_Node_Str",e);
  }
 finally {
    status.done();
  }
  final int pvClusterSize=counter[0] / numInitialClusters;
  final int pdClusterSize=counter[1] / numInitialClusters;
  final int psClusterSize=counter[2] / numInitialClusters;
  if (pvClusterSize > 0) {
    Arrays.sort(pv,0,counter[0] - 1);
  }
  if (pdClusterSize > 0) {
    Arrays.sort(pd,0,counter[1] - 1);
  }
  if (psClusterSize > 0) {
    Arrays.sort(ps,0,counter[2] - 1);
  }
  final double[] pvThreshold=new double[numInitialClusters - 1];
  final double[] pdThreshold=new double[numInitialClusters - 1];
  final double[] psThreshold=new double[numInitialClusters - 1];
  for (int i=0; i < numInitialClusters - 1; i++) {
    pvThreshold[i]=pv[(i + 1) * pvClusterSize];
    pdThreshold[i]=pd[(i + 1) * pdClusterSize];
    psThreshold[i]=ps[(i + 1) * psClusterSize];
  }
  for (int y=0; y < srcHeight; y++) {
    for (int x=0; x < srcWidth; x++) {
      if (category[y][x] == Categories.vol) {
        cluster[y][x]=computePixelClusterIdx(fdd[y][x],pvThreshold,numInitialClusters);
      }
 else       if (category[y][x] == Categories.dbl) {
        cluster[y][x]=computePixelClusterIdx(fdd[y][x],pdThreshold,numInitialClusters);
      }
 else       if (category[y][x] == Categories.suf) {
        cluster[y][x]=computePixelClusterIdx(fdd[y][x],psThreshold,numInitialClusters);
      }
    }
  }
}