Example #1
0
 @Override
 void setInvalidPixelExpression(Band band) {
   if (band.isFlagBand()) {
     band.setNoDataValueUsed(false);
   } else {
     band.setNoDataValueUsed(true);
     band.setNoDataValue(-2);
   }
 }
  @Override
  public void computeTile(Band targetBand, Tile targetTile, ProgressMonitor pm)
      throws OperatorException {

    if (targetBand.isFlagBand()) {
      // no computations
      return;
    }

    final Rectangle rectangle = targetTile.getRectangle();
    final int bigWidth = (int) (scalingFactor * rectangle.getWidth());
    final int bigHeight = (int) (scalingFactor * rectangle.getHeight());
    final int bigX = (int) (scalingFactor * rectangle.getX());
    final int bigY = (int) (scalingFactor * rectangle.getY());
    final Rectangle big = new Rectangle(bigX, bigY, bigWidth, bigHeight);

    pm.beginTask("Processing frame...", rectangle.height);

    try {
      // todo: clean up the tiles which are not finally needed  (depends on how many channels are
      // used)
      final Tile szMerisTile = getSourceTile(synergyProduct.getTiePointGrid("sun_zenith"), big);
      final Tile vzMerisTile = getSourceTile(synergyProduct.getTiePointGrid("view_zenith"), big);
      final Tile saMerisTile = getSourceTile(synergyProduct.getTiePointGrid("sun_azimuth"), big);
      final Tile pressureTile = getSourceTile(synergyProduct.getTiePointGrid("atm_press"), big);

      final Tile seAatsrNadirTile =
          getSourceTile(
              synergyProduct.getBand(
                  "sun_elev_nadir" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + ""),
              big);
      final Tile veAatsrNadirTile =
          getSourceTile(
              synergyProduct.getBand(
                  "view_elev_nadir" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + ""),
              big);
      final Tile saAatsrNadirTile =
          getSourceTile(
              synergyProduct.getBand(
                  "sun_azimuth_nadir" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + ""),
              big);
      final Tile seAatsrFwardTile =
          getSourceTile(
              synergyProduct.getBand(
                  "sun_elev_fward" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + ""),
              big);
      final Tile veAatsrFwardTile =
          getSourceTile(
              synergyProduct.getBand(
                  "view_elev_fward" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + ""),
              big);
      final Tile saAatsrFwardTile =
          getSourceTile(
              synergyProduct.getBand(
                  "sun_azimuth_fward" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + ""),
              big);
      final Tile vaAatsrFwardTile =
          getSourceTile(
              synergyProduct.getBand(
                  "view_azimuth_fward" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + ""),
              big);
      final Tile merisRad13Tile =
          getSourceTile(
              synergyProduct.getBand(
                  "radiance_13" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_MERIS + ""),
              big);
      final Tile merisRad14Tile =
          getSourceTile(
              synergyProduct.getBand(
                  "radiance_14" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_MERIS + ""),
              big);

      final Band reflecNadir16Band =
          synergyProduct.getBand(
              "reflec_nadir_1600" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + "");
      final Tile aatsrReflNadir1600Tile = getSourceTile(reflecNadir16Band, big);
      final Band reflecNadir87Band =
          synergyProduct.getBand(
              "reflec_nadir_0870" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + "");
      final Tile aatsrReflNadir0870Tile = getSourceTile(reflecNadir87Band, big);
      final Band reflecFward16Band =
          synergyProduct.getBand(
              "reflec_fward_1600" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + "");
      final Tile aatsrReflFward1600Tile = getSourceTile(reflecFward16Band, big);
      final Band reflecFward87Band =
          synergyProduct.getBand(
              "reflec_fward_0870" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + "");
      final Tile aatsrReflFward0870Tile = getSourceTile(reflecFward87Band, big);

      final Tile wsTile =
          getSourceTile(glintProduct.getBand(GlintAveOp.RESULT_WINDSPEED_NAME), rectangle);

      // Flags tiles

      final Tile isInvalid = getSourceTile(invalidBand, rectangle);

      for (int iY = rectangle.y; iY < rectangle.y + rectangle.height; iY++) {
        for (int iX = rectangle.x; iX < rectangle.x + rectangle.width; iX++) {

          final int iTarX = (int) (scalingFactor * iX + aveBlock);
          final int iTarY = (int) (scalingFactor * iY + aveBlock);
          checkForCancellation();

          final float aatsrViewElevationNadir = getAvePixel(veAatsrNadirTile, iTarX, iTarY);
          final float aatsrSunElevationNadir = getAvePixel(seAatsrNadirTile, iTarX, iTarY);
          final float aatsrViewElevationFward = getAvePixel(veAatsrFwardTile, iTarX, iTarY);
          final float aatsrSunElevationFward = getAvePixel(seAatsrFwardTile, iTarX, iTarY);

          // just use one windspeed (the 'closer to ECMWF' one from Glint retrieval)
          final float ws = wsTile.getSampleFloat(iX, iY);

          if (isInvalid.getSampleBoolean(iX, iY)
              || ws == SynergyConstants.OUTPUT_WS_BAND_NODATAVALUE) {
            targetTile.setSample(iX, iY, noDataVal);
          } else if (targetBand.getName().equals(SynergyConstants.OUTPUT_AOT_BAND_NAME)
              && (aot550Result[iX][iY] > 0.0
                  || aot550Result[iX][iY] == SynergyConstants.OUTPUT_AOT_BAND_NODATAVALUE)) {
            targetTile.setSample(iX, iY, aot550Result[iX][iY]);
          } else if (targetBand.getName().equals(SynergyConstants.OUTPUT_ANG_BAND_NAME)
              && (angResult[iX][iY] > 0.0
                  || angResult[iX][iY] == SynergyConstants.OUTPUT_ANG_BAND_NODATAVALUE)) {
            targetTile.setSample(iX, iY, angResult[iX][iY]);
          } else if (targetBand.getName().equals(SynergyConstants.OUTPUT_AOTERR_BAND_NAME)
              && (aot550ErrorResult[iX][iY] > 0.0
                  || aot550ErrorResult[iX][iY]
                      == SynergyConstants.OUTPUT_AOTERR_BAND_NODATAVALUE)) {
            targetTile.setSample(iX, iY, aot550ErrorResult[iX][iY]);
          } else if (targetBand.getName().equals(SynergyConstants.OUTPUT_ANGERR_BAND_NAME)
              && (angErrorResult[iX][iY] > 0.0
                  || angErrorResult[iX][iY] == SynergyConstants.OUTPUT_ANGERR_BAND_NODATAVALUE)) {
            targetTile.setSample(iX, iY, aot550ErrorResult[iX][iY]);
          } else if (targetBand.getName().equals(SynergyConstants.OUTPUT_GLINT_BAND_NAME)
              && (glintResult[iX][iY] > 0.0
                  || glintResult[iX][iY] == SynergyConstants.OUTPUT_GLINT_BAND_NODATAVALUE)) {
            targetTile.setSample(iX, iY, glintResult[iX][iY]);
          } else if (targetBand.getName().equals(SynergyConstants.OUTPUT_WS_BAND_NAME)
              && (wsResult[iX][iY] > 0.0
                  || wsResult[iX][iY] == SynergyConstants.OUTPUT_WS_BAND_NODATAVALUE)) {
            targetTile.setSample(iX, iY, wsResult[iX][iY]);
          } else {
            final float merisViewAzimuth = getAvePixel(vaMerisTileComplete, iTarX, iTarY);
            final float merisSunAzimuth = getAvePixel(saMerisTile, iTarX, iTarY);
            final float merisAzimuthDifference =
                GlintPreparation.removeAzimuthDifferenceAmbiguity(
                    merisViewAzimuth, merisSunAzimuth);
            final float merisViewZenith = getAvePixel(vzMerisTile, iTarX, iTarY);
            final float merisSunZenith = getAvePixel(szMerisTile, iTarX, iTarY);
            final float merisRad13 =
                getAvePixel(merisRad13Tile, iTarX, iTarY) / SynergyConstants.MERIS_13_SOLAR_FLUX;
            final float merisRad14 =
                getAvePixel(merisRad14Tile, iTarX, iTarY) / SynergyConstants.MERIS_14_SOLAR_FLUX;
            final double aatsrSeNadir = getAvePixel(seAatsrNadirTile, iTarX, iTarY);
            final double aatsrSeFward = getAvePixel(seAatsrFwardTile, iTarX, iTarY);

            // for RP test data (unit '%'), we need to divide AATSR reflectances by 100.
            // however, the correct AATSR units should be 'dl', as for the Synergy products created
            // in the Synergy module
            float aatsrUnitCorrFactor = 1.0f;
            if (reflecNadir87Band.getUnit().equals("%")) {
              // check for one band should be enough
              aatsrUnitCorrFactor = 100.0f;
            }
            final float aatsrReflNadir87 =
                (float)
                    (getAvePixel(aatsrReflNadir0870Tile, iTarX, iTarY)
                        / (Math.PI
                            * Math.cos(MathUtils.DTOR * (90.0 - aatsrSeNadir))
                            * aatsrUnitCorrFactor));
            final float aatsrReflNadir16 =
                (float)
                    (getAvePixel(aatsrReflNadir1600Tile, iTarX, iTarY)
                        / (Math.PI
                            * Math.cos(MathUtils.DTOR * (90.0 - aatsrSeNadir))
                            * aatsrUnitCorrFactor));
            final float aatsrReflFward87 =
                (float)
                    (getAvePixel(aatsrReflFward0870Tile, iTarX, iTarY)
                        / (Math.PI
                            * Math.cos(MathUtils.DTOR * (90.0 - aatsrSeFward))
                            * aatsrUnitCorrFactor));
            final float aatsrReflFward16 =
                (float)
                    (getAvePixel(aatsrReflFward1600Tile, iTarX, iTarY)
                        / (Math.PI
                            * Math.cos(MathUtils.DTOR * (90.0 - aatsrSeFward))
                            * aatsrUnitCorrFactor));

            final float aatsrViewAzimuthNadir = getAvePixel(vaAatsrNadirTileComplete, iTarX, iTarY);
            final float aatsrSunAzimuthNadir = getAvePixel(saAatsrNadirTile, iTarX, iTarY);
            final float aatsrViewAzimuthFward = vaAatsrFwardTile.getSampleFloat(iTarX, iTarY);
            final float aatsrSunAzimuthFward = saAatsrFwardTile.getSampleFloat(iTarX, iTarY);

            final float aatsrAzimuthDifferenceNadir =
                GlintPreparation.removeAzimuthDifferenceAmbiguity(
                    aatsrViewAzimuthNadir, aatsrSunAzimuthNadir);
            final float aatsrAzimuthDifferenceFward = aatsrViewAzimuthFward - aatsrSunAzimuthFward;
            // negative pressures were stored in LUT to ensure ascending sequence
            final float surfacePressure = -1.0f * getAvePixel(pressureTile, iTarX, iTarY);

            // breadboard begin STEP 1
            final float[] glintArray =
                doSynAOStep1(
                    aatsrViewElevationNadir,
                    aatsrViewElevationFward,
                    aatsrSunElevationNadir,
                    aatsrSunElevationFward,
                    aatsrAzimuthDifferenceNadir,
                    aatsrAzimuthDifferenceFward,
                    merisViewZenith,
                    merisSunZenith,
                    merisAzimuthDifference,
                    surfacePressure,
                    ws);
            glintResult[iX][iY] = glintArray[0];
            wsResult[iX][iY] = ws;
            // breadboard end STEP 1

            // breadboard begin STEP 2
            doSynAOStep2();
            // breadboard end STEP 2

            // breadboard begin STEP 3
            doSynAOStep3(
                iY,
                iX,
                merisRad13,
                merisRad14,
                aatsrReflNadir16,
                aatsrReflNadir87,
                aatsrReflFward16,
                aatsrReflFward87);

            // breadboard end STEP 3

            if (targetBand.getName().equals(SynergyConstants.OUTPUT_AOT_BAND_NAME)) {
              targetTile.setSample(iX, iY, aot550Result[iX][iY]);
            }
            if (targetBand.getName().equals(SynergyConstants.OUTPUT_ANG_BAND_NAME)) {
              targetTile.setSample(iX, iY, angResult[iX][iY]);
            }
            if (targetBand.getName().equals(SynergyConstants.OUTPUT_AOTERR_BAND_NAME)) {
              targetTile.setSample(iX, iY, aot550ErrorResult[iX][iY]);
            }
            if (targetBand.getName().equals(SynergyConstants.OUTPUT_ANGERR_BAND_NAME)) {
              targetTile.setSample(iX, iY, angErrorResult[iX][iY]);
            }
            if (targetBand.getName().equals(SynergyConstants.OUTPUT_GLINT_BAND_NAME)) {
              targetTile.setSample(iX, iY, glintResult[iX][iY]);
            }
            if (targetBand.getName().equals(SynergyConstants.OUTPUT_WS_BAND_NAME)) {
              targetTile.setSample(iX, iY, wsResult[iX][iY]);
            }
          }
          pm.worked(1);
        }
      }
    } catch (Exception e) {
      throw new OperatorException(
          "Failed to process ocean aerosol algorithm:\n" + e.getMessage(), e);
    } finally {
      pm.done();
    }
  }