@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(); } }