/** * This method copies selected tie point grids to a rescaled target product * * @param sourceProduct - the source product * @param targetProduct - the target product * @param xScalingFactor - scaling factor in x-direction * @param yScalingFactor - scaling factor in y-direction */ public static void copyRescaledTiePointGrids( Product sourceProduct, Product targetProduct, int xScalingFactor, int yScalingFactor) { // Add tie point grids for sun/view zenith/azimuths. Get data from AATSR bands. final Band szaBand = sourceProduct.getBand("sun_elev_nadir_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band saaBand = sourceProduct.getBand("sun_azimuth_nadir_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band latitudeBand = sourceProduct.getBand("latitude_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band longitudeBand = sourceProduct.getBand("longitude_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band altitudeBand = sourceProduct.getBand("altitude_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final TiePointGrid szaTpg = getRescaledTpgFromBand(szaBand, xScalingFactor, yScalingFactor); targetProduct.addTiePointGrid(szaTpg); final TiePointGrid saaTpg = getRescaledTpgFromBand(saaBand, xScalingFactor, yScalingFactor); targetProduct.addTiePointGrid(saaTpg); final TiePointGrid latTpg = getRescaledTpgFromBand(latitudeBand, xScalingFactor, yScalingFactor); targetProduct.addTiePointGrid(latTpg); final TiePointGrid lonTpg = getRescaledTpgFromBand(longitudeBand, xScalingFactor, yScalingFactor); targetProduct.addTiePointGrid(lonTpg); final TiePointGrid altTpg = getRescaledTpgFromBand(altitudeBand, xScalingFactor, yScalingFactor); targetProduct.addTiePointGrid(altTpg); }
/** * This method copies selected tie point grids to a downscaled target product * * @param sourceProduct - the source product * @param targetProduct - the target product * @param scalingFactor - factor of downscaling */ public static void copyDownscaledTiePointGrids( Product sourceProduct, Product targetProduct, float scalingFactor) { // Add tie point grids for sun/view zenith/azimuths. Get data from AATSR bands. final Band szaBand = sourceProduct.getBand("sun_elev_nadir_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band saaBand = sourceProduct.getBand("sun_azimuth_nadir_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band latitudeBand = sourceProduct.getBand("latitude_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band longitudeBand = sourceProduct.getBand("longitude_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band altitudeBand = sourceProduct.getBand("altitude_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR); final Band szaDownscaledBand = downscaleBand(szaBand, scalingFactor); final Band saaDownscaledBand = downscaleBand(saaBand, scalingFactor); final Band latitudeDownscaledBand = downscaleBand(latitudeBand, scalingFactor); final Band longitudeDownscaledBand = downscaleBand(longitudeBand, scalingFactor); final Band altitudeDownscaledBand = downscaleBand(altitudeBand, scalingFactor); addTpg(targetProduct, szaDownscaledBand, "sun_zenith"); addTpg(targetProduct, saaDownscaledBand, "sun_azimuth"); // unscaled latitude/longitude TPGs were added by 'copyGeoCoding', we have to remove them before // downscaling targetProduct.removeTiePointGrid(targetProduct.getTiePointGrid("latitude")); targetProduct.removeTiePointGrid(targetProduct.getTiePointGrid("longitude")); addTpg(targetProduct, latitudeDownscaledBand, "latitude"); addTpg(targetProduct, longitudeDownscaledBand, "longitude"); addTpg(targetProduct, altitudeDownscaledBand, "altitude"); }
/** * @param inputProduct * @param instr * @param bandList */ public static void getGeometryBandList( Product inputProduct, String instr, ArrayList<RasterDataNode> bandList) { final String[] viewArr = {"nadir", "fward"}; int nView = viewArr.length; final String[] bodyArr = {"sun", "view"}; final String[] angArr = {"elev", "azimuth"}; String bandName; if (instr.equals("MERIS")) { angArr[0] = "zenith"; nView = 1; } for (int iView = 0; iView < nView; iView++) { for (String body : bodyArr) { for (String ang : angArr) { if (instr.equals("AATSR")) { bandName = body + "_" + ang + "_" + viewArr[iView] + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR; bandList.add(inputProduct.getBand(bandName)); } else { bandName = body + "_" + ang; bandList.add(inputProduct.getRasterDataNode(bandName)); } } } } }
@Override public void configureSourceSamples( SampleConfigurer sampleConfigurer, Product sourceProduct, String spectralBandPrefix) { for (int i = 0; i < MODIS_L1B_NUM_SPECTRAL_BANDS; i++) { if (sourceProduct.containsBand(MODIS_L1B_SPECTRAL_BAND_NAMES[i])) { sampleConfigurer.defineSample(i, MODIS_L1B_SPECTRAL_BAND_NAMES[i], sourceProduct); } else { sampleConfigurer.defineSample( i, MODIS_L1B_SPECTRAL_BAND_NAMES[i].replace(".", "_"), sourceProduct); } } for (int i = 0; i < MODIS_L1B_NUM_EMISSIVE_BANDS; i++) { if (sourceProduct.containsBand(MODIS_L1B_EMISSIVE_BAND_NAMES[i])) { sampleConfigurer.defineSample( OccciConstants.MODIS_SRC_RAD_OFFSET + i, MODIS_L1B_EMISSIVE_BAND_NAMES[i], sourceProduct); } else { final String newEmissiveBandName = MODIS_L1B_EMISSIVE_BAND_NAMES[i].replace(".", "_"); final Band emissiveBand = sourceProduct.getBand(newEmissiveBandName); emissiveBand.setScalingFactor( 1.0); // todo: we do this to come back to counts with SeaDAS reader, // as the NN was also trained with counts emissiveBand.setScalingOffset(0.0); sampleConfigurer.defineSample( OccciConstants.MODIS_SRC_RAD_OFFSET + i, newEmissiveBandName, sourceProduct); } } }
public void testViewMode() { MaskTableModel maskTableModel = new MaskTableModel(false); assertEquals(false, maskTableModel.isInManagmentMode()); assertEquals(4, maskTableModel.getColumnCount()); assertEquals("Name", maskTableModel.getColumnName(0)); assertEquals("Colour", maskTableModel.getColumnName(1)); assertEquals("Transparency", maskTableModel.getColumnName(2)); assertEquals("Description", maskTableModel.getColumnName(3)); assertEquals(0, maskTableModel.getRowCount()); Product product = MaskFormTest.createTestProduct(); maskTableModel.setProduct(product, null); assertEquals(false, maskTableModel.isInManagmentMode()); assertEquals(4, maskTableModel.getColumnCount()); assertEquals("Name", maskTableModel.getColumnName(0)); assertEquals("Colour", maskTableModel.getColumnName(1)); assertEquals("Transparency", maskTableModel.getColumnName(2)); assertEquals("Description", maskTableModel.getColumnName(3)); assertEquals(10, maskTableModel.getRowCount()); maskTableModel.setProduct(product, product.getBand("C")); assertEquals(false, maskTableModel.isInManagmentMode()); assertEquals(5, maskTableModel.getColumnCount()); assertEquals("Visibility", maskTableModel.getColumnName(0)); assertEquals("Name", maskTableModel.getColumnName(1)); assertEquals("Colour", maskTableModel.getColumnName(2)); assertEquals("Transparency", maskTableModel.getColumnName(3)); assertEquals("Description", maskTableModel.getColumnName(4)); assertEquals(10, maskTableModel.getRowCount()); }
private void createTargetProduct() { // construct target product targetProduct = new Product( PRODUCT_NAME, sourceProduct.getProductType(), sourceProduct.getSceneRasterWidth(), sourceProduct.getSceneRasterHeight()); OperatorUtils.copyProductNodes(sourceProduct, targetProduct); for (final Band band : targetProduct.getBands()) { targetProduct.removeBand(band); } for (String key : targetMap.keySet()) { String bandName = targetMap.get(key).targetBandName_I; targetProduct.addBand(bandName, ProductData.TYPE_FLOAT32); targetProduct.getBand(bandName).setUnit(Unit.METERS); } // targetProduct.setPreferredTileSize(1,1); }
static boolean setFlagCodingsAndBitmaskDefs(final Product product) { final FlagCoding flagCoding = new FlagCoding("GLOBCOLOUR"); for (Flags flag : Flags.values()) { flagCoding.addFlag(flag.name(), flag.getMask(), flag.getDescription()); } boolean codingAdded = false; for (final String name : product.getBandNames()) { if (name.endsWith("flags")) { final Band band = product.getBand(name); if (band == null || band.isFloatingPointType() || band.getFlagCoding() != null) { continue; } if (!product.getFlagCodingGroup().contains(flagCoding.getName())) { product.getFlagCodingGroup().add(flagCoding); } band.setSampleCoding(flagCoding); addBitmaskDefinitions(product, name); codingAdded = true; } } return codingAdded; }
// Creates the appropriate <code>Product</code> for the current request and assembles a list of // <code>RsBands</code> // to be processed. This method does NOT load the tie point ADS because these are product // specific. private void loadInputProduct() throws IOException, ProcessorException { Request request = getRequest(); Band band; Parameter bandParam; String[] bandNames; // clear vector of bands // --------------------- _inputBandList.clear(); // only the first product - there might be more but these will be ignored // ---------------------------------------------------------------------- _inputProduct = loadInputProduct(0); // check what product type the input is and load the appropriate tie point ADS // --------------------------------------------------------------------------- _sensorType = SmacUtils.getSensorType(_inputProduct.getProductType()); if (ObjectUtils.equalObjects(_sensorType, SensorCoefficientManager.MERIS_NAME)) { loadMerisBitmaskExpression(); loadMERIS_ADS(_inputProduct); } else if (ObjectUtils.equalObjects(_sensorType, SensorCoefficientManager.AATSR_NAME)) { loadAatsrBitmaskExpression(); loadAATSR_ADS(_inputProduct); _useMerisADS = false; // then we must set this to false anyway } else { throw new ProcessorException(SmacConstants.LOG_MSG_UNSUPPORTED_SENSOR); } // set up the bands we need for this request // ----------------------------------------- bandParam = request.getParameter(SmacConstants.BANDS_PARAM_NAME); checkParamNotNull(bandParam, "bands"); bandNames = (String[]) bandParam.getValue(); if ((bandNames == null) || (bandNames.length < 1)) { throw new ProcessorException(SmacConstants.LOG_MSG_NO_INPUT_BANDS); } for (String bandName : bandNames) { band = _inputProduct.getBand(bandName); if (band == null) { _logger.warning( "The requested band '" + bandName + "' is not contained in the input product!"); } else { if (band.getSpectralBandIndex() != -1) { _inputBandList.add(band); } else { _logger.warning( "The requested band '" + bandName + "' is not a spectral band! It is excluded from processing"); } } } }
@Override public void initialize() throws OperatorException { final Band blueBand = sourceProduct.getBand(Landsat8Constants.LANDSAT8_BLUE_BAND_NAME); final Band cirrusBand = sourceProduct.getBand(Landsat8Constants.LANDSAT8_CIRRUS_BAND_NAME); final Band aerosolBand = sourceProduct.getBand(Landsat8Constants.LANDSAT8_COASTAL_AEROSOL_BAND_NAME); final Band panBand = sourceProduct.getBand(Landsat8Constants.LANDSAT8_PANCHROMATIC_BAND_NAME); // MPa: try with clost band: // get clost image: blue * aerosol * pan * cirrus RenderedImage blueImage = blueBand.getGeophysicalImage(); RenderedImage aerosolImage = aerosolBand.getGeophysicalImage(); RenderedOp blueAerosolImage = MultiplyDescriptor.create(blueImage, aerosolImage, null); RenderedImage panImage = panBand.getGeophysicalImage(); RenderedOp blueAerosolPanImage = MultiplyDescriptor.create(blueAerosolImage, panImage, null); RenderedImage cirrusImage = cirrusBand.getGeophysicalImage(); RenderedOp blueAerosolPanCirrusImage = MultiplyDescriptor.create(blueAerosolPanImage, cirrusImage, null); final Product clostProduct = createClostProduct(blueAerosolPanCirrusImage); setTargetProduct(clostProduct); }
protected Product createProduct( GCTileFile refGcFile, String prodName, String prodType, int width, int height) throws IOException { final Product product = new Product(prodName, prodType, width, height); product.setFileLocation(new File(refGcFile.getFilePath())); product.setStartTime(refGcFile.getStartDate()); product.setEndTime(refGcFile.getEndDate()); addGeoCoding(product); addBands(product, refGcFile); addIndexCodingAndBitmasks(product.getBand("SM")); refGcFile.readMetadata(product.getMetadataRoot()); return product; }
public static void getSpectralBandList( Product inputProduct, String bandNamePrefix, String bandNameSuffix, int[] excludeBandIndices, ArrayList<Band> bandList) { final String[] bandNames = inputProduct.getBandNames(); Comparator<Band> byWavelength = new WavelengthComparator(); for (String name : bandNames) { if (name.startsWith(bandNamePrefix) && name.endsWith(bandNameSuffix)) { boolean exclude = false; if (excludeBandIndices != null) { for (int i : excludeBandIndices) { exclude = exclude || (i == inputProduct.getBand(name).getSpectralBandIndex() + 1); } } if (!exclude) { bandList.add(inputProduct.getBand(name)); } } } Collections.sort(bandList, byWavelength); }
/** * Initializes this operator and sets the one and only target product. * * <p>The target product can be either defined by a field of type {@link * org.esa.beam.framework.datamodel.Product} annotated with the {@link * org.esa.beam.framework.gpf.annotations.TargetProduct TargetProduct} annotation or by calling * {@link #setTargetProduct} method. * * <p>The framework calls this method after it has created this operator. Any client code that * must be performed before computation of tile data should be placed here. * * @throws org.esa.beam.framework.gpf.OperatorException If an error occurs during operator * initialisation. * @see #getTargetProduct() */ @Override public void initialize() throws OperatorException { productName = sourceProduct.getName() + "_vgtComp"; targetProduct = new Product( productName, "VGT_COMP", sourceProduct.getSceneRasterWidth(), sourceProduct.getSceneRasterHeight()); // Some target products may require more aid from ProductUtils methods... ProductUtils.copyGeoCoding(sourceProduct, targetProduct); sourceBandS1_B0 = sourceProduct.getBand(sourceBandNameS1_B0); sourceBandS1_B2 = sourceProduct.getBand(sourceBandNameS1_B2); sourceBandS1_B3 = sourceProduct.getBand(sourceBandNameS1_B3); sourceBandS1_MIR = sourceProduct.getBand(sourceBandNameS1_MIR); sourceBandS1_SM = sourceProduct.getBand(sourceBandNameS1_SM); sourceBandP_B0 = sourceProduct.getBand(sourceBandNameP_B0); sourceBandP_B2 = sourceProduct.getBand(sourceBandNameP_B2); sourceBandP_B3 = sourceProduct.getBand(sourceBandNameP_B3); sourceBandP_MIR = sourceProduct.getBand(sourceBandNameP_MIR); sourceBandP_SM = sourceProduct.getBand(sourceBandNameP_SM); sourceBandP_Idepix = sourceProduct.getBand(sourceBandNameP_Idepix); targetDifferenceBandB0 = targetProduct.addBand(targetDifferenceBandNameB0, ProductData.TYPE_FLOAT32); targetDifferenceBandB2 = targetProduct.addBand(targetDifferenceBandNameB2, ProductData.TYPE_FLOAT32); targetDifferenceBandB3 = targetProduct.addBand(targetDifferenceBandNameB3, ProductData.TYPE_FLOAT32); targetDifferenceBandMIR = targetProduct.addBand(targetDifferenceBandNameMIR, ProductData.TYPE_FLOAT32); targetProduct.setPreferredTileSize( new Dimension(targetProduct.getSceneRasterWidth(), targetProduct.getSceneRasterHeight())); }
protected void addFlagsAndMasks(Product product) { Band QFBand = product.getBand("l2_flags"); if (QFBand != null) { FlagCoding flagCoding = new FlagCoding("L2Flags"); flagCoding.addFlag("ATMFAIL", 0x01, "Atmospheric correction failure"); flagCoding.addFlag("LAND", 0x02, "Land"); flagCoding.addFlag("PRODWARN", 0x04, "One (or more) product algorithms generated a warning"); flagCoding.addFlag("HIGLINT", 0x08, "High glint determined"); flagCoding.addFlag("HILT", 0x10, "High (or saturating) TOA radiance"); flagCoding.addFlag("HISATZEN", 0x20, "Large satellite zenith angle"); flagCoding.addFlag("COASTZ", 0x40, "Shallow water (<30m)"); flagCoding.addFlag("SPARE8", 0x80, "Unused"); flagCoding.addFlag("STRAYLIGHT", 0x100, "Straylight determined"); flagCoding.addFlag("CLDICE", 0x200, "Cloud/Ice determined"); flagCoding.addFlag("COCCOLITH", 0x400, "Coccolithophores detected"); flagCoding.addFlag("TURBIDW", 0x800, "Turbid water determined"); flagCoding.addFlag("HISOLZEN", 0x1000, "High solar zenith angle"); flagCoding.addFlag("SPARE14", 0x2000, "Unused"); flagCoding.addFlag("LOWLW", 0x4000, "Low Lw @ 555nm (possible cloud shadow)"); flagCoding.addFlag("CHLFAIL", 0x8000, "Chlorophyll algorithm failure"); flagCoding.addFlag("NAVWARN", 0x10000, "Navigation suspect"); flagCoding.addFlag("ABSAER", 0x20000, "Absorbing Aerosols determined"); flagCoding.addFlag("SPARE19", 0x40000, "Unused"); flagCoding.addFlag("MAXAERITER", 0x80000, "Maximum iterations reached for NIR iteration"); flagCoding.addFlag("MODGLINT", 0x100000, "Moderate glint determined"); flagCoding.addFlag("CHLWARN", 0x200000, "Chlorophyll out-of-bounds (<0.01 or >100 mg m^-3)"); flagCoding.addFlag( "ATMWARN", 0x400000, "Atmospheric correction warning; Epsilon out-of-bounds"); flagCoding.addFlag("SPARE24", 0x800000, "Unused"); flagCoding.addFlag("SEAICE", 0x1000000, "Sea ice determined"); flagCoding.addFlag("NAVFAIL", 0x2000000, "Navigation failure"); flagCoding.addFlag("FILTER", 0x4000000, "Insufficient data for smoothing filter"); flagCoding.addFlag("SSTWARN", 0x8000000, "Sea surface temperature suspect"); flagCoding.addFlag("SSTFAIL", 0x10000000, "Sea surface temperature algorithm failure"); flagCoding.addFlag("HIPOL", 0x20000000, "High degree of polariztion determined"); flagCoding.addFlag( "PRODFAIL", 0x40000000, "One (or more) product algorithms produced a failure"); flagCoding.addFlag("SPARE32", 0x80000000, "Unused"); product.getFlagCodingGroup().add(flagCoding); QFBand.setSampleCoding(flagCoding); product .getMaskGroup() .add( Mask.BandMathsType.create( "ATMFAIL", "Atmospheric correction failure", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.ATMFAIL", FailRed, 0.0)); product .getMaskGroup() .add( Mask.BandMathsType.create( "LAND", "Land", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.LAND", LandBrown, 0.0)); product .getMaskGroup() .add( Mask.BandMathsType.create( "PRODWARN", "One (or more) product algorithms generated a warning", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.PRODWARN", DeepBlue, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "HILT", "High (or saturating) TOA radiance", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.HILT", Color.GRAY, 0.2)); product .getMaskGroup() .add( Mask.BandMathsType.create( "HIGLINT", "High glint determined", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.HIGLINT", BrightPink, 0.2)); product .getMaskGroup() .add( Mask.BandMathsType.create( "HISATZEN", "Large satellite zenith angle", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.HISATZEN", LightCyan, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "COASTZ", "Shallow water (<30m)", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.COASTZ", BurntUmber, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "STRAYLIGHT", "Straylight determined", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.STRAYLIGHT", Color.YELLOW, 0.2)); product .getMaskGroup() .add( Mask.BandMathsType.create( "CLDICE", "Cloud/Ice determined", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.CLDICE", Color.WHITE, 0.0)); product .getMaskGroup() .add( Mask.BandMathsType.create( "COCCOLITH", "Coccolithophores detected", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.COCCOLITH", Color.CYAN, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "TURBIDW", "Turbid water determined", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.TURBIDW", LightBrown, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "HISOLZEN", "High solar zenith angle", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.HISOLZEN", Purple, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "LOWLW", "Low Lw @ 555nm (possible cloud shadow)", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.LOWLW", Cornflower, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "CHLFAIL", "Chlorophyll algorithm failure", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.CHLFAIL", FailRed, 0.0)); product .getMaskGroup() .add( Mask.BandMathsType.create( "NAVWARN", "Navigation suspect", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.NAVWARN", Color.MAGENTA, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "ABSAER", "Absorbing Aerosols determined", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.ABSAER", Color.ORANGE, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "MAXAERITER", "Maximum iterations reached for NIR correction", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.MAXAERITER", MediumGray, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "MODGLINT", "Moderate glint determined", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.MODGLINT", LightPurple, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "CHLWARN", "Chlorophyll out-of-bounds (<0.01 or >100 mg m^-3)", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.CHLWARN", Color.LIGHT_GRAY, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "ATMWARN", "Atmospheric correction warning; Epsilon out-of-bounds", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.ATMWARN", Color.MAGENTA, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "SEAICE", "Sea ice determined", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.SEAICE", Color.DARK_GRAY, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "NAVFAIL", "Navigation failure", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.NAVFAIL", FailRed, 0.0)); product .getMaskGroup() .add( Mask.BandMathsType.create( "FILTER", "Insufficient data for smoothing filter", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.FILTER", Color.LIGHT_GRAY, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "SSTWARN", "Sea surface temperature suspect", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.SSTWARN", Color.MAGENTA, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "SSTFAIL", "Sea surface temperature algorithm failure", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.SSTFAIL", FailRed, 0.1)); product .getMaskGroup() .add( Mask.BandMathsType.create( "HIPOL", "High degree of polariztion determined", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.HIPOL", Color.PINK, 0.5)); product .getMaskGroup() .add( Mask.BandMathsType.create( "PRODFAIL", "One (or more) product algorithms produced a failure", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l2_flags.PRODFAIL", FailRed, 0.1)); } Band QFBandSST = product.getBand("qual_sst"); if (QFBandSST != null) { // FlagCoding flagCoding = new FlagCoding("SSTFlags"); // product.getFlagCodingGroup().add(flagCoding); // // QFBandSST.setSampleCoding(flagCoding); product .getMaskGroup() .add( Mask.BandMathsType.create( "Best", "Highest quality SST retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 0", SeadasFileReader.Cornflower, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Good", "Good quality SST retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 1", SeadasFileReader.LightPurple, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Questionable", "Questionable quality SST retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 2", SeadasFileReader.BurntUmber, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Bad", "Bad quality SST retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 3", SeadasFileReader.FailRed, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "No SST Retrieval", "No SST retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 4", SeadasFileReader.FailRed, 0.6)); } Band QFBandSST4 = product.getBand("qual_sst4"); if (QFBandSST4 != null) { // FlagCoding flagCoding = new FlagCoding("SST4Flags"); // product.getFlagCodingGroup().add(flagCoding); // QFBandSST4.setSampleCoding(flagCoding); product .getMaskGroup() .add( Mask.BandMathsType.create( "Best", "Highest quality SST4 retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 0", SeadasFileReader.Cornflower, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Good", "Good quality SST4 retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 1", SeadasFileReader.LightPurple, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Questionable", "Questionable quality SST4 retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 2", SeadasFileReader.BurntUmber, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Bad", "Bad quality SST4 retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 3", SeadasFileReader.FailRed, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "No SST Retrieval", "No SST retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 4", SeadasFileReader.FailRed, 0.6)); } }
@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(); } }
@Override protected void addFlagsAndMasks(Product product) { Band QFBand = product.getBand("l3m_qual"); if (QFBand != null) { FlagCoding flagCoding = new FlagCoding("SST_Quality"); flagCoding.addFlag("Best", 0x00, "Highest quality retrieval"); flagCoding.addFlag("Good", 0x01, "Good quality retrieval"); flagCoding.addFlag("Questionable", 0x02, "Questionable quality retrieval"); flagCoding.addFlag("Bad", 0x03, "Bad quality retrieval"); product.getFlagCodingGroup().add(flagCoding); QFBand.setSampleCoding(flagCoding); product .getMaskGroup() .add( Mask.BandMathsType.create( "Best", "Highest quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l3m_qual == 0", SeadasFileReader.Cornflower, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Good", "Good quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l3m_qual == 1", SeadasFileReader.LightPurple, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Questionable", "Questionable quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l3m_qual == 2", SeadasFileReader.BurntUmber, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Bad", "Bad quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "l3m_qual == 3", SeadasFileReader.FailRed, 0.6)); } QFBand = product.getBand("qual_sst"); if (QFBand != null) { FlagCoding flagCoding = new FlagCoding("SST_Quality"); flagCoding.addFlag("Best", 0x00, "Highest quality retrieval"); flagCoding.addFlag("Good", 0x01, "Good quality retrieval"); flagCoding.addFlag("Questionable", 0x02, "Questionable quality retrieval"); flagCoding.addFlag("Bad", 0x03, "Bad quality retrieval"); product.getFlagCodingGroup().add(flagCoding); QFBand.setSampleCoding(flagCoding); product .getMaskGroup() .add( Mask.BandMathsType.create( "Best", "Highest quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 0", SeadasFileReader.Cornflower, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Good", "Good quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 1", SeadasFileReader.LightPurple, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Questionable", "Questionable quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 2", SeadasFileReader.BurntUmber, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Bad", "Bad quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == 3", SeadasFileReader.FailRed, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "No Data", "No data retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst == -1", SeadasFileReader.MediumGray, 0.6)); } QFBand = product.getBand("qual_sst4"); if (QFBand != null) { FlagCoding flagCoding = new FlagCoding("SST_Quality"); flagCoding.addFlag("Best", 0x00, "Highest quality retrieval"); flagCoding.addFlag("Good", 0x01, "Good quality retrieval"); flagCoding.addFlag("Questionable", 0x02, "Questionable quality retrieval"); flagCoding.addFlag("Bad", 0x03, "Bad quality retrieval"); product.getFlagCodingGroup().add(flagCoding); QFBand.setSampleCoding(flagCoding); product .getMaskGroup() .add( Mask.BandMathsType.create( "Best", "Highest quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 0", SeadasFileReader.Cornflower, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Good", "Good quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 1", SeadasFileReader.LightPurple, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Questionable", "Questionable quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 2", SeadasFileReader.BurntUmber, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "Bad", "Bad quality retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == 3", SeadasFileReader.FailRed, 0.6)); product .getMaskGroup() .add( Mask.BandMathsType.create( "No Data", "No data retrieval", product.getSceneRasterWidth(), product.getSceneRasterHeight(), "qual_sst4 == -1", SeadasFileReader.MediumGray, 0.6)); } }
// Processes a single AATSR band. private void processAatsrBand(Band band, ProgressMonitor pm) throws IOException { // load appropriate Sensor coefficientFile and init algorithm // ---------------------------------------------------------- if (!loadBandCoefficients(band)) { _logger.severe( SmacConstants.LOG_MSG_COEFF_NOT_FOUND_1 + band.getName() + SmacConstants.LOG_MSG_COEFF_NOT_FOUND_2); setCurrentStatus(ProcessorConstants.STATUS_FAILED); return; } _logger.info( SmacConstants.LOG_MSG_GENERATING_PIXEL_1 + band.getName() + SmacConstants.LOG_MSG_GENERATING_PIXEL_2); // initialize vectors and other data // --------------------------------- int width = band.getSceneRasterWidth(); int height = band.getSceneRasterHeight(); Band outBand = _outputProduct.getBand(band.getName()); boolean isForwardBand = checkForAATSRForwardBand(band); float[] sza = new float[width]; float[] saa = new float[width]; float[] vza = new float[width]; float[] vaa = new float[width]; float[] taup550 = new float[width]; float[] uh2o = new float[width]; float[] uo3 = new float[width]; float[] press = new float[width]; boolean[] process = new boolean[width]; float[] toa = new float[width]; float[] toa_corr = new float[width]; TiePointGrid szaBand; TiePointGrid saaBand; TiePointGrid vzaBand; TiePointGrid vaaBand; Term bitMask; // set the tie point bands according to input band view // ---------------------------------------------------- if (isForwardBand) { szaBand = _szaFwdBand; saaBand = _saaFwdBand; vzaBand = _vzaFwdBand; vaaBand = _vaaFwdBand; bitMask = _bitMaskTermForward; } else { szaBand = _szaBand; saaBand = _saaBand; vzaBand = _vzaBand; vaaBand = _vaaBand; bitMask = _bitMaskTerm; } // initialize vectors // ------------------ for (int x = 0; x < width; x++) { taup550[x] = _tau_aero_550; uh2o[x] = _u_h2o; uo3[x] = _u_o3; press[x] = _surf_press; process[x] = true; } // progress init pm.beginTask( SmacConstants.LOG_MSG_GENERATING_PIXEL_1 + band.getName() + SmacConstants.LOG_MSG_GENERATING_PIXEL_2, height * 6); try { // loop over all scanlines for (int y = 0; y < band.getSceneRasterHeight(); y++) { // read scanline band.readPixels(0, y, width, 1, toa, SubProgressMonitor.create(pm, 1)); szaBand.readPixels(0, y, width, 1, sza, SubProgressMonitor.create(pm, 1)); saaBand.readPixels(0, y, width, 1, saa, SubProgressMonitor.create(pm, 1)); vzaBand.readPixels(0, y, width, 1, vza, SubProgressMonitor.create(pm, 1)); vaaBand.readPixels(0, y, width, 1, vaa, SubProgressMonitor.create(pm, 1)); // scale sun and view elevation to zenith angles sza = RsMathUtils.elevationToZenith(sza, sza); vza = RsMathUtils.elevationToZenith(vza, sza); // forEachPixel bitmask if (bitMask != null) { _inputProduct.readBitmask(0, y, width, 1, bitMask, process, ProgressMonitor.NULL); } // process scanline toa_corr = _algorithm.run( sza, saa, vza, vaa, taup550, uh2o, uo3, press, process, _invalidPixel, toa, toa_corr); // write scanline outBand.writePixels(0, y, width, 1, toa_corr, ProgressMonitor.NULL); // update progress pm.worked(1); if (pm.isCanceled()) { _logger.warning(ProcessorConstants.LOG_MSG_PROC_CANCELED); setCurrentStatus(ProcessorConstants.STATUS_ABORTED); return; } } } finally { pm.done(); } _logger.info(ProcessorConstants.LOG_MSG_PROC_SUCCESS); }
// Processes a single band MERIS data using the MERIS ADS. private void processMerisBandWithADS(Band band, ProgressMonitor pm) throws IOException { // load appropriate Sensor coefficientFile and init algorithm // ---------------------------------------------------------- if (!loadBandCoefficients(band)) { _logger.severe( SmacConstants.LOG_MSG_COEFF_NOT_FOUND_1 + band.getName() + SmacConstants.LOG_MSG_COEFF_NOT_FOUND_2); /*I18N*/ setCurrentStatus(ProcessorConstants.STATUS_FAILED); return; } _logger.info( SmacConstants.LOG_MSG_GENERATING_PIXEL_1 + band.getName() + SmacConstants.LOG_MSG_GENERATING_PIXEL_2); /*I18N*/ // initialize vectors and other data // --------------------------------- int width = band.getSceneRasterWidth(); int height = band.getSceneRasterHeight(); Band outBand = _outputProduct.getBand(convertMerisBandName(band)); float[] sza = new float[width]; float[] saa = new float[width]; float[] vza = new float[width]; float[] vaa = new float[width]; float[] taup550 = new float[width]; float[] uh2o = new float[width]; float[] uo3 = new float[width]; float[] press = new float[width]; float[] elev = new float[width]; boolean[] process = new boolean[width]; float[] toa = new float[width]; float[] toa_corr = new float[width]; // set up vector - this parameter is constant for the request for (int x = 0; x < width; x++) { taup550[x] = _tau_aero_550; process[x] = true; } // progress bar init // ----------------- pm.beginTask( SmacConstants.LOG_MSG_GENERATING_PIXEL_1 + band.getName() + SmacConstants.LOG_MSG_GENERATING_PIXEL_2, height * 10); try { // loop over all scanlines // ----------------------- for (int y = 0; y < height; y++) { // read scanline // ------------- band.readPixels(0, y, width, 1, toa, SubProgressMonitor.create(pm, 1)); _szaBand.readPixels(0, y, width, 1, sza, SubProgressMonitor.create(pm, 1)); _saaBand.readPixels(0, y, width, 1, saa, SubProgressMonitor.create(pm, 1)); _vzaBand.readPixels(0, y, width, 1, vza, SubProgressMonitor.create(pm, 1)); _vaaBand.readPixels(0, y, width, 1, vaa, SubProgressMonitor.create(pm, 1)); _wvBand.readPixels(0, y, width, 1, uh2o, SubProgressMonitor.create(pm, 1)); _o3Band.readPixels(0, y, width, 1, uo3, SubProgressMonitor.create(pm, 1)); _pressBand.readPixels(0, y, width, 1, press, SubProgressMonitor.create(pm, 1)); _elevBand.readPixels(0, y, width, 1, elev, SubProgressMonitor.create(pm, 1)); // scale radiance to reflectance // ------------------------------- toa = RsMathUtils.radianceToReflectance(toa, sza, band.getSolarFlux(), toa); // correct pressure due to elevation // --------------------------------- press = RsMathUtils.simpleBarometric(press, elev, press); // scale DU to cm * atm // ---------------------- uo3 = dobsonToCmAtm(uo3); // scale relative humidity to g/cm^2 // ----------------------------------- uh2o = relativeHumidityTogcm2(uh2o); // forEachPixel bitmask // ---------------- if (_bitMaskTerm != null) { _inputProduct.readBitmask(0, y, width, 1, _bitMaskTerm, process, ProgressMonitor.NULL); } // process scanline // ---------------- toa_corr = _algorithm.run( sza, saa, vza, vaa, taup550, uh2o, uo3, press, process, _invalidPixel, toa, toa_corr); // write scanline // -------------- outBand.writePixels(0, y, width, 1, toa_corr, ProgressMonitor.NULL); // update progressbar // ------------------ pm.worked(1); if (pm.isCanceled()) { _logger.warning(ProcessorConstants.LOG_MSG_PROC_CANCELED); setCurrentStatus(ProcessorConstants.STATUS_ABORTED); return; } } } finally { pm.done(); } _logger.info(ProcessorConstants.LOG_MSG_PROC_SUCCESS); }
// Processes a single spectralBand of MERIS data. private void processMerisBand(Band spectralBand, ProgressMonitor pm) throws IOException { // load appropriate Sensor coefficientFile and init algorithm // ---------------------------------------------------------- if (!loadBandCoefficients(spectralBand)) { _logger.severe( SmacConstants.LOG_MSG_COEFF_NOT_FOUND_1 + spectralBand.getName() + SmacConstants.LOG_MSG_COEFF_NOT_FOUND_2); setCurrentStatus(ProcessorConstants.STATUS_FAILED); return; } _logger.info( SmacConstants.LOG_MSG_GENERATING_PIXEL_1 + spectralBand.getName() + SmacConstants.LOG_MSG_GENERATING_PIXEL_2); /*I18N*/ // initialize vectors and other data int n; int width = spectralBand.getSceneRasterWidth(); int height = spectralBand.getSceneRasterHeight(); Band outBand = _outputProduct.getBand(convertMerisBandName(spectralBand)); float[] sza = new float[width]; float[] saa = new float[width]; float[] vza = new float[width]; float[] vaa = new float[width]; float[] taup550 = new float[width]; float[] uh2o = new float[width]; float[] uo3 = new float[width]; float[] press = new float[width]; boolean[] process = new boolean[width]; float[] toa = new float[width]; float[] toa_corr = new float[width]; for (n = 0; n < width; n++) { taup550[n] = _tau_aero_550; uh2o[n] = _u_h2o; uo3[n] = _u_o3; press[n] = _surf_press; process[n] = true; } // progress init pm.beginTask( SmacConstants.LOG_MSG_GENERATING_PIXEL_1 + spectralBand.getName() + SmacConstants.LOG_MSG_GENERATING_PIXEL_2, height * 6); try { // loop over all scanlines for (int y = 0; y < spectralBand.getSceneRasterHeight(); y++) { // read scanline spectralBand.readPixels(0, y, width, 1, toa, SubProgressMonitor.create(pm, 1)); _szaBand.readPixels(0, y, width, 1, sza, SubProgressMonitor.create(pm, 1)); _saaBand.readPixels(0, y, width, 1, saa, SubProgressMonitor.create(pm, 1)); _vzaBand.readPixels(0, y, width, 1, vza, SubProgressMonitor.create(pm, 1)); _vaaBand.readPixels(0, y, width, 1, vaa, SubProgressMonitor.create(pm, 1)); // scale radiances to reflectances toa = RsMathUtils.radianceToReflectance(toa, sza, spectralBand.getSolarFlux(), toa); // forEachPixel bitmask if (_bitMaskTerm != null) { _inputProduct.readBitmask(0, y, width, 1, _bitMaskTerm, process, ProgressMonitor.NULL); } // process scanline toa_corr = _algorithm.run( sza, saa, vza, vaa, taup550, uh2o, uo3, press, process, _invalidPixel, toa, toa_corr); // write scanline outBand.writePixels(0, y, width, 1, toa_corr, ProgressMonitor.NULL); // update progressbar pm.worked(1); if (pm.isCanceled()) { _logger.warning(ProcessorConstants.LOG_MSG_PROC_CANCELED); setCurrentStatus(ProcessorConstants.STATUS_ABORTED); return; } } } finally { pm.done(); } _logger.info(ProcessorConstants.LOG_MSG_PROC_SUCCESS); }
@Override public void initialize() throws OperatorException { if (computeErrorBands) { deactivateComputeTileMethod(); } if (endmemberFile != null) { loadEndmemberFile(); } if (sourceBandNames == null || sourceBandNames.length == 0) { Band[] bands = sourceProduct.getBands(); ArrayList<String> bandNameList = new ArrayList<String>(); for (Band band : bands) { if (band.getSpectralWavelength() > 0) { bandNameList.add(band.getName()); } } sourceBandNames = bandNameList.toArray(new String[bandNameList.size()]); } validateParameters(); sourceBands = new Band[sourceBandNames.length]; for (int i = 0; i < sourceBandNames.length; i++) { String sourceBandName = sourceBandNames[i]; Band sourceBand = sourceProduct.getBand(sourceBandName); if (sourceBand == null) { throw new OperatorException("Source band not found: " + sourceBandName); } if (sourceBand.getSpectralWavelength() <= 0) { throw new OperatorException("Source band without spectral wavelength: " + sourceBandName); } sourceBands[i] = sourceBand; } int numSourceBands = sourceBands.length; int numEndmembers = endmembers.length; if (numSourceBands < numEndmembers) { throw new OperatorException("Number of source bands must be >= number of endmembers."); } double[][] lsuMatrixElements = new double[numSourceBands][numEndmembers]; for (int j = 0; j < numEndmembers; j++) { Endmember endmember = endmembers[j]; double[] wavelengths = endmember.getWavelengths(); double[] radiations = endmember.getRadiations(); for (int i = 0; i < numSourceBands; i++) { Band sourceBand = sourceBands[i]; float wavelength = sourceBand.getSpectralWavelength(); float bandwidth = sourceBand.getSpectralBandwidth(); int k = findEndmemberSpectralIndex(wavelengths, wavelength, Math.max(bandwidth, minBandwidth)); if (k == -1) { throw new OperatorException( String.format( "Band %s: No matching endmember wavelength found (%f nm)", sourceBand.getName(), wavelength)); } lsuMatrixElements[i][j] = radiations[k]; } } if (UC_LSU.equals(unmixingModelName)) { spectralUnmixing = new UnconstrainedLSU(lsuMatrixElements); } else if (C_LSU.equals(unmixingModelName)) { spectralUnmixing = new ConstrainedLSU(lsuMatrixElements); } else if (FC_LSU.equals(unmixingModelName)) { spectralUnmixing = new FullyConstrainedLSU(lsuMatrixElements); } else if (unmixingModelName == null) { spectralUnmixing = new UnconstrainedLSU(lsuMatrixElements); } int width = sourceProduct.getSceneRasterWidth(); int height = sourceProduct.getSceneRasterHeight(); targetProduct = new Product(sourceProduct.getName() + "_unmixed", "SpectralUnmixing", width, height); abundanceBands = new Band[numEndmembers]; for (int i = 0; i < numEndmembers; i++) { abundanceBands[i] = targetProduct.addBand( endmembers[i].getName() + abundanceBandNameSuffix, ProductData.TYPE_FLOAT32); } if (computeErrorBands) { errorBands = new Band[numSourceBands]; for (int i = 0; i < errorBands.length; i++) { final String erroBandName = sourceBands[i].getName() + errorBandNameSuffix; errorBands[i] = targetProduct.addBand(erroBandName, ProductData.TYPE_FLOAT32); ProductUtils.copySpectralBandProperties(sourceBands[i], errorBands[i]); } summaryErrorBand = targetProduct.addBand("summary_error", ProductData.TYPE_FLOAT32); summaryErrorBand.setDescription("Root mean square error"); } ProductUtils.copyMetadata(sourceProduct, targetProduct); ProductUtils.copyTiePointGrids(sourceProduct, targetProduct); ProductUtils.copyGeoCoding(sourceProduct, targetProduct); }
// Don't do this...it hurts. Too much of a memory hog... private void addBandsBinMap(Product product) throws IOException, InvalidRangeException { String[] bandList = product.getBandNames(); if (rowInfo == null) { rowInfo = createRowInfos(); } final int height = sceneHeight; final int width = sceneWidth; final ISINGrid grid = this.grid; // loop over lines try { int[] lineOffsets = new int[1]; int[] lineLengths = new int[1]; int[] stride = new int[1]; stride[0] = 1; // for (int y = sourceOffsetY; y < sourceOffsetY + sourceHeight; y++) { for (String name : bandList) { if (name.endsWith("mean") || name.endsWith("stdev")) continue; Band band = product.getBand(name); ProductData buffer; final Variable variable = variableMap.get(band); DataType prodtype = variable.getDataType(); float[] fbuffer = new float[width * height]; short[] sbuffer = new short[width * height]; int[] ibuffer = new int[width * height]; byte[] bbuffer = new byte[width * height]; if (prodtype == DataType.FLOAT) { Arrays.fill(fbuffer, Float.NaN); buffer = ProductData.createInstance(fbuffer); } else if (prodtype == DataType.SHORT) { Arrays.fill(sbuffer, (short) -999); buffer = ProductData.createInstance(sbuffer); } else if (prodtype == DataType.BYTE) { Arrays.fill(bbuffer, (byte) 255); buffer = ProductData.createInstance(bbuffer); } else { Arrays.fill(ibuffer, -999); buffer = ProductData.createInstance(ibuffer); } for (int y = 0; y < height; y++) { final int rowIndex = (height - 1) - y; final RowInfo rowInfo = this.rowInfo[rowIndex]; if (rowInfo != null) { final Array bindata; final int lineOffset = rowInfo.offset; final int lineLength = rowInfo.length; lineOffsets[0] = lineOffset; lineLengths[0] = lineLength; synchronized (ncFile) { bindata = variable .read() .section(lineOffsets, lineLengths, stride); // .copyTo1DJavaArray(); } int lineIndex0 = 0; for (int x = 0; x < width; x++) { final double lon = x * 360.0 / width; final int binIndex = grid.getBinIndex(rowIndex, lon); int lineIndex = -1; for (int i = lineIndex0; i < lineLength; i++) { int binidx = bins[lineOffset + i]; if (binidx >= binIndex) { if (binidx == binIndex) { lineIndex = i; } lineIndex0 = i; break; } } if (lineIndex >= 0) { final int rasterIndex = width * y + x; final Array elem; elem = Array.factory(bindata.copyTo1DJavaArray()); for (int i = 0; i < elem.getSize(); i++) { if (prodtype == DataType.FLOAT) { buffer.setElemFloatAt(rasterIndex, elem.getFloat(i)); } else { buffer.setElemIntAt(rasterIndex, elem.getInt(i)); } // System.arraycopy(bindata, lineIndex, buffer, // rasterIndex, 1); } } } } } band.setDataElems(buffer); } } catch (IOException e) { throw new IOException("Could not map product " + product.getName(), e); } }
public void initialize() throws OperatorException { // System.out.println("starting..."); if (new File(SynergyConstants.SYNERGY_AUXDATA_HOME_DEFAULT).exists()) { auxdataPath = SynergyConstants.SYNERGY_AUXDATA_HOME_DEFAULT + File.separator + "aerosolLUTs" + File.separator + "ocean"; } else { // try this one (in case of calvalus processing) auxdataPath = SynergyConstants.SYNERGY_AUXDATA_CALVALUS_DEFAULT; } noDataVal = (float) SynergyConstants.OUTPUT_AOT_BAND_NODATAVALUE; // get the glint product... Map<String, Product> glintInput = new HashMap<String, Product>(3); glintInput.put("l1bSynergy", synergyProduct); Map<String, Object> glintAveParams = new HashMap<String, Object>(2); glintAveParams.put("aveBlock", aveBlock); glintProduct = GPF.createProduct( OperatorSpi.getOperatorAlias(GlintAveOp.class), glintAveParams, glintInput); scalingFactor = aveBlock; aveBlock /= 2; minNAve = (int) (scalingFactor * scalingFactor - 1); noDataVal = (float) SynergyConstants.OUTPUT_AOT_BAND_NODATAVALUE; createTargetProduct(); // targetProduct = glintProduct; // test // correction of azimuth discontinuity: // set up tiles for MERIS and AATSR which cover the whole scene... final int sceneWidth = synergyProduct.getSceneRasterWidth(); final int sceneHeight = synergyProduct.getSceneRasterHeight(); final Rectangle rect = new Rectangle(0, 0, sceneWidth, sceneHeight); vaMerisTileComplete = getSourceTile(synergyProduct.getTiePointGrid("view_azimuth"), rect); vaAatsrNadirTileComplete = getSourceTile( synergyProduct.getBand( "view_azimuth_nadir" + "_" + SynergyConstants.INPUT_BANDS_SUFFIX_AATSR + ""), rect); aot550Result = new float[sceneWidth][sceneHeight]; angResult = new float[sceneWidth][sceneHeight]; aot550ErrorResult = new float[sceneWidth][sceneHeight]; angErrorResult = new float[sceneWidth][sceneHeight]; glintResult = new float[sceneWidth][sceneHeight]; wsResult = new float[sceneWidth][sceneHeight]; // read aerosol class table try { aerosolClassTable = AerosolAuxData.getInstance().createAerosolClassTable(); } catch (IOException e) { throw new OperatorException("Failed to read aerosol class table:\n" + e.getMessage(), e); } // read aerosol models try { aerosolModelTable = AerosolAuxData.getInstance().createAerosolModelTable(auxdataPath); } catch (IOException e) { throw new OperatorException("Failed to read aerosol class table:\n" + e.getMessage(), e); } // wvl=[ 865, 885,1610, 885,1610, 885] wvl = new float[] {865.0f, 885.0f, 1610.0f, 885.0f, 1610.0f, 885.0f}; wvlWeight = new float[] {1.0f, 1.0f, 3.0f, 1.0f, 3.0f, 3.0f}; wvlIndex = new int[] {0, 3, 5}; // at this point, just use 1 MERIS and 1 AATSR channel... // todo: clarify with RP which we should finally use // find model indices belonging to aerosol classes... final List<Integer> modelIndices = aerosolModelTable.getMaritimeAndDesertIndices(); nMod = modelIndices.size(); nWvl = wvlIndex.length; try { aerosolLookupTables = AerosolAuxData.getInstance() .createAerosolOceanLookupTables( auxdataPath, modelIndices, wvl, wvlIndex); } catch (IOException e) { throw new OperatorException("Failed to create aerosol lookup tables:\n" + e.getMessage(), e); // String msg = SynergyConstants.AUXDATA_ERROR_MESSAGE; // SynergyUtils.logErrorMessage(msg); } nTauLut = aerosolLookupTables[0][0].getDimensions()[4].getSequence().length; interpol5DResultLow = new double[nMod][nWvl][nTauLut]; interpol5DResultHigh = new double[nMod][nWvl][nTau]; interpolAngResult = new float[nWvl][nTau][nAng]; costFunction = new float[nWvl][nTau][nAng]; vectorTauLut = new double[nTauLut]; for (int i = 0; i < nTauLut; i++) { vectorTauLut[i] = i * 2.0 / (nTauLut - 1); } vectorTauLutHigh = new double[nTau]; for (int i = 0; i < nTau; i++) { vectorTauLutHigh[i] = i * 2.0 / (nTau - 1); } final float[] angArray = aerosolModelTable.getAngArray(modelIndices, 0); angstroemParameters = AerosolHelpers.getInstance().getAngstroemParameters(angArray, nAng); // read corresponding small LUTs and make a big LUT... // correct azimuths in these tiles for later usage... GlintPreparation.correctViewAzimuthLinear(vaMerisTileComplete, rect); GlintPreparation.correctViewAzimuthLinear(vaAatsrNadirTileComplete, rect); }