Program: 11563
Project: 11563
Buggy source:
/** 
 * Called by the framework in order to compute the stack of tiles for the given target bands. <p>The default implementation throws a runtime exception with the message "not implemented".</p>
 * @param targetTiles     The current tiles to be computed for each target band.
 * @param targetRectangle The area in pixel coordinates to be computed (same for all rasters in <code>targetRasters</code>).
 * @param pm              A progress monitor which should be used to determine computation cancelation requests.
 * @throws OperatorException if an error occurs during computation of the target rasters.
 */
@Override public void computeTileStack(Map<Band,Tile> targetTiles,Rectangle targetRectangle,ProgressMonitor pm) throws OperatorException {
  final int x0=targetRectangle.x;
  final int y0=targetRectangle.y;
  final int w=targetRectangle.width;
  final int h=targetRectangle.height;
  double tileOverlapPercentage;
  try {
    if (!isElevationModelAvailable) {
      getElevationModel();
    }
    tileOverlapPercentage=computeTileOverlapPercentage(x0,y0,w,h);
  }
 catch (  Exception e) {
    throw new OperatorException(e);
  }
  final Tile targetTile=targetTiles.get(targetProduct.getBand(SIMULATED_BAND_NAME));
  final ProductData masterBuffer=targetTile.getDataBuffer();
  ProductData demBandBuffer=null;
  ProductData zeroHeightBandBuffer=null;
  ProductData localIncidenceAngleBandBuffer=null;
  ProductData layoverShadowMaskBuffer=null;
  if (saveDEM) {
    demBandBuffer=targetTiles.get(targetProduct.getBand(demBandName)).getDataBuffer();
  }
  if (saveZeroHeightSimulation) {
    zeroHeightBandBuffer=targetTiles.get(targetProduct.getBand(zeroHeightSimulationBandName)).getDataBuffer();
  }
  if (saveLocalIncidenceAngle) {
    localIncidenceAngleBandBuffer=targetTiles.get(targetProduct.getBand(simulatedLocalIncidenceAngleBandName)).getDataBuffer();
  }
  if (saveLayoverShadowMask) {
    layoverShadowMaskBuffer=targetTiles.get(targetProduct.getBand(layoverShadowMaskBandName)).getDataBuffer();
  }
  int ymin, ymax;
  if (tileOverlapPercentage >= 0.0f) {
    ymin=Math.max(y0 - (int)(tileSize * tileOverlapPercentage),0);
    ymax=y0 + h;
  }
 else {
    ymin=y0;
    ymax=y0 + h + (int)(tileSize * Math.abs(tileOverlapPercentage));
  }
  final int xmax=x0 + w;
  final PositionData posData=new PositionData();
  final GeoPos geoPos=new GeoPos();
  double[] slrs=null;
  double[] elev=null;
  int[] index=null;
  final boolean[] savePixel=new boolean[w];
  if (saveLayoverShadowMask) {
    slrs=new double[w];
    elev=new double[w];
    index=new int[w];
  }
  try {
    if (reGridMethod) {
      final double[] latLonMinMax=new double[4];
      computeImageGeoBoundary(x0,xmax,ymin,ymax,latLonMinMax);
      final double latMin=latLonMinMax[0];
      final double latMax=latLonMinMax[1];
      final double lonMin=latLonMinMax[2];
      final double lonMax=latLonMinMax[3];
      final int nLat=(int)((latMax - latMin) / delLat) + 1;
      final int nLon=(int)((lonMax - lonMin) / delLon) + 1;
      final double[][] tileDEM=new double[nLat + 1][nLon + 1];
      final double[][] neighbourDEM=new double[3][3];
      double alt;
      for (int i=0; i < nLat; i++) {
        final double lat=latMin + i * delLat;
        for (int j=0; j < nLon; j++) {
          double lon=lonMin + j * delLon;
          if (lon >= 180.0) {
            lon-=360.0;
          }
          if (saveZeroHeightSimulation) {
            alt=1;
          }
 else {
            geoPos.setLocation((float)lat,(float)lon);
            alt=dem.getElevation(geoPos);
            if (alt == demNoDataValue)             continue;
          }
          tileDEM[i][j]=alt;
          if (!getPosition(lat,lon,alt,x0,y0,w,h,posData))           continue;
          final LocalGeometry localGeometry=new LocalGeometry(lat,lon,delLat,delLon,posData.earthPoint,posData.sensorPos);
          final double[] localIncidenceAngles={SARGeocoding.NonValidIncidenceAngle,SARGeocoding.NonValidIncidenceAngle};
          int r=0;
          for (int ii=Math.max(0,i - 1); ii <= i + 1; ++ii) {
            ii=Math.min(nLat,ii);
            int c=0;
            float neighbourLat=(float)(latMin + ii * delLat);
            for (int jj=Math.max(0,j - 1); jj <= j + 1; ++jj) {
              jj=Math.min(nLon,jj);
              neighbourDEM[r][c]=tileDEM[ii][jj];
              if (neighbourDEM[r][c] == 0) {
                if (saveZeroHeightSimulation) {
                  neighbourDEM[r][c]=1;
                }
 else {
                  geoPos.setLocation(neighbourLat,(float)(lonMin + jj * delLon));
                  neighbourDEM[r][c]=dem.getElevation(geoPos);
                }
                tileDEM[ii][jj]=neighbourDEM[r][c];
              }
              ++c;
            }
            ++r;
          }
          SARGeocoding.computeLocalIncidenceAngle(localGeometry,demNoDataValue,false,true,false,0,0,0,0,neighbourDEM,localIncidenceAngles);
          if (localIncidenceAngles[1] == SARGeocoding.NonValidIncidenceAngle) {
            continue;
          }
          final double v=computeBackscatteredPower(localIncidenceAngles[1]);
          saveSimulatedData(posData.azimuthIndex,posData.rangeIndex,v,x0,y0,w,h,targetTile,masterBuffer);
          int idx=0;
          if (saveDEM || saveLocalIncidenceAngle)           idx=targetTile.getDataBufferIndex((int)posData.rangeIndex,(int)posData.azimuthIndex);
          if (saveDEM && idx >= 0) {
            demBandBuffer.setElemDoubleAt(idx,alt);
          }
          if (saveZeroHeightSimulation) {
            saveSimulatedData(posData.azimuthIndex,posData.rangeIndex,1,x0,y0,w,h,targetTile,zeroHeightBandBuffer);
          }
          if (saveLocalIncidenceAngle && idx >= 0) {
            localIncidenceAngleBandBuffer.setElemDoubleAt(idx,localIncidenceAngles[1]);
          }
          if (saveLayoverShadowMask) {
            int rIndex=(int)posData.rangeIndex;
            int aIndex=(int)posData.azimuthIndex;
            index[rIndex]=targetTile.getDataBufferIndex(rIndex,aIndex);
            if (index[rIndex] < 0) {
              savePixel[rIndex]=false;
            }
 else {
              slrs[rIndex]=posData.slantRange;
              elev[rIndex]=computeElevationAngle(posData.slantRange,posData.earthPoint,posData.sensorPos);
              savePixel[rIndex]=true;
            }
          }
        }
        if (saveLayoverShadowMask) {
          computeLayoverShadow(savePixel,slrs,index,elev,layoverShadowMaskBuffer);
        }
      }
    }
 else {
      final double[][] localDEM=new double[ymax - ymin + 2][w + 2];
      final TileGeoreferencing tileGeoRef=new TileGeoreferencing(targetProduct,x0,ymin,w,ymax - ymin);
      if (saveZeroHeightSimulation) {
        for (        double[] aLocalDEM : localDEM) {
          Arrays.fill(aLocalDEM,1);
        }
      }
 else {
        final boolean valid=DEMFactory.getLocalDEM(dem,demNoDataValue,demResamplingMethod,tileGeoRef,x0,ymin,w,ymax - ymin,localDEM);
        if (!valid)         return;
      }
      for (int y=ymin; y < ymax; y++) {
        final int yy=y - ymin;
        for (int x=x0; x < xmax; x++) {
          final int xx=x - x0;
          double alt=localDEM[yy][xx];
          if (alt == demNoDataValue)           continue;
          tileGeoRef.getGeoPos(x,y,geoPos);
          if (!geoPos.isValid())           continue;
          double lat=geoPos.lat;
          double lon=geoPos.lon;
          if (lon >= 180.0) {
            lon-=360.0;
          }
          if (orbitMethod) {
            double[] latlon=orbit.lp2ell(new Point(x + 0.5,y + 0.5),meta);
            lat=latlon[0] * MathUtils.RTOD;
            lon=latlon[1] * MathUtils.RTOD;
            alt=dem.getElevation(new GeoPos((float)lat,(float)lon));
          }
          if (!getPosition(lat,lon,alt,x0,y0,w,h,posData))           continue;
          final LocalGeometry localGeometry=new LocalGeometry(x,y,tileGeoRef,posData.earthPoint,posData.sensorPos);
          final double[] localIncidenceAngles={SARGeocoding.NonValidIncidenceAngle,SARGeocoding.NonValidIncidenceAngle};
          SARGeocoding.computeLocalIncidenceAngle(localGeometry,demNoDataValue,false,true,false,x0,ymin,x,y,localDEM,localIncidenceAngles);
          if (localIncidenceAngles[1] == SARGeocoding.NonValidIncidenceAngle)           continue;
          final double v=computeBackscatteredPower(localIncidenceAngles[1]);
          saveSimulatedData(posData.azimuthIndex,posData.rangeIndex,v,x0,y0,w,h,targetTile,masterBuffer);
          int idx=0;
          if (saveDEM || saveLocalIncidenceAngle)           idx=targetTile.getDataBufferIndex((int)posData.rangeIndex,(int)posData.azimuthIndex);
          if (saveDEM && idx >= 0) {
            demBandBuffer.setElemDoubleAt(idx,alt);
          }
          if (saveZeroHeightSimulation) {
            saveSimulatedData(posData.azimuthIndex,posData.rangeIndex,1,x0,y0,w,h,targetTile,zeroHeightBandBuffer);
          }
          if (saveLocalIncidenceAngle && idx >= 0) {
            localIncidenceAngleBandBuffer.setElemDoubleAt(idx,localIncidenceAngles[1]);
          }
          if (saveLayoverShadowMask) {
            int rIndex=(int)posData.rangeIndex;
            int aIndex=(int)posData.azimuthIndex;
            index[xx]=targetTile.getDataBufferIndex(rIndex,aIndex);
            if (index[xx] < 0) {
              savePixel[xx]=false;
            }
 else {
              slrs[xx]=posData.slantRange;
              elev[xx]=computeElevationAngle(posData.slantRange,posData.earthPoint,posData.sensorPos);
              savePixel[xx]=true;
            }
          }
        }
        if (saveLayoverShadowMask) {
          computeLayoverShadow(savePixel,slrs,index,elev,layoverShadowMaskBuffer);
        }
      }
    }
  }
 catch (  Throwable e) {
    OperatorUtils.catchOperatorException(getId(),e);
  }
}

Fixed version (ground truth):
/** 
 * Called by the framework in order to compute the stack of tiles for the given target bands. <p>The default implementation throws a runtime exception with the message "not implemented".</p>
 * @param targetTiles     The current tiles to be computed for each target band.
 * @param targetRectangle The area in pixel coordinates to be computed (same for all rasters in <code>targetRasters</code>).
 * @param pm              A progress monitor which should be used to determine computation cancelation requests.
 * @throws OperatorException if an error occurs during computation of the target rasters.
 */
@Override public void computeTileStack(Map<Band,Tile> targetTiles,Rectangle targetRectangle,ProgressMonitor pm) throws OperatorException {
  final int x0=targetRectangle.x;
  final int y0=targetRectangle.y;
  final int w=targetRectangle.width;
  final int h=targetRectangle.height;
  double tileOverlapPercentage;
  try {
    if (!isElevationModelAvailable) {
      getElevationModel();
    }
    tileOverlapPercentage=computeTileOverlapPercentage(x0,y0,w,h);
  }
 catch (  Exception e) {
    throw new OperatorException(e);
  }
  final Tile targetTile=targetTiles.get(targetProduct.getBand(SIMULATED_BAND_NAME));
  final ProductData masterBuffer=targetTile.getDataBuffer();
  ProductData demBandBuffer=null;
  ProductData zeroHeightBandBuffer=null;
  ProductData localIncidenceAngleBandBuffer=null;
  ProductData layoverShadowMaskBuffer=null;
  if (saveDEM) {
    demBandBuffer=targetTiles.get(targetProduct.getBand(demBandName)).getDataBuffer();
  }
  if (saveZeroHeightSimulation) {
    zeroHeightBandBuffer=targetTiles.get(targetProduct.getBand(zeroHeightSimulationBandName)).getDataBuffer();
  }
  if (saveLocalIncidenceAngle) {
    localIncidenceAngleBandBuffer=targetTiles.get(targetProduct.getBand(simulatedLocalIncidenceAngleBandName)).getDataBuffer();
  }
  if (saveLayoverShadowMask) {
    layoverShadowMaskBuffer=targetTiles.get(targetProduct.getBand(layoverShadowMaskBandName)).getDataBuffer();
  }
  int ymin, ymax;
  if (tileOverlapPercentage >= 0.0f) {
    ymin=Math.max(y0 - (int)(tileSize * tileOverlapPercentage),0);
    ymax=y0 + h;
  }
 else {
    ymin=y0;
    ymax=y0 + h + (int)(tileSize * Math.abs(tileOverlapPercentage));
  }
  final int xmax=x0 + w;
  final PositionData posData=new PositionData();
  final GeoPos geoPos=new GeoPos();
  double[] slrs=null;
  double[] elev=null;
  int[] index=null;
  final boolean[] savePixel=new boolean[w];
  if (saveLayoverShadowMask) {
    slrs=new double[w];
    elev=new double[w];
    index=new int[w];
  }
  try {
    if (reGridMethod) {
      final double[] latLonMinMax=new double[4];
      computeImageGeoBoundary(x0,xmax,ymin,ymax,latLonMinMax);
      final double latMin=latLonMinMax[0];
      final double latMax=latLonMinMax[1];
      final double lonMin=latLonMinMax[2];
      final double lonMax=latLonMinMax[3];
      final int nLat=(int)((latMax - latMin) / delLat) + 1;
      final int nLon=(int)((lonMax - lonMin) / delLon) + 1;
      final double[][] tileDEM=new double[nLat + 1][nLon + 1];
      final double[][] neighbourDEM=new double[3][3];
      double alt;
      for (int i=0; i < nLat; i++) {
        final double lat=latMin + i * delLat;
        for (int j=0; j < nLon; j++) {
          double lon=lonMin + j * delLon;
          if (lon >= 180.0) {
            lon-=360.0;
          }
          if (saveZeroHeightSimulation) {
            alt=1;
          }
 else {
            geoPos.setLocation((float)lat,(float)lon);
            alt=dem.getElevation(geoPos);
            if (alt == demNoDataValue)             continue;
          }
          tileDEM[i][j]=alt;
          if (!getPosition(lat,lon,alt,x0,y0,w,h,posData))           continue;
          final LocalGeometry localGeometry=new LocalGeometry(lat,lon,delLat,delLon,posData.earthPoint,posData.sensorPos);
          final double[] localIncidenceAngles={SARGeocoding.NonValidIncidenceAngle,SARGeocoding.NonValidIncidenceAngle};
          int r=0;
          for (int ii=Math.max(0,i - 1); ii <= i + 1; ++ii) {
            ii=Math.min(nLat,ii);
            int c=0;
            float neighbourLat=(float)(latMin + ii * delLat);
            for (int jj=Math.max(0,j - 1); jj <= j + 1; ++jj) {
              jj=Math.min(nLon,jj);
              neighbourDEM[r][c]=tileDEM[ii][jj];
              if (neighbourDEM[r][c] == 0) {
                if (saveZeroHeightSimulation) {
                  neighbourDEM[r][c]=1;
                }
 else {
                  geoPos.setLocation(neighbourLat,(float)(lonMin + jj * delLon));
                  neighbourDEM[r][c]=dem.getElevation(geoPos);
                }
                tileDEM[ii][jj]=neighbourDEM[r][c];
              }
              ++c;
            }
            ++r;
          }
          SARGeocoding.computeLocalIncidenceAngle(localGeometry,demNoDataValue,false,true,false,0,0,0,0,neighbourDEM,localIncidenceAngles);
          if (localIncidenceAngles[1] == SARGeocoding.NonValidIncidenceAngle) {
            continue;
          }
          final double v=computeBackscatteredPower(localIncidenceAngles[1]);
          saveSimulatedData(posData.azimuthIndex,posData.rangeIndex,v,x0,y0,w,h,targetTile,masterBuffer);
          int idx=0;
          if (saveDEM || saveLocalIncidenceAngle)           idx=targetTile.getDataBufferIndex((int)posData.rangeIndex,(int)posData.azimuthIndex);
          if (saveDEM && idx >= 0) {
            demBandBuffer.setElemDoubleAt(idx,alt);
          }
          if (saveZeroHeightSimulation) {
            saveSimulatedData(posData.azimuthIndex,posData.rangeIndex,1,x0,y0,w,h,targetTile,zeroHeightBandBuffer);
          }
          if (saveLocalIncidenceAngle && idx >= 0) {
            localIncidenceAngleBandBuffer.setElemDoubleAt(idx,localIncidenceAngles[1]);
          }
          if (saveLayoverShadowMask) {
            int rIndex=(int)posData.rangeIndex;
            int aIndex=(int)posData.azimuthIndex;
            index[rIndex]=targetTile.getDataBufferIndex(rIndex,aIndex);
            if (index[rIndex] < 0) {
              savePixel[rIndex]=false;
            }
 else {
              slrs[rIndex]=posData.slantRange;
              elev[rIndex]=computeElevationAngle(posData.slantRange,posData.earthPoint,posData.sensorPos);
              savePixel[rIndex]=true;
            }
          }
        }
        if (saveLayoverShadowMask) {
          computeLayoverShadow(savePixel,slrs,index,elev,layoverShadowMaskBuffer);
        }
      }
    }
 else {
      final double[][] localDEM=new double[ymax - ymin + 2][w + 2];
      final TileGeoreferencing tileGeoRef=new TileGeoreferencing(targetProduct,x0,ymin,w,ymax - ymin);
      if (saveZeroHeightSimulation) {
        for (        double[] aLocalDEM : localDEM) {
          Arrays.fill(aLocalDEM,1);
        }
      }
 else {
        final boolean valid=DEMFactory.getLocalDEM(dem,demNoDataValue,demResamplingMethod,tileGeoRef,x0,ymin,w,ymax - ymin,localDEM);
        if (!valid)         return;
      }
      for (int y=ymin; y < ymax; y++) {
        final int yy=y - ymin;
        for (int x=x0; x < xmax; x++) {
          final int xx=x - x0;
          double alt=localDEM[yy + 1][xx + 1];
          if (alt == demNoDataValue)           continue;
          tileGeoRef.getGeoPos(x,y,geoPos);
          if (!geoPos.isValid())           continue;
          double lat=geoPos.lat;
          double lon=geoPos.lon;
          if (lon >= 180.0) {
            lon-=360.0;
          }
          if (orbitMethod) {
            double[] latlon=orbit.lp2ell(new Point(x + 0.5,y + 0.5),meta);
            lat=latlon[0] * MathUtils.RTOD;
            lon=latlon[1] * MathUtils.RTOD;
            alt=dem.getElevation(new GeoPos((float)lat,(float)lon));
          }
          if (!getPosition(lat,lon,alt,x0,y0,w,h,posData))           continue;
          final LocalGeometry localGeometry=new LocalGeometry(x,y,tileGeoRef,posData.earthPoint,posData.sensorPos);
          final double[] localIncidenceAngles={SARGeocoding.NonValidIncidenceAngle,SARGeocoding.NonValidIncidenceAngle};
          SARGeocoding.computeLocalIncidenceAngle(localGeometry,demNoDataValue,false,true,false,x0,ymin,x,y,localDEM,localIncidenceAngles);
          if (localIncidenceAngles[1] == SARGeocoding.NonValidIncidenceAngle)           continue;
          final double v=computeBackscatteredPower(localIncidenceAngles[1]);
          saveSimulatedData(posData.azimuthIndex,posData.rangeIndex,v,x0,y0,w,h,targetTile,masterBuffer);
          int idx=0;
          if (saveDEM || saveLocalIncidenceAngle)           idx=targetTile.getDataBufferIndex((int)posData.rangeIndex,(int)posData.azimuthIndex);
          if (saveDEM && idx >= 0) {
            demBandBuffer.setElemDoubleAt(idx,alt);
          }
          if (saveZeroHeightSimulation) {
            saveSimulatedData(posData.azimuthIndex,posData.rangeIndex,1,x0,y0,w,h,targetTile,zeroHeightBandBuffer);
          }
          if (saveLocalIncidenceAngle && idx >= 0) {
            localIncidenceAngleBandBuffer.setElemDoubleAt(idx,localIncidenceAngles[1]);
          }
          if (saveLayoverShadowMask) {
            int rIndex=(int)posData.rangeIndex;
            int aIndex=(int)posData.azimuthIndex;
            index[xx]=targetTile.getDataBufferIndex(rIndex,aIndex);
            if (index[xx] < 0) {
              savePixel[xx]=false;
            }
 else {
              slrs[xx]=posData.slantRange;
              elev[xx]=computeElevationAngle(posData.slantRange,posData.earthPoint,posData.sensorPos);
              savePixel[xx]=true;
            }
          }
        }
        if (saveLayoverShadowMask) {
          computeLayoverShadow(savePixel,slrs,index,elev,layoverShadowMaskBuffer);
        }
      }
    }
  }
 catch (  Throwable e) {
    OperatorUtils.catchOperatorException(getId(),e);
  }
}