Program: 11460
Project: 11460
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;
  OverlapPercentage tileOverlapPercentage=null;
  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();
  }
  final int ymin=Math.max(y0 - (int)(h * tileOverlapPercentage.tileOverlapUp),0);
  final int ymax=Math.min(y0 + h + (int)(h * tileOverlapPercentage.tileOverlapDown),sourceImageHeight);
  final int xmin=Math.max(x0 - (int)(w * tileOverlapPercentage.tileOverlapLeft),0);
  final int xmax=Math.min(x0 + w + (int)(w * tileOverlapPercentage.tileOverlapRight),sourceImageWidth);
  final PositionData posData=new PositionData();
  final GeoPos geoPos=new GeoPos();
  double[] slrs=null;
  double[] elev=null;
  int[] index=null;
  boolean[] savePixel=null;
  try {
    if (reGridMethod) {
      final double[] latLonMinMax=new double[4];
      computeImageGeoBoundary(xmin,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;
      if (saveLayoverShadowMask) {
        slrs=new double[nLon];
        elev=new double[nLon];
        index=new int[nLon];
        savePixel=new boolean[nLon];
      }
      for (int i=0; i < nLat; i++) {
        final double lat=latMin + i * delLat;
        Arrays.fill(slrs,0.0);
        Arrays.fill(elev,0.0);
        Arrays.fill(index,-1);
        Arrays.fill(savePixel,Boolean.FALSE);
        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(lat,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;
            double neighbourLat=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,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;
            if (rIndex >= x0 && rIndex < x0 + w && aIndex >= y0 && aIndex < y0 + h) {
              index[j]=targetTile.getDataBufferIndex(rIndex,aIndex);
              slrs[j]=posData.slantRange;
              elev[j]=computeElevationAngle(posData.slantRange,posData.earthPoint,posData.sensorPos);
              savePixel[j]=true;
            }
 else {
              savePixel[j]=false;
            }
          }
        }
        if (saveLayoverShadowMask) {
          computeLayoverShadow(savePixel,slrs,index,elev,layoverShadowMaskBuffer);
        }
      }
    }
 else {
      final int widthExt=xmax - xmin;
      final int heightExt=ymax - ymin;
      if (saveLayoverShadowMask) {
        slrs=new double[widthExt];
        elev=new double[widthExt];
        index=new int[widthExt];
        savePixel=new boolean[widthExt];
      }
      final double[][] localDEM=new double[heightExt + 2][widthExt + 2];
      final TileGeoreferencing tileGeoRef=new TileGeoreferencing(targetProduct,xmin,ymin,widthExt,heightExt);
      if (saveZeroHeightSimulation) {
        for (        double[] aLocalDEM : localDEM) {
          Arrays.fill(aLocalDEM,1);
        }
      }
 else {
        final boolean valid=DEMFactory.getLocalDEM(dem,demNoDataValue,demResamplingMethod,tileGeoRef,xmin,ymin,widthExt,heightExt,sourceProduct,true,localDEM);
        if (!valid)         return;
      }
      for (int y=ymin; y < ymax; y++) {
        final int yy=y - ymin;
        Arrays.fill(slrs,0.0);
        Arrays.fill(elev,0.0);
        Arrays.fill(index,-1);
        Arrays.fill(savePixel,Boolean.FALSE);
        for (int x=xmin; x < xmax; x++) {
          final int xx=x - xmin;
          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=jOrbit.lp2ell(new Point(x + 0.5,y + 0.5),meta);
            lat=latlon[0] * Constants.RTOD;
            lon=latlon[1] * Constants.RTOD;
            alt=dem.getElevation(new GeoPos(lat,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,xmin,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;
            if (rIndex >= x0 && rIndex < x0 + w && aIndex >= y0 && aIndex < y0 + h) {
              index[xx]=targetTile.getDataBufferIndex(rIndex,aIndex);
              slrs[xx]=posData.slantRange;
              elev[xx]=computeElevationAngle(posData.slantRange,posData.earthPoint,posData.sensorPos);
              savePixel[xx]=true;
            }
 else {
              savePixel[xx]=false;
            }
          }
        }
        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;
  OverlapPercentage tileOverlapPercentage=null;
  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();
  }
  final int ymin=Math.max(y0 - (int)(h * tileOverlapPercentage.tileOverlapUp),0);
  final int ymax=Math.min(y0 + h + (int)(h * tileOverlapPercentage.tileOverlapDown),sourceImageHeight);
  final int xmin=Math.max(x0 - (int)(w * tileOverlapPercentage.tileOverlapLeft),0);
  final int xmax=Math.min(x0 + w + (int)(w * tileOverlapPercentage.tileOverlapRight),sourceImageWidth);
  final PositionData posData=new PositionData();
  final GeoPos geoPos=new GeoPos();
  double[] slrs=null;
  double[] elev=null;
  int[] index=null;
  boolean[] savePixel=null;
  try {
    if (reGridMethod) {
      final double[] latLonMinMax=new double[4];
      computeImageGeoBoundary(xmin,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;
      if (saveLayoverShadowMask) {
        slrs=new double[nLon];
        elev=new double[nLon];
        index=new int[nLon];
        savePixel=new boolean[nLon];
      }
      for (int i=0; i < nLat; i++) {
        final double lat=latMin + i * delLat;
        if (saveLayoverShadowMask) {
          Arrays.fill(slrs,0.0);
          Arrays.fill(elev,0.0);
          Arrays.fill(index,-1);
          Arrays.fill(savePixel,Boolean.FALSE);
        }
        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(lat,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;
            double neighbourLat=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,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;
            if (rIndex >= x0 && rIndex < x0 + w && aIndex >= y0 && aIndex < y0 + h) {
              index[j]=targetTile.getDataBufferIndex(rIndex,aIndex);
              slrs[j]=posData.slantRange;
              elev[j]=computeElevationAngle(posData.slantRange,posData.earthPoint,posData.sensorPos);
              savePixel[j]=true;
            }
 else {
              savePixel[j]=false;
            }
          }
        }
        if (saveLayoverShadowMask) {
          computeLayoverShadow(savePixel,slrs,index,elev,layoverShadowMaskBuffer);
        }
      }
    }
 else {
      final int widthExt=xmax - xmin;
      final int heightExt=ymax - ymin;
      if (saveLayoverShadowMask) {
        slrs=new double[widthExt];
        elev=new double[widthExt];
        index=new int[widthExt];
        savePixel=new boolean[widthExt];
      }
      final double[][] localDEM=new double[heightExt + 2][widthExt + 2];
      final TileGeoreferencing tileGeoRef=new TileGeoreferencing(targetProduct,xmin,ymin,widthExt,heightExt);
      if (saveZeroHeightSimulation) {
        for (        double[] aLocalDEM : localDEM) {
          Arrays.fill(aLocalDEM,1);
        }
      }
 else {
        final boolean valid=DEMFactory.getLocalDEM(dem,demNoDataValue,demResamplingMethod,tileGeoRef,xmin,ymin,widthExt,heightExt,sourceProduct,true,localDEM);
        if (!valid)         return;
      }
      for (int y=ymin; y < ymax; y++) {
        final int yy=y - ymin;
        if (saveLayoverShadowMask) {
          Arrays.fill(slrs,0.0);
          Arrays.fill(elev,0.0);
          Arrays.fill(index,-1);
          Arrays.fill(savePixel,Boolean.FALSE);
        }
        for (int x=xmin; x < xmax; x++) {
          final int xx=x - xmin;
          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=jOrbit.lp2ell(new Point(x + 0.5,y + 0.5),meta);
            lat=latlon[0] * Constants.RTOD;
            lon=latlon[1] * Constants.RTOD;
            alt=dem.getElevation(new GeoPos(lat,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,xmin,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;
            if (rIndex >= x0 && rIndex < x0 + w && aIndex >= y0 && aIndex < y0 + h) {
              index[xx]=targetTile.getDataBufferIndex(rIndex,aIndex);
              slrs[xx]=posData.slantRange;
              elev[xx]=computeElevationAngle(posData.slantRange,posData.earthPoint,posData.sensorPos);
              savePixel[xx]=true;
            }
 else {
              savePixel[xx]=false;
            }
          }
        }
        if (saveLayoverShadowMask) {
          computeLayoverShadow(savePixel,slrs,index,elev,layoverShadowMaskBuffer);
        }
      }
    }
  }
 catch (  Throwable e) {
    OperatorUtils.catchOperatorException(getId(),e);
  }
}