Program: 175176
Project: 175176
Buggy source:
/** 
 * @see In matlab: reverse geolocation
 */
@Override public double[] pixelFromGeo(final double lon,final double lat) throws GeoLocationException {
  double[] resultReverse=new double[2];
  double[] pXYZ=GeoUtils.convertFromGeoToEarthCentred(lat,lon);
  Double dd2[]=(Double[])orbitInterpolation.getTimeStampInterp().toArray(new Double[0]);
  double[] results=findZeroDoppler(statepVecInterp,pXYZ,ArrayUtils.toPrimitive(dd2));
  double zeroDopplerTime=results[0];
  double srdist=results[1];
  double lNominatore=(zeroDopplerTime - orbitInterpolation.getZeroDopplerTimeFirstRef());
  double lDenom=(orbitInterpolation.getZeroDopplerTimeLastRef() - orbitInterpolation.getZeroDopplerTimeFirstRef());
  double l=(lNominatore / lDenom) * (meta.getNlines() - 1);
  if (meta.getCoordinateConversion() != null && meta.getCoordinateConversion().length > 0) {
    double timeRef=meta.getOrbitStatePosVelox().get(0).timeStampInitSeconds - orbitInterpolation.getSecondsDiffFromRefTime()[0];
    double[] groundToSlantRangePolyTimesSeconds=new double[coordConv.length];
    int index=0;
    for (    S1Metadata.CoordinateConversion cc : coordConv) {
      groundToSlantRangePolyTimesSeconds[index]=cc.groundToSlantRangePolyTimesSeconds - timeRef;
      index++;
    }
    int idx=0;
    if (zeroDopplerTime < groundToSlantRangePolyTimesSeconds[0]) {
      idx=0;
    }
 else     if (zeroDopplerTime > groundToSlantRangePolyTimesSeconds[groundToSlantRangePolyTimesSeconds.length - 1]) {
      idx=groundToSlantRangePolyTimesSeconds.length - 2;
    }
 else {
      for (idx=groundToSlantRangePolyTimesSeconds.length - 1; idx > 0; idx--) {
        if (groundToSlantRangePolyTimesSeconds[idx] < zeroDopplerTime)         break;
      }
      if (idx == groundToSlantRangePolyTimesSeconds.length - 1) {
        idx=idx - 1;
      }
      if (idx == groundToSlantRangePolyTimesSeconds.length) {
        idx=idx - 2;
      }
    }
    double factor1=(groundToSlantRangePolyTimesSeconds[idx + 1] - zeroDopplerTime) / (groundToSlantRangePolyTimesSeconds[idx + 1] - groundToSlantRangePolyTimesSeconds[idx]);
    double factor2=(zeroDopplerTime - groundToSlantRangePolyTimesSeconds[idx]) / (groundToSlantRangePolyTimesSeconds[idx + 1] - groundToSlantRangePolyTimesSeconds[idx]);
    double[] groundToSlantRangeCoefficientsInterp=new double[coordConv[idx].groundToSlantRangeCoefficients.length];
    for (int idCoeff=0; idCoeff < groundToSlantRangeCoefficientsInterp.length; idCoeff++) {
      groundToSlantRangeCoefficientsInterp[idCoeff]=factor1 * coordConv[idx].groundToSlantRangeCoefficients[idCoeff] + factor2 * coordConv[idx + 1].groundToSlantRangeCoefficients[idCoeff];
    }
    double[] slantToGroundRangeCoefficientsInterp=new double[coordConv[idx].slantToGroundRangeCoefficients.length];
    for (int idCoeff=0; idCoeff < slantToGroundRangeCoefficientsInterp.length; idCoeff++) {
      slantToGroundRangeCoefficientsInterp[idCoeff]=factor1 * coordConv[idx].slantToGroundRangeCoefficients[idCoeff] + factor2 * coordConv[idx + 1].slantToGroundRangeCoefficients[idCoeff];
    }
    double newD=0;
    double oldD=0;
    int nCoeffs=groundToSlantRangeCoefficientsInterp.length;
    int[] numCoeffs=new int[nCoeffs];
    int[] numExps=new int[nCoeffs];
    int[] denomCoeffs=new int[nCoeffs];
    int[] denomExps=new int[nCoeffs];
    for (int i=0; i < nCoeffs; i++) {
      numCoeffs[i]=i - 1;
      numExps[i]=i;
      denomCoeffs[i]=i;
      denomExps[i]=i - 1;
    }
    denomExps[0]=0;
    double deltaD=0;
    do {
      double numCoeffsXGround=0;
      double denomCoeffsXGround=0;
      double scalNum=0;
      double scalDen=0;
      for (int i=0; i < groundToSlantRangeCoefficientsInterp.length; i++) {
        double dExp=FastMath.pow(oldD,numExps[i]);
        double denomExp=FastMath.pow(oldD,denomExps[i]);
        numCoeffsXGround=groundToSlantRangeCoefficientsInterp[i] * numCoeffs[i];
        denomCoeffsXGround=groundToSlantRangeCoefficientsInterp[i] * denomCoeffs[i];
        scalNum=scalNum + dExp * numCoeffsXGround;
        scalDen=scalDen + denomExp * denomCoeffsXGround;
      }
      double num=srdist + scalNum;
      newD=num / scalDen;
      deltaD=FastMath.abs(newD - oldD);
      oldD=newD;
    }
 while (deltaD > 1);
    double p=0;
    if (meta.isPixelTimeOrderingAscending()) {
      p=(newD + meta.getGroundRangeOrigin()) / meta.getSamplePixelSpacing();
    }
 else {
      p=meta.getNumberOfSamplesPerLine() - 1 - (newD + meta.getGroundRangeOrigin()) / meta.getSamplePixelSpacing();
    }
    resultReverse[0]=p;
    resultReverse[1]=l;
    logger.debug("String_Node_Str" + l + "String_Node_Str"+ "String_Node_Str"+ p);
  }
  return resultReverse;
}

Fixed version (ground truth):
/** 
 * @see In matlab: reverse geolocation
 * @result r[o]=p r[1]=l
 */
@Override public double[] pixelFromGeo(final double lon,final double lat) throws GeoLocationException {
  double[] resultReverse=new double[2];
  double[] pXYZ=GeoUtils.convertFromGeoToEarthCentred(lat,lon);
  Double dd2[]=(Double[])orbitInterpolation.getTimeStampInterp().toArray(new Double[0]);
  double[] results=findZeroDoppler(statepVecInterp,pXYZ,ArrayUtils.toPrimitive(dd2));
  double zeroDopplerTime=results[0];
  double srdist=results[1];
  double lNominatore=(zeroDopplerTime - orbitInterpolation.getZeroDopplerTimeFirstRef());
  double lDenom=(orbitInterpolation.getZeroDopplerTimeLastRef() - orbitInterpolation.getZeroDopplerTimeFirstRef());
  double l=(lNominatore / lDenom) * (meta.getNlines() - 1);
  if (meta.getCoordinateConversion() != null && meta.getCoordinateConversion().length > 0) {
    double timeRef=meta.getOrbitStatePosVelox().get(0).timeStampInitSeconds - orbitInterpolation.getSecondsDiffFromRefTime()[0];
    double[] groundToSlantRangePolyTimesSeconds=new double[coordConv.length];
    int index=0;
    for (    S1Metadata.CoordinateConversion cc : coordConv) {
      groundToSlantRangePolyTimesSeconds[index]=cc.groundToSlantRangePolyTimesSeconds - timeRef;
      index++;
    }
    int idx=0;
    if (zeroDopplerTime < groundToSlantRangePolyTimesSeconds[0]) {
      idx=0;
    }
 else     if (zeroDopplerTime > groundToSlantRangePolyTimesSeconds[groundToSlantRangePolyTimesSeconds.length - 1]) {
      idx=groundToSlantRangePolyTimesSeconds.length - 2;
    }
 else {
      for (idx=groundToSlantRangePolyTimesSeconds.length - 1; idx > 0; idx--) {
        if (groundToSlantRangePolyTimesSeconds[idx] < zeroDopplerTime)         break;
      }
      if (idx == groundToSlantRangePolyTimesSeconds.length - 1) {
        idx=idx - 1;
      }
      if (idx == groundToSlantRangePolyTimesSeconds.length) {
        idx=idx - 2;
      }
    }
    double factor1=(groundToSlantRangePolyTimesSeconds[idx + 1] - zeroDopplerTime) / (groundToSlantRangePolyTimesSeconds[idx + 1] - groundToSlantRangePolyTimesSeconds[idx]);
    double factor2=(zeroDopplerTime - groundToSlantRangePolyTimesSeconds[idx]) / (groundToSlantRangePolyTimesSeconds[idx + 1] - groundToSlantRangePolyTimesSeconds[idx]);
    double[] groundToSlantRangeCoefficientsInterp=new double[coordConv[idx].groundToSlantRangeCoefficients.length];
    for (int idCoeff=0; idCoeff < groundToSlantRangeCoefficientsInterp.length; idCoeff++) {
      groundToSlantRangeCoefficientsInterp[idCoeff]=factor1 * coordConv[idx].groundToSlantRangeCoefficients[idCoeff] + factor2 * coordConv[idx + 1].groundToSlantRangeCoefficients[idCoeff];
    }
    double[] slantToGroundRangeCoefficientsInterp=new double[coordConv[idx].slantToGroundRangeCoefficients.length];
    for (int idCoeff=0; idCoeff < slantToGroundRangeCoefficientsInterp.length; idCoeff++) {
      slantToGroundRangeCoefficientsInterp[idCoeff]=factor1 * coordConv[idx].slantToGroundRangeCoefficients[idCoeff] + factor2 * coordConv[idx + 1].slantToGroundRangeCoefficients[idCoeff];
    }
    double newD=0;
    double oldD=0;
    int nCoeffs=groundToSlantRangeCoefficientsInterp.length;
    int[] numCoeffs=new int[nCoeffs];
    int[] numExps=new int[nCoeffs];
    int[] denomCoeffs=new int[nCoeffs];
    int[] denomExps=new int[nCoeffs];
    for (int i=0; i < nCoeffs; i++) {
      numCoeffs[i]=i - 1;
      numExps[i]=i;
      denomCoeffs[i]=i;
      denomExps[i]=i - 1;
    }
    denomExps[0]=0;
    double deltaD=0;
    do {
      double numCoeffsXGround=0;
      double denomCoeffsXGround=0;
      double scalNum=0;
      double scalDen=0;
      for (int i=0; i < groundToSlantRangeCoefficientsInterp.length; i++) {
        double dExp=FastMath.pow(oldD,numExps[i]);
        double denomExp=FastMath.pow(oldD,denomExps[i]);
        numCoeffsXGround=groundToSlantRangeCoefficientsInterp[i] * numCoeffs[i];
        denomCoeffsXGround=groundToSlantRangeCoefficientsInterp[i] * denomCoeffs[i];
        scalNum=scalNum + dExp * numCoeffsXGround;
        scalDen=scalDen + denomExp * denomCoeffsXGround;
      }
      double num=srdist + scalNum;
      newD=num / scalDen;
      deltaD=FastMath.abs(newD - oldD);
      oldD=newD;
    }
 while (deltaD > 1);
    double p=0;
    if (meta.isPixelTimeOrderingAscending()) {
      p=(newD + meta.getGroundRangeOrigin()) / meta.getSamplePixelSpacing();
    }
 else {
      p=meta.getNumberOfSamplesPerLine() - 1 - (newD + meta.getGroundRangeOrigin()) / meta.getSamplePixelSpacing();
    }
    resultReverse[0]=p;
    resultReverse[1]=l;
    logger.debug("String_Node_Str" + l + "String_Node_Str"+ "String_Node_Str"+ p);
  }
  return resultReverse;
}