Program: 11404
Project: 11404
Buggy source:
/** 
 * Compute the centers of the 90 clusters in the 3 categories.
 * @param srcBandList    the input bands
 * @param tileRectangles Array of rectangles for all source tiles of the image
 * @param op             the operator
 */
private void getClusterCenters(final java.util.List<ClusterInfo> pvCenterList,final java.util.List<ClusterInfo> pdCenterList,final java.util.List<ClusterInfo> psCenterList,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 ThreadManager threadManager=new ThreadManager();
  final double[][][] pvSumRe=new double[numInitialClusters][3][3];
  final double[][][] pvSumIm=new double[numInitialClusters][3][3];
  final double[][][] pdSumRe=new double[numInitialClusters][3][3];
  final double[][][] pdSumIm=new double[numInitialClusters][3][3];
  final double[][][] psSumRe=new double[numInitialClusters][3][3];
  final double[][][] psSumIm=new double[numInitialClusters][3][3];
  final int[][] clusterCounter=new int[3][numInitialClusters];
  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[][] Sr=new double[2][2];
        final double[][] Si=new double[2][2];
        final double[][] Tr=new double[3][3];
        final double[][] Ti=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;
          for (int i=0; i < sourceTiles.length; ++i) {
            sourceTiles[i]=op.getSourceTile(srcBandList.srcBands[i],rectangle);
            dataBuffers[i]=sourceTiles[i].getDataBuffer();
          }
          final TileIndex srcIndex=new TileIndex(sourceTiles[0]);
          for (int y=y0; y < yMax; ++y) {
            srcIndex.calculateStride(y);
            for (int x=x0; x < xMax; ++x) {
              PolOpUtils.getCoherencyMatrixT3(srcIndex.getIndex(x),sourceProductType,dataBuffers,Tr,Ti);
synchronized (clusterCounter) {
                int clusterIdx;
                if (mask[y][x] < -64) {
                  clusterIdx=mask[y][x] + 128;
                  computeSummationOfT3(clusterIdx + 1,Tr,Ti,pvSumRe,pvSumIm);
                  clusterCounter[0][clusterIdx]++;
                }
 else                 if (mask[y][x] < 0) {
                  clusterIdx=mask[y][x] + 64;
                  computeSummationOfT3(clusterIdx + 1,Tr,Ti,pdSumRe,pdSumIm);
                  clusterCounter[1][clusterIdx]++;
                }
 else                 if (mask[y][x] < 64) {
                  clusterIdx=mask[y][x];
                  computeSummationOfT3(clusterIdx + 1,Tr,Ti,psSumRe,psSumIm);
                  clusterCounter[2][clusterIdx]++;
                }
              }
            }
          }
        }
      }
;
      threadManager.add(worker);
      status.worked(1);
    }
    threadManager.finish();
  }
 catch (  Throwable e) {
    OperatorUtils.catchOperatorException(op.getId() + "String_Node_Str",e);
  }
 finally {
    status.done();
  }
  for (int c=0; c < numInitialClusters; c++) {
    double[][] centerRe=new double[3][3];
    double[][] centerIm=new double[3][3];
    if (clusterCounter[0][c] > 0) {
      for (int i=0; i < 3; i++) {
        for (int j=0; j < 3; j++) {
          centerRe[i][j]=pvSumRe[c][i][j] / clusterCounter[0][c];
          centerIm[i][j]=pvSumIm[c][i][j] / clusterCounter[0][c];
        }
      }
      ClusterInfo clusterCenter=new ClusterInfo();
      clusterCenter.setClusterCenter(c,centerRe,centerIm,clusterCounter[0][c]);
      pvCenterList.add(clusterCenter);
    }
    if (clusterCounter[1][c] > 0) {
      for (int i=0; i < 3; i++) {
        for (int j=0; j < 3; j++) {
          centerRe[i][j]=pdSumRe[c][i][j] / clusterCounter[1][c];
          centerIm[i][j]=pdSumIm[c][i][j] / clusterCounter[1][c];
        }
      }
      ClusterInfo clusterCenter=new ClusterInfo();
      clusterCenter.setClusterCenter(c,centerRe,centerIm,clusterCounter[1][c]);
      pdCenterList.add(clusterCenter);
    }
    if (clusterCounter[2][c] > 0) {
      for (int i=0; i < 3; i++) {
        for (int j=0; j < 3; j++) {
          centerRe[i][j]=psSumRe[c][i][j] / clusterCounter[2][c];
          centerIm[i][j]=psSumIm[c][i][j] / clusterCounter[2][c];
        }
      }
      ClusterInfo clusterCenter=new ClusterInfo();
      clusterCenter.setClusterCenter(c,centerRe,centerIm,clusterCounter[2][c]);
      psCenterList.add(clusterCenter);
    }
  }
}

Fixed version (ground truth):
/** 
 * Compute the centers of the 90 clusters in the 3 categories.
 * @param srcBandList    the input bands
 * @param tileRectangles Array of rectangles for all source tiles of the image
 * @param op             the operator
 */
private void getClusterCenters(final java.util.List<ClusterInfo> pvCenterList,final java.util.List<ClusterInfo> pdCenterList,final java.util.List<ClusterInfo> psCenterList,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 ThreadManager threadManager=new ThreadManager();
  final double[][][] pvSumRe=new double[numInitialClusters][3][3];
  final double[][][] pvSumIm=new double[numInitialClusters][3][3];
  final double[][][] pdSumRe=new double[numInitialClusters][3][3];
  final double[][][] pdSumIm=new double[numInitialClusters][3][3];
  final double[][][] psSumRe=new double[numInitialClusters][3][3];
  final double[][][] psSumIm=new double[numInitialClusters][3][3];
  final int[][] clusterCounter=new int[3][numInitialClusters];
  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[][] Tr=new double[3][3];
        final double[][] Ti=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;
          for (int i=0; i < sourceTiles.length; ++i) {
            sourceTiles[i]=op.getSourceTile(srcBandList.srcBands[i],rectangle);
            dataBuffers[i]=sourceTiles[i].getDataBuffer();
          }
          final TileIndex srcIndex=new TileIndex(sourceTiles[0]);
          for (int y=y0; y < yMax; ++y) {
            srcIndex.calculateStride(y);
            for (int x=x0; x < xMax; ++x) {
              PolOpUtils.getCoherencyMatrixT3(srcIndex.getIndex(x),sourceProductType,dataBuffers,Tr,Ti);
synchronized (clusterCounter) {
                if (category[y][x] == Categories.vol) {
                  computeSummationOfT3(cluster[y][x] + 1,Tr,Ti,pvSumRe,pvSumIm);
                  clusterCounter[0][cluster[y][x]]++;
                }
 else                 if (category[y][x] == Categories.dbl) {
                  computeSummationOfT3(cluster[y][x] + 1,Tr,Ti,pdSumRe,pdSumIm);
                  clusterCounter[1][cluster[y][x]]++;
                }
 else                 if (category[y][x] == Categories.suf) {
                  computeSummationOfT3(cluster[y][x] + 1,Tr,Ti,psSumRe,psSumIm);
                  clusterCounter[2][cluster[y][x]]++;
                }
              }
            }
          }
        }
      }
;
      threadManager.add(worker);
      status.worked(1);
    }
    threadManager.finish();
  }
 catch (  Throwable e) {
    OperatorUtils.catchOperatorException(op.getId() + "String_Node_Str",e);
  }
 finally {
    status.done();
  }
  for (int c=0; c < numInitialClusters; c++) {
    double[][] centerRe=new double[3][3];
    double[][] centerIm=new double[3][3];
    if (clusterCounter[0][c] > 0) {
      for (int i=0; i < 3; i++) {
        for (int j=0; j < 3; j++) {
          centerRe[i][j]=pvSumRe[c][i][j] / clusterCounter[0][c];
          centerIm[i][j]=pvSumIm[c][i][j] / clusterCounter[0][c];
        }
      }
      ClusterInfo clusterCenter=new ClusterInfo();
      clusterCenter.setClusterCenter(c,centerRe,centerIm,clusterCounter[0][c]);
      pvCenterList.add(clusterCenter);
    }
    if (clusterCounter[1][c] > 0) {
      for (int i=0; i < 3; i++) {
        for (int j=0; j < 3; j++) {
          centerRe[i][j]=pdSumRe[c][i][j] / clusterCounter[1][c];
          centerIm[i][j]=pdSumIm[c][i][j] / clusterCounter[1][c];
        }
      }
      ClusterInfo clusterCenter=new ClusterInfo();
      clusterCenter.setClusterCenter(c,centerRe,centerIm,clusterCounter[1][c]);
      pdCenterList.add(clusterCenter);
    }
    if (clusterCounter[2][c] > 0) {
      for (int i=0; i < 3; i++) {
        for (int j=0; j < 3; j++) {
          centerRe[i][j]=psSumRe[c][i][j] / clusterCounter[2][c];
          centerIm[i][j]=psSumIm[c][i][j] / clusterCounter[2][c];
        }
      }
      ClusterInfo clusterCenter=new ClusterInfo();
      clusterCenter.setClusterCenter(c,centerRe,centerIm,clusterCounter[2][c]);
      psCenterList.add(clusterCenter);
    }
  }
}