Program: 11478
Project: 11478
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 {
  processingStarted=true;
  final int x0=targetRectangle.x;
  final int y0=targetRectangle.y;
  final int w=targetRectangle.width;
  final int h=targetRectangle.height;
  final int ymax=y0 + h;
  final int xmax=x0 + w;
  final GeoPos geoPos=new GeoPos();
  final PosVector earthPoint=new PosVector();
  final PosVector sensorPos=new PosVector();
  final int srcMaxRange=sourceImageWidth - 1;
  final int srcMaxAzimuth=sourceImageHeight - 1;
  ProductData demBuffer=null;
  ProductData latBuffer=null;
  ProductData lonBuffer=null;
  ProductData localIncidenceAngleBuffer=null;
  ProductData projectedLocalIncidenceAngleBuffer=null;
  ProductData layoverShadowingMasksBuffer=null;
  ProductData incidenceAngleFromEllipsoidBuffer=null;
  final Set<Band> keySet=targetTiles.keySet();
  if (!warpDataAvailable) {
    getWarpData(keySet,targetRectangle);
    outputResidualAndShiftFiles();
  }
  final List<RangeDopplerGeocodingOp.TileData> trgTileList=new ArrayList<>();
  for (  Band targetBand : keySet) {
    if (targetBand.getName().equals("String_Node_Str")) {
      demBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      latBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      lonBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      localIncidenceAngleBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      projectedLocalIncidenceAngleBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals(SARSimulationOp.layoverShadowMaskBandName)) {
      layoverShadowingMasksBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      incidenceAngleFromEllipsoidBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    final String[] srcBandNames=targetBandNameToSourceBandName.get(targetBand.getName());
    final Band[] srcBands=new Band[]{sourceProduct.getBand(srcBandNames[0]),srcBandNames.length > 1 ? sourceProduct.getBand(srcBandNames[1]) : null};
    final RangeDopplerGeocodingOp.TileData td=new RangeDopplerGeocodingOp.TileData(targetTiles.get(targetBand),srcBands,isPolsar,targetBand.getName(),getBandUnit(targetBand.getName()),absRoot,calibrator,imgResampling);
    td.applyRadiometricNormalization=targetBandapplyRadiometricNormalizationFlag.get(targetBand.getName());
    td.applyRetroCalibration=targetBandApplyRetroCalibrationFlag.get(targetBand.getName());
    trgTileList.add(td);
  }
  final RangeDopplerGeocodingOp.TileData[] trgTiles=trgTileList.toArray(new RangeDopplerGeocodingOp.TileData[trgTileList.size()]);
  final TileGeoreferencing tileGeoRef=new TileGeoreferencing(targetProduct,x0 - 1,y0 - 1,w + 2,h + 2);
  int diffLat=Math.abs(latitude.getPixelInt(0,0) - latitude.getPixelInt(0,targetImageHeight));
  try {
    final double[][] localDEM=new double[h + 2][w + 2];
    if (useAvgSceneHeight) {
      DEMFactory.fillDEM(localDEM,avgSceneHeight);
    }
 else {
      final boolean valid=DEMFactory.getLocalDEM(dem,demNoDataValue,demResamplingMethod,tileGeoRef,x0,y0,w,h,sourceProduct,true,localDEM);
      if (!valid)       return;
    }
    for (int y=y0; y < ymax; y++) {
      final int yy=y - y0 + 1;
      for (int x=x0; x < xmax; x++) {
        final int index=trgTiles[0].targetTile.getDataBufferIndex(x,y);
        final double alt=localDEM[yy][x - x0 + 1];
        if (!useAvgSceneHeight && alt == demNoDataValue) {
          if (saveDEM) {
            demBuffer.setElemDoubleAt(index,demNoDataValue);
          }
          continue;
        }
        tileGeoRef.getGeoPos(x,y,geoPos);
        if (!geoPos.isValid()) {
          continue;
        }
        final double lat=geoPos.lat;
        double lon=geoPos.lon;
        if (lon >= 180.0) {
          lon-=360.0;
        }
        GeoUtils.geo2xyzWGS84(lat,lon,alt,earthPoint);
        final double zeroDopplerTime=getEarthPointZeroDopplerTime(earthPoint);
        if (Double.compare(zeroDopplerTime,NonValidZeroDopplerTime) == 0) {
          if (saveDEM) {
            demBuffer.setElemDoubleAt(index,demNoDataValue);
          }
          continue;
        }
        double slantRange=SARGeocoding.computeSlantRange(zeroDopplerTime,orbit,earthPoint,sensorPos);
        double zeroDoppler=zeroDopplerTime;
        if (!skipBistaticCorrection) {
          zeroDoppler=zeroDopplerTime + slantRange / Constants.lightSpeedInMetersPerDay;
          slantRange=SARGeocoding.computeSlantRange(zeroDoppler,orbit,earthPoint,sensorPos);
        }
        final double azimuthIndex=(zeroDoppler - firstLineUTC) / lineTimeInterval;
        double rangeIndex=SARGeocoding.computeRangeIndex(srgrFlag,sourceImageWidth,firstLineUTC,lastLineUTC,rangeSpacing,zeroDoppler,slantRange,nearEdgeSlantRange,srgrConvParams);
        if (!nearRangeOnLeft) {
          rangeIndex=srcMaxRange - rangeIndex;
        }
        if (!SARGeocoding.isValidCell(rangeIndex,azimuthIndex,lat,lon,diffLat,latitude,longitude,srcMaxRange,srcMaxAzimuth,sensorPos)) {
          if (saveDEM) {
            demBuffer.setElemDoubleAt(index,demNoDataValue);
          }
        }
 else {
          final double[] localIncidenceAngles={SARGeocoding.NonValidIncidenceAngle,SARGeocoding.NonValidIncidenceAngle};
          if (saveLocalIncidenceAngle || saveProjectedLocalIncidenceAngle || saveSigmaNought) {
            final LocalGeometry localGeometry=new LocalGeometry(x,y,tileGeoRef,earthPoint,sensorPos);
            SARGeocoding.computeLocalIncidenceAngle(localGeometry,demNoDataValue,saveLocalIncidenceAngle,saveProjectedLocalIncidenceAngle,saveSigmaNought,x0,y0,x,y,localDEM,localIncidenceAngles);
            if (saveLocalIncidenceAngle && localIncidenceAngles[0] != SARGeocoding.NonValidIncidenceAngle) {
              localIncidenceAngleBuffer.setElemDoubleAt(index,localIncidenceAngles[0]);
            }
            if (saveProjectedLocalIncidenceAngle && localIncidenceAngles[1] != SARGeocoding.NonValidIncidenceAngle) {
              projectedLocalIncidenceAngleBuffer.setElemDoubleAt(index,localIncidenceAngles[1]);
            }
          }
          if (saveDEM) {
            demBuffer.setElemDoubleAt(index,alt);
          }
          if (saveLatLon) {
            latBuffer.setElemDoubleAt(index,lat);
            lonBuffer.setElemDoubleAt(index,lon);
          }
          if (saveLayoverShadowMask) {
            final Rectangle srcRect=new Rectangle((int)(rangeIndex + 0.5),(int)(azimuthIndex + 0.5),1,1);
            final Tile sourceTile=getSourceTile(maskBand,srcRect);
            final int m=sourceTile.getDataBuffer().getElemIntAt(sourceTile.getDataBufferIndex((int)(rangeIndex + 0.5),(int)(azimuthIndex + 0.5)));
            layoverShadowingMasksBuffer.setElemIntAt(index,m);
          }
          if (saveIncidenceAngleFromEllipsoid) {
            incidenceAngleFromEllipsoidBuffer.setElemDoubleAt(index,incidenceAngle.getPixelDouble(rangeIndex,azimuthIndex));
          }
          for (          RangeDopplerGeocodingOp.TileData tileData : trgTiles) {
            final Unit.UnitType bandUnit=getBandUnit(tileData.bandName);
            final String[] srcBandName=targetBandNameToSourceBandName.get(tileData.bandName);
            final Band srcBand=sourceProduct.getBand(srcBandName[0]);
            final PixelPos pixelPos=new PixelPos();
            final WarpOp.WarpData warpData=warpDataMap.get(srcBand);
            if (warpData.notEnoughGCPs) {
              continue;
            }
            WarpOp.getWarpedCoords(warpData,warpPolynomialOrder,rangeIndex,azimuthIndex,pixelPos);
            if (pixelPos.x < 0.0 || pixelPos.x >= srcMaxRange || pixelPos.y < 0.0 || pixelPos.y >= srcMaxAzimuth) {
              tileData.tileDataBuffer.setElemDoubleAt(index,tileData.noDataValue);
              continue;
            }
            final int[] subSwathIndex={INVALID_SUB_SWATH_INDEX};
            double v=getPixelValue(pixelPos.y,pixelPos.x,tileData,subSwathIndex);
            if (v != tileData.noDataValue && tileData.applyRadiometricNormalization) {
              if (localIncidenceAngles[1] != SARGeocoding.NonValidIncidenceAngle) {
                final double satelliteHeight=Math.sqrt(sensorPos.x * sensorPos.x + sensorPos.y * sensorPos.y + sensorPos.z * sensorPos.z);
                final double sceneToEarthCentre=Math.sqrt(earthPoint.x * earthPoint.x + earthPoint.y * earthPoint.y + earthPoint.z * earthPoint.z);
                v=calibrator.applyCalibration(v,rangeIndex,azimuthIndex,slantRange,satelliteHeight,sceneToEarthCentre,localIncidenceAngles[1],tileData.bandPolar,bandUnit,subSwathIndex);
              }
 else {
                v=tileData.noDataValue;
              }
            }
            tileData.tileDataBuffer.setElemDoubleAt(index,v);
          }
          orthoDataProduced=true;
        }
      }
    }
  }
 catch (  Throwable e) {
    orthoDataProduced=true;
    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 {
  processingStarted=true;
  final int x0=targetRectangle.x;
  final int y0=targetRectangle.y;
  final int w=targetRectangle.width;
  final int h=targetRectangle.height;
  final int ymax=y0 + h;
  final int xmax=x0 + w;
  final GeoPos geoPos=new GeoPos();
  final PosVector earthPoint=new PosVector();
  final PosVector sensorPos=new PosVector();
  final int srcMaxRange=sourceImageWidth - 1;
  final int srcMaxAzimuth=sourceImageHeight - 1;
  ProductData demBuffer=null;
  ProductData latBuffer=null;
  ProductData lonBuffer=null;
  ProductData localIncidenceAngleBuffer=null;
  ProductData projectedLocalIncidenceAngleBuffer=null;
  ProductData layoverShadowingMasksBuffer=null;
  ProductData incidenceAngleFromEllipsoidBuffer=null;
  final Set<Band> keySet=targetTiles.keySet();
  if (!warpDataAvailable) {
    getWarpData(keySet,targetRectangle);
    outputResidualAndShiftFiles();
  }
  final List<RangeDopplerGeocodingOp.TileData> trgTileList=new ArrayList<>();
  for (  Band targetBand : keySet) {
    if (targetBand.getName().equals("String_Node_Str")) {
      demBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      latBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      lonBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      localIncidenceAngleBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      projectedLocalIncidenceAngleBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals(SARSimulationOp.layoverShadowMaskBandName)) {
      layoverShadowingMasksBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    if (targetBand.getName().equals("String_Node_Str")) {
      incidenceAngleFromEllipsoidBuffer=targetTiles.get(targetBand).getDataBuffer();
      continue;
    }
    final String[] srcBandNames=targetBandNameToSourceBandName.get(targetBand.getName());
    final Band[] srcBands=new Band[]{sourceProduct.getBand(srcBandNames[0]),srcBandNames.length > 1 ? sourceProduct.getBand(srcBandNames[1]) : null};
    final RangeDopplerGeocodingOp.TileData td=new RangeDopplerGeocodingOp.TileData(targetTiles.get(targetBand),srcBands,isPolsar,targetBand.getName(),getBandUnit(targetBand.getName()),absRoot,calibrator,imgResampling);
    td.applyRadiometricNormalization=targetBandapplyRadiometricNormalizationFlag.get(targetBand.getName());
    td.applyRetroCalibration=targetBandApplyRetroCalibrationFlag.get(targetBand.getName());
    trgTileList.add(td);
  }
  final RangeDopplerGeocodingOp.TileData[] trgTiles=trgTileList.toArray(new RangeDopplerGeocodingOp.TileData[trgTileList.size()]);
  final TileGeoreferencing tileGeoRef=new TileGeoreferencing(targetProduct,x0 - 1,y0 - 1,w + 2,h + 2);
  int diffLat=Math.abs(latitude.getPixelInt(0,0) - latitude.getPixelInt(0,targetImageHeight));
  try {
    final double[][] localDEM=new double[h + 2][w + 2];
    if (useAvgSceneHeight) {
      DEMFactory.fillDEM(localDEM,avgSceneHeight);
    }
 else {
      final boolean valid=DEMFactory.getLocalDEM(dem,demNoDataValue,demResamplingMethod,tileGeoRef,x0,y0,w,h,sourceProduct,true,localDEM);
      if (!valid)       return;
    }
    for (int y=y0; y < ymax; y++) {
      final int yy=y - y0 + 1;
      for (int x=x0; x < xmax; x++) {
        final int index=trgTiles[0].targetTile.getDataBufferIndex(x,y);
        final double alt=localDEM[yy][x - x0 + 1];
        if (!useAvgSceneHeight && alt == demNoDataValue) {
          if (saveDEM) {
            demBuffer.setElemDoubleAt(index,demNoDataValue);
          }
          continue;
        }
        tileGeoRef.getGeoPos(x,y,geoPos);
        if (!geoPos.isValid()) {
          continue;
        }
        final double lat=geoPos.lat;
        double lon=geoPos.lon;
        if (lon >= 180.0) {
          lon-=360.0;
        }
        GeoUtils.geo2xyzWGS84(lat,lon,alt,earthPoint);
        final double zeroDopplerTime=getEarthPointZeroDopplerTime(earthPoint);
        if (Double.compare(zeroDopplerTime,NonValidZeroDopplerTime) == 0) {
          if (saveDEM) {
            demBuffer.setElemDoubleAt(index,demNoDataValue);
          }
          continue;
        }
        double slantRange=SARGeocoding.computeSlantRange(zeroDopplerTime,orbit,earthPoint,sensorPos);
        double zeroDoppler=zeroDopplerTime;
        if (!skipBistaticCorrection) {
          zeroDoppler=zeroDopplerTime + slantRange / Constants.lightSpeedInMetersPerDay;
          slantRange=SARGeocoding.computeSlantRange(zeroDoppler,orbit,earthPoint,sensorPos);
        }
        final double azimuthIndex=(zeroDoppler - firstLineUTC) / lineTimeInterval;
        double rangeIndex=SARGeocoding.computeRangeIndex(srgrFlag,sourceImageWidth,firstLineUTC,lastLineUTC,rangeSpacing,zeroDoppler,slantRange,nearEdgeSlantRange,srgrConvParams);
        if (!nearRangeOnLeft) {
          rangeIndex=srcMaxRange - rangeIndex;
        }
        if (!SARGeocoding.isValidCell(rangeIndex,azimuthIndex,lat,lon,diffLat,latitude,longitude,srcMaxRange,srcMaxAzimuth,sensorPos)) {
          if (saveDEM) {
            demBuffer.setElemDoubleAt(index,demNoDataValue);
          }
        }
 else {
          final double[] localIncidenceAngles={SARGeocoding.NonValidIncidenceAngle,SARGeocoding.NonValidIncidenceAngle};
          if (saveLocalIncidenceAngle || saveProjectedLocalIncidenceAngle || saveSigmaNought) {
            final LocalGeometry localGeometry=new LocalGeometry(x,y,tileGeoRef,earthPoint,sensorPos);
            SARGeocoding.computeLocalIncidenceAngle(localGeometry,demNoDataValue,saveLocalIncidenceAngle,saveProjectedLocalIncidenceAngle,saveSigmaNought,x0,y0,x,y,localDEM,localIncidenceAngles);
            if (saveLocalIncidenceAngle && localIncidenceAngles[0] != SARGeocoding.NonValidIncidenceAngle) {
              localIncidenceAngleBuffer.setElemDoubleAt(index,localIncidenceAngles[0]);
            }
            if (saveProjectedLocalIncidenceAngle && localIncidenceAngles[1] != SARGeocoding.NonValidIncidenceAngle) {
              projectedLocalIncidenceAngleBuffer.setElemDoubleAt(index,localIncidenceAngles[1]);
            }
          }
          if (saveDEM) {
            demBuffer.setElemDoubleAt(index,alt);
          }
          if (saveLatLon) {
            latBuffer.setElemDoubleAt(index,lat);
            lonBuffer.setElemDoubleAt(index,lon);
          }
          if (saveLayoverShadowMask) {
            final Rectangle srcRect=new Rectangle((int)(rangeIndex + 0.5),(int)(azimuthIndex + 0.5),1,1);
            final Tile sourceTile=getSourceTile(maskBand,srcRect);
            final int m=sourceTile.getDataBuffer().getElemIntAt(sourceTile.getDataBufferIndex((int)(rangeIndex + 0.5),(int)(azimuthIndex + 0.5)));
            layoverShadowingMasksBuffer.setElemIntAt(index,m);
          }
          if (saveIncidenceAngleFromEllipsoid) {
            incidenceAngleFromEllipsoidBuffer.setElemDoubleAt(index,incidenceAngle.getPixelDouble(rangeIndex,azimuthIndex));
          }
          for (          RangeDopplerGeocodingOp.TileData tileData : trgTiles) {
            final Unit.UnitType bandUnit=getBandUnit(tileData.bandName);
            final String[] srcBandName=targetBandNameToSourceBandName.get(tileData.bandName);
            final Band srcBand=sourceProduct.getBand(srcBandName[0]);
            final PixelPos pixelPos=new PixelPos();
            final WarpOp.WarpData warpData=warpDataMap.get(srcBand);
            if (warpData.notEnoughGCPs) {
              continue;
            }
            WarpOp.getWarpedCoords(warpData,warpPolynomialOrder,rangeIndex,azimuthIndex,pixelPos);
            if (pixelPos.x < 0.0 || pixelPos.x >= srcMaxRange || pixelPos.y < 0.0 || pixelPos.y >= srcMaxAzimuth) {
              tileData.tileDataBuffer.setElemDoubleAt(index,tileData.noDataValue);
              continue;
            }
            final int[] subSwathIndex={INVALID_SUB_SWATH_INDEX};
            double v=getPixelValue(pixelPos.y,pixelPos.x,tileData,subSwathIndex);
            if (v != tileData.noDataValue && tileData.applyRadiometricNormalization) {
              if (localIncidenceAngles[1] != SARGeocoding.NonValidIncidenceAngle) {
                final double satelliteHeight=Math.sqrt(sensorPos.x * sensorPos.x + sensorPos.y * sensorPos.y + sensorPos.z * sensorPos.z);
                final double sceneToEarthCentre=Math.sqrt(earthPoint.x * earthPoint.x + earthPoint.y * earthPoint.y + earthPoint.z * earthPoint.z);
                v=calibrator.applyCalibration(v,rangeIndex,azimuthIndex,slantRange,satelliteHeight,sceneToEarthCentre,localIncidenceAngles[1],tileData.bandName,tileData.bandPolar,bandUnit,subSwathIndex);
              }
 else {
                v=tileData.noDataValue;
              }
            }
            tileData.tileDataBuffer.setElemDoubleAt(index,v);
          }
          orthoDataProduced=true;
        }
      }
    }
  }
 catch (  Throwable e) {
    orthoDataProduced=true;
    OperatorUtils.catchOperatorException(getId(),e);
  }
}