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