Example #1
1
  public Map<Band, Variable> addBands(
      Product product, Variable idxVariable, List<Variable> l3ProdVars) {

    final Structure binListStruc = (Structure) idxVariable;

    final Map<Band, Variable> bandToVariableMap = new HashMap<Band, Variable>();

    //        bandToVariableMap.put(addBand(product, "bin_num", ProductData.TYPE_UINT32),
    // binListStruc.select("bin_num").findVariable("bin_num"));
    bandToVariableMap.put(
        addBand(product, "weights", ProductData.TYPE_FLOAT32),
        binListStruc.select("weights").findVariable("weights"));
    bandToVariableMap.put(
        addBand(product, "nobs", ProductData.TYPE_UINT16),
        binListStruc.select("nobs").findVariable("nobs"));
    bandToVariableMap.put(
        addBand(product, "nscenes", ProductData.TYPE_UINT16),
        binListStruc.select("nscenes").findVariable("nscenes"));
    //        ncFile.getRootGroup().findGroup("Level-3 Binned Data").findVariable("BinList");
    if (ncFile.getRootGroup().findGroup("Level-3_Binned_Data").findVariable("qual_l3") != null) {
      bandToVariableMap.put(
          addBand(product, "qual_l3", ProductData.TYPE_UINT8),
          ncFile.getRootGroup().findGroup("Level-3_Binned_Data").findVariable("qual_l3"));
    }
    String groupnames = "";
    for (Variable l3Var : l3ProdVars) {
      String varName = l3Var.getShortName();
      final int dataType = ProductData.TYPE_FLOAT32;

      if (!varName.contains("Bin")
          && (!varName.startsWith("qual"))
          && (!varName.equalsIgnoreCase("SEAGrid"))
          && (!varName.equalsIgnoreCase("Input_Files"))) {
        final Structure binStruc = (Structure) l3Var;
        if (groupnames.length() == 0) {
          groupnames = varName;
        } else {
          groupnames = groupnames + ":" + varName;
        }

        List<String> vnames = binStruc.getVariableNames();
        for (String bandvar : vnames) {
          bandToVariableMap.put(
              addBand(product, bandvar, dataType), binStruc.select(bandvar).findVariable(bandvar));
        }
        // Add virtual band for product mean
        StringBuilder prodname = new StringBuilder(varName);
        prodname.append("_mean");

        String calcmean = ComputeBinMeans(varName);
        Band varmean =
            new VirtualBand(
                prodname.toString(),
                ProductData.TYPE_FLOAT32,
                product.getSceneRasterWidth(),
                product.getSceneRasterHeight(),
                calcmean);
        varmean.setNoDataValue(Double.NaN);
        varmean.setNoDataValueUsed(true);
        product.addBand(varmean);

        // Add virtual band for product stdev
        int underscore = prodname.indexOf("_mean");
        prodname.delete(underscore, underscore + 5);
        prodname.append("_stdev");

        String calcstdev = ComputeBinVariances(varName);

        Band varstdev =
            new VirtualBand(
                prodname.toString(),
                ProductData.TYPE_FLOAT32,
                product.getSceneRasterWidth(),
                product.getSceneRasterHeight(),
                calcstdev);
        varstdev.setNoDataValue(Double.NaN);
        varstdev.setNoDataValueUsed(true);

        product.addBand(varstdev);
      }
    }
    product.setAutoGrouping(groupnames);
    return bandToVariableMap;
  }
 private void copyBandRasterDataSubSampling(
     Band sourceBand,
     int sourceOffsetX,
     int sourceOffsetY,
     int sourceWidth,
     int sourceHeight,
     int sourceStepX,
     int sourceStepY,
     ProductData destBuffer,
     int destWidth) {
   final int sourceMinY = sourceOffsetY;
   final int sourceMaxY = sourceOffsetY + sourceHeight - 1;
   int destPos = 0;
   for (int sourceY = sourceMinY; sourceY <= sourceMaxY; sourceY += sourceStepY) {
     // no subsampling in x-direction
     if (sourceStepX == 1) {
       copyData(
           sourceBand.getRasterData(),
           sourceY * sourceBand.getSceneRasterWidth() + sourceOffsetX,
           destBuffer,
           destPos,
           destWidth);
     } else {
       copyLine(
           sourceBand.getRasterData(),
           sourceY * sourceBand.getSceneRasterWidth() + sourceOffsetX,
           sourceWidth,
           sourceStepX,
           destBuffer,
           destPos);
     }
     destPos += destWidth;
   }
 }
 /**
  * The template method which is called by the <code>readBandRasterDataSubSampling</code> method
  * after an optional spatial subset has been applied to the input parameters.
  *
  * <p>
  *
  * <p>The destination band, buffer and region parameters are exactly the ones passed to the
  * original <code>readBandRasterDataSubSampling</code> call. Since the <code>destOffsetX</code>
  * and <code>destOffsetY</code> parameters are already taken into acount in the <code>
  * sourceOffsetX</code> and <code>sourceOffsetY</code> parameters, an implementor of this method
  * is free to ignore them.
  *
  * @param sourceOffsetX the absolute X-offset in source raster co-ordinates
  * @param sourceOffsetY the absolute Y-offset in source raster co-ordinates
  * @param sourceWidth the width of region providing samples to be read given in source raster
  *     co-ordinates
  * @param sourceHeight the height of region providing samples to be read given in source raster
  *     co-ordinates
  * @param sourceStepX the sub-sampling in X direction within the region providing samples to be
  *     read
  * @param sourceStepY the sub-sampling in Y direction within the region providing samples to be
  *     read
  * @param destBand the destination band which identifies the data source from which to read the
  *     sample values
  * @param destBuffer the destination buffer which receives the sample values to be read
  * @param destOffsetX the X-offset in the band's raster co-ordinates
  * @param destOffsetY the Y-offset in the band's raster co-ordinates
  * @param destWidth the width of region to be read given in the band's raster co-ordinates
  * @param destHeight the height of region to be read given in the band's raster co-ordinates
  * @throws IOException if an I/O error occurs
  * @see #getSubsetDef
  */
 @Override
 protected void readBandRasterDataImpl(
     int sourceOffsetX,
     int sourceOffsetY,
     int sourceWidth,
     int sourceHeight,
     int sourceStepX,
     int sourceStepY,
     Band destBand,
     int destOffsetX,
     int destOffsetY,
     int destWidth,
     int destHeight,
     ProductData destBuffer,
     ProgressMonitor pm)
     throws IOException {
   Band sourceBand = (Band) bandMap.get(destBand);
   // if the band already has an internal raster
   if (sourceBand.getRasterData() != null) {
     // if the destination region equals the entire raster
     if (sourceBand.getSceneRasterWidth() == destWidth
         && sourceBand.getSceneRasterHeight() == destHeight) {
       copyBandRasterDataFully(sourceBand, destBuffer, destWidth, destHeight);
       // else if the destination region is smaller than the entire raster
     } else {
       copyBandRasterDataSubSampling(
           sourceBand,
           sourceOffsetX,
           sourceOffsetY,
           sourceWidth,
           sourceHeight,
           sourceStepX,
           sourceStepY,
           destBuffer,
           destWidth);
     }
   } else {
     // if the desired destination region equals the source raster
     if (sourceWidth == destWidth && sourceHeight == destHeight) {
       readBandRasterDataRegion(
           sourceBand, sourceOffsetX, sourceOffsetY, sourceWidth, sourceHeight, destBuffer, pm);
       // else if the desired destination region is smaller than the source raster
     } else {
       readBandRasterDataSubSampling(
           sourceBand,
           sourceOffsetX,
           sourceOffsetY,
           sourceWidth,
           sourceHeight,
           sourceStepX,
           sourceStepY,
           destBuffer,
           destWidth,
           pm);
     }
   }
 }
Example #4
0
  public synchronized void readBandData(
      Band destBand,
      int sourceOffsetX,
      int sourceOffsetY,
      int sourceWidth,
      int sourceHeight,
      int sourceStepX,
      int sourceStepY,
      ProductData destBuffer,
      ProgressMonitor pm)
      throws IOException, InvalidRangeException {

    if (mustFlipY) {
      sourceOffsetY = destBand.getSceneRasterHeight() - (sourceOffsetY + sourceHeight);
    }
    if (mustFlipX) {
      sourceOffsetX = destBand.getSceneRasterWidth() - (sourceOffsetX + sourceWidth);
    }
    sourceOffsetY += leadLineSkip;
    start[0] = sourceOffsetY;
    start[1] = sourceOffsetX;
    stride[0] = sourceStepY;
    stride[1] = sourceStepX;
    count[0] = sourceHeight;
    count[1] = sourceWidth;
    Object buffer = destBuffer.getElems();
    Variable variable = variableMap.get(destBand);

    pm.beginTask("Reading band '" + variable.getShortName() + "'...", sourceHeight);
    try {
      Section section = new Section(start, count, stride);

      Array array;
      int[] newshape = {sourceHeight, sourceWidth};

      array = variable.read(section);
      if (array.getRank() == 3) {
        array = array.reshapeNoCopy(newshape);
      }
      Object storage;

      if (mustFlipX && !mustFlipY) {
        storage = array.flip(1).copyTo1DJavaArray();
      } else if (!mustFlipX && mustFlipY) {
        storage = array.flip(0).copyTo1DJavaArray();
      } else if (mustFlipX && mustFlipY) {
        storage = array.flip(0).flip(1).copyTo1DJavaArray();
      } else {
        storage = array.copyTo1DJavaArray();
      }

      arraycopy(storage, 0, buffer, 0, destBuffer.getNumElems());
    } finally {
      pm.done();
    }
  }
 private void readBandRasterDataSubSampling(
     Band sourceBand,
     int sourceOffsetX,
     int sourceOffsetY,
     int sourceWidth,
     int sourceHeight,
     int sourceStepX,
     int sourceStepY,
     ProductData destBuffer,
     int destWidth,
     ProgressMonitor pm)
     throws IOException {
   final int sourceMinY = sourceOffsetY;
   final int sourceMaxY = sourceOffsetY + sourceHeight - 1;
   ProductData lineBuffer = ProductData.createInstance(destBuffer.getType(), sourceWidth);
   int destPos = 0;
   try {
     pm.beginTask("Reading sub sampled raster data...", 2 * (sourceMaxY - sourceMinY));
     for (int sourceY = sourceMinY; sourceY <= sourceMaxY; sourceY += sourceStepY) {
       sourceBand.readRasterData(
           sourceOffsetX, sourceY, sourceWidth, 1, lineBuffer, SubProgressMonitor.create(pm, 1));
       if (sourceStepX == 1) {
         copyData(lineBuffer, 0, destBuffer, destPos, destWidth);
       } else {
         copyLine(lineBuffer, 0, sourceWidth, sourceStepX, destBuffer, destPos);
       }
       pm.worked(1);
       destPos += destWidth;
     }
   } finally {
     pm.done();
   }
 }
Example #6
0
 protected void setSpectralBand(Product product) {
   int spectralBandIndex = 0;
   for (String name : product.getBandNames()) {
     Band band = product.getBandAt(product.getBandIndex(name));
     if (name.matches("\\w+_\\d{3,}")) {
       String[] parts = name.split("_");
       String wvlstr = parts[parts.length - 1].trim();
       // Some bands have the wvl portion in the middle...
       if (!wvlstr.matches("^\\d{3,}")) {
         wvlstr = parts[parts.length - 2].trim();
       }
       final float wavelength = Float.parseFloat(wvlstr);
       band.setSpectralWavelength(wavelength);
       band.setSpectralBandIndex(spectralBandIndex++);
     }
   }
 }
Example #7
0
  private boolean checkFlagDatasetIncluded() {
    final String[] nodeNames = productSubsetDef.getNodeNames();
    final List<String> flagDsNameList = new ArrayList<String>(10);
    boolean flagDsInSubset = false;
    for (int i = 0; i < product.getNumBands(); i++) {
      Band band = product.getBandAt(i);
      if (band.getFlagCoding() != null) {
        flagDsNameList.add(band.getName());
        if (StringUtils.contains(nodeNames, band.getName())) {
          flagDsInSubset = true;
        }
        break;
      }
    }

    final int numFlagDs = flagDsNameList.size();
    boolean ok = true;
    if (numFlagDs > 0 && !flagDsInSubset) {
      int status =
          JOptionPane.showConfirmDialog(
              getJDialog(),
              "No flag dataset selected.\n\n"
                  + "If you do not include a flag dataset in the subset,\n"
                  + "you will not be able to create bitmask overlays.\n\n"
                  + "Do you wish to include the available flag dataset(s)\n"
                  + "in the current subset?\n",
              "No Flag Dataset Selected",
              JOptionPane.YES_NO_CANCEL_OPTION);
      if (status == JOptionPane.YES_OPTION) {
        productSubsetDef.addNodeNames(flagDsNameList.toArray(new String[numFlagDs]));
        ok = true;
      } else if (status == JOptionPane.NO_OPTION) {
        /* OK, no flag datasets wanted */
        ok = true;
      } else if (status == JOptionPane.CANCEL_OPTION) {
        ok = false;
      }
    }

    return ok;
  }
 private void readBandRasterDataRegion(
     Band sourceBand,
     int sourceOffsetX,
     int sourceOffsetY,
     int sourceWidth,
     int sourceHeight,
     ProductData destBuffer,
     ProgressMonitor pm)
     throws IOException {
   sourceBand.readRasterData(
       sourceOffsetX, sourceOffsetY, sourceWidth, sourceHeight, destBuffer, pm);
 }
Example #9
0
  public void computeLatLonBandData(
      int height,
      int width,
      Band latBand,
      Band lonBand,
      final float[] latRawData,
      final float[] lonRawData,
      final int[] colPoints) {

    float[] latFloats = new float[height * width];
    float[] lonFloats = new float[height * width];
    final int rawWidth = colPoints.length;

    int colPointIdx = 0;
    int p1 = colPoints[colPointIdx] - 1;
    int p2 = colPoints[++colPointIdx] - 1;

    for (int x = 0; x < width; x++) {
      if (x == p2 && colPointIdx < rawWidth - 1) {
        p1 = p2;
        p2 = colPoints[++colPointIdx] - 1;
      }
      final int steps = p2 - p1;
      final double step = 1.0 / steps;
      final double weight = step * (x - p1);
      for (int y = 0; y < height; y++) {
        final int rawPos2 = y * rawWidth + colPointIdx;
        final int rawPos1 = rawPos2 - 1;
        final int pos = y * width + x;
        latFloats[pos] = computeGeoPixel(latRawData[rawPos1], latRawData[rawPos2], weight);
        lonFloats[pos] = computeGeoPixel(lonRawData[rawPos1], lonRawData[rawPos2], weight);
      }
    }

    latBand.setDataElems(latFloats);
    lonBand.setDataElems(lonFloats);
  }
Example #10
0
  protected Band addNewBand(Product product, Variable variable) {
    final int sceneRasterWidth = product.getSceneRasterWidth();
    final int sceneRasterHeight = product.getSceneRasterHeight();
    Band band = null;

    int variableRank = variable.getRank();
    if (variableRank == 2) {
      final int[] dimensions = variable.getShape();
      final int height = dimensions[0] - leadLineSkip - tailLineSkip;
      final int width = dimensions[1];
      if (height == sceneRasterHeight && width == sceneRasterWidth) {
        final String name = variable.getShortName();
        final int dataType = getProductDataType(variable);
        band = new Band(name, dataType, width, height);
        final String validExpression = bandInfoMap.get(name);
        if (validExpression != null && !validExpression.equals("")) {
          band.setValidPixelExpression(validExpression);
        }
        product.addBand(band);

        try {
          band.setNoDataValue(
              (double) variable.findAttribute("bad_value_scaled").getNumericValue().floatValue());
          band.setNoDataValueUsed(true);
        } catch (Exception ignored) {
        }

        final List<Attribute> list = variable.getAttributes();
        for (Attribute hdfAttribute : list) {
          final String attribName = hdfAttribute.getShortName();
          if ("units".equals(attribName)) {
            band.setUnit(hdfAttribute.getStringValue());
          } else if ("long_name".equals(attribName)) {
            band.setDescription(hdfAttribute.getStringValue());
          } else if ("slope".equals(attribName)) {
            band.setScalingFactor(hdfAttribute.getNumericValue(0).doubleValue());
          } else if ("intercept".equals(attribName)) {
            band.setScalingOffset(hdfAttribute.getNumericValue(0).doubleValue());
          }
        }
      }
    }
    return band;
  }
Example #11
0
 private Band addBand(Product product, String varName, int productType) {
   Band band =
       new Band(
           varName, productType, product.getSceneRasterWidth(), product.getSceneRasterHeight());
   band.setScalingOffset(0.0);
   band.setScalingFactor(1.0);
   band.setLog10Scaled(false);
   if (productType == ProductData.TYPE_FLOAT32) {
     band.setNoDataValue(Double.NaN);
   } else {
     band.setNoDataValue(-999);
   }
   band.setNoDataValueUsed(true);
   product.addBand(band);
   return band;
 }
Example #12
0
  // 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);
    }
  }
  @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));
    }
  }
  protected Map<Band, Variable> addSmiBands(Product product, List<Variable> variables) {
    final int sceneRasterWidth = product.getSceneRasterWidth();
    final int sceneRasterHeight = product.getSceneRasterHeight();
    Map<Band, Variable> bandToVariableMap = new HashMap<Band, Variable>();
    for (Variable variable : variables) {
      int variableRank = variable.getRank();
      if (variableRank == 2) {
        final int[] dimensions = variable.getShape();
        final int height = dimensions[0];
        final int width = dimensions[1];
        if (height == sceneRasterHeight && width == sceneRasterWidth) {
          String name = variable.getShortName();
          if (name.equals("l3m_data")) {
            try {
              name = getStringAttribute("Parameter") + " " + getStringAttribute("Measure");
            } catch (Exception e) {
              e.printStackTrace();
            }
          }

          final int dataType = getProductDataType(variable);
          final Band band = new Band(name, dataType, width, height);
          //                    band = new Band(name, dataType, width, height);

          product.addBand(band);

          try {
            Attribute fillvalue = variable.findAttribute("_FillValue");
            if (fillvalue == null) {
              fillvalue = variable.findAttribute("Fill");
            }
            if (fillvalue != null) {
              band.setNoDataValue((double) fillvalue.getNumericValue().floatValue());
              band.setNoDataValueUsed(true);
            }
          } catch (Exception ignored) {

          }
          bandToVariableMap.put(band, variable);
          // Set units, if defined
          try {
            band.setUnit(getStringAttribute("Units"));
          } catch (Exception ignored) {

          }

          final List<Attribute> list = variable.getAttributes();
          double[] validMinMax = {0.0, 0.0};
          for (Attribute hdfAttribute : list) {
            final String attribName = hdfAttribute.getShortName();
            if ("units".equals(attribName)) {
              band.setUnit(hdfAttribute.getStringValue());
            } else if ("long_name".equalsIgnoreCase(attribName)) {
              band.setDescription(hdfAttribute.getStringValue());
            } else if ("slope".equalsIgnoreCase(attribName)) {
              band.setScalingFactor(hdfAttribute.getNumericValue(0).doubleValue());
            } else if ("intercept".equalsIgnoreCase(attribName)) {
              band.setScalingOffset(hdfAttribute.getNumericValue(0).doubleValue());
            } else if ("scale_factor".equals(attribName)) {
              band.setScalingFactor(hdfAttribute.getNumericValue(0).doubleValue());
            } else if ("add_offset".equals(attribName)) {
              band.setScalingOffset(hdfAttribute.getNumericValue(0).doubleValue());
            } else if (attribName.startsWith("valid_")) {
              if ("valid_min".equals(attribName)) {
                validMinMax[0] = hdfAttribute.getNumericValue(0).doubleValue();
              } else if ("valid_max".equals(attribName)) {
                validMinMax[1] = hdfAttribute.getNumericValue(0).doubleValue();
              } else if ("valid_range".equals(attribName)) {
                validMinMax[0] = hdfAttribute.getNumericValue(0).doubleValue();
                validMinMax[1] = hdfAttribute.getNumericValue(1).doubleValue();
              }
            }
          }
          if (validMinMax[0] != validMinMax[1]) {
            double[] minmax = {0.0, 0.0};
            minmax[0] = validMinMax[0];
            minmax[1] = validMinMax[1];

            if (band.getScalingFactor() != 1.0) {
              minmax[0] *= band.getScalingFactor();
              minmax[1] *= band.getScalingFactor();
            }
            if (band.getScalingOffset() != 0.0) {
              minmax[0] += band.getScalingOffset();
              minmax[1] += band.getScalingOffset();
            }

            String validExp = format("%s >= %.2f && %s <= %.2f", name, minmax[0], name, minmax[1]);
            band.setValidPixelExpression(
                validExp); // .format(name, validMinMax[0], name, validMinMax[1]));
          }
        }
      } else if (variableRank == 4) {
        final int[] dimensions = variable.getShape();
        final int height = dimensions[2];
        final int width = dimensions[3];
        if (height == sceneRasterHeight && width == sceneRasterWidth) {
          String name = variable.getShortName();

          final int dataType = getProductDataType(variable);
          final Band band = new Band(name, dataType, width, height);
          //                    band = new Band(name, dataType, width, height);

          Variable sliced = null;
          try {
            sliced = variable.slice(0, 0).slice(0, 0);
          } catch (InvalidRangeException e) {
            e.printStackTrace(); // Todo change body of catch statement.
          }

          bandToVariableMap.put(band, sliced);
          product.addBand(band);

          try {
            Attribute fillvalue = variable.findAttribute("_FillValue");
            if (fillvalue != null) {
              band.setNoDataValue((double) fillvalue.getNumericValue().floatValue());
              band.setNoDataValueUsed(true);
            }
          } catch (Exception ignored) {

          }
          // Set units, if defined
          try {
            band.setUnit(getStringAttribute("units"));
          } catch (Exception ignored) {

          }

          final List<Attribute> list = variable.getAttributes();
          for (Attribute hdfAttribute : list) {
            final String attribName = hdfAttribute.getShortName();
            if ("scale_factor".equals(attribName)) {
              band.setScalingFactor(hdfAttribute.getNumericValue(0).doubleValue());
            } else if ("add_offset".equals(attribName)) {
              band.setScalingOffset(hdfAttribute.getNumericValue(0).doubleValue());
            }
          }
        }
      }
    }
    return bandToVariableMap;
  }
Example #15
0
 private void copyBandRasterDataFully(
     Band sourceBand, ProductData destBuffer, int destWidth, int destHeight) {
   copyData(sourceBand.getRasterData(), 0, destBuffer, 0, destWidth * destHeight);
 }
Example #16
0
  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));
    }
  }
Example #17
0
  protected void addBandsToProduct(Product product) {
    Debug.assertNotNull(getSourceProduct());
    Debug.assertNotNull(product);
    for (int i = 0; i < getSourceProduct().getNumBands(); i++) {
      Band sourceBand = getSourceProduct().getBandAt(i);
      String bandName = sourceBand.getName();
      if (isNodeAccepted(bandName)) {
        Band destBand;
        boolean treatVirtualBandsAsRealBands = false;
        if (getSubsetDef() != null && getSubsetDef().getTreatVirtualBandsAsRealBands()) {
          treatVirtualBandsAsRealBands = true;
        }

        // @todo 1 se/se - extract copy of a band or virtual band to create deep clone of band and
        // virtual band
        if (!treatVirtualBandsAsRealBands && sourceBand instanceof VirtualBand) {
          VirtualBand virtualSource = (VirtualBand) sourceBand;
          destBand =
              new VirtualBand(
                  bandName,
                  sourceBand.getDataType(),
                  getSceneRasterWidth(),
                  getSceneRasterHeight(),
                  virtualSource.getExpression());
        } else {
          destBand =
              new Band(
                  bandName,
                  sourceBand.getDataType(),
                  getSceneRasterWidth(),
                  getSceneRasterHeight());
        }
        if (sourceBand.getUnit() != null) {
          destBand.setUnit(sourceBand.getUnit());
        }
        if (sourceBand.getDescription() != null) {
          destBand.setDescription(sourceBand.getDescription());
        }
        destBand.setScalingFactor(sourceBand.getScalingFactor());
        destBand.setScalingOffset(sourceBand.getScalingOffset());
        destBand.setLog10Scaled(sourceBand.isLog10Scaled());
        destBand.setSpectralBandIndex(sourceBand.getSpectralBandIndex());
        destBand.setSpectralWavelength(sourceBand.getSpectralWavelength());
        destBand.setSpectralBandwidth(sourceBand.getSpectralBandwidth());
        destBand.setSolarFlux(sourceBand.getSolarFlux());
        if (sourceBand.isNoDataValueSet()) {
          destBand.setNoDataValue(sourceBand.getNoDataValue());
        }
        destBand.setNoDataValueUsed(sourceBand.isNoDataValueUsed());
        destBand.setValidPixelExpression(sourceBand.getValidPixelExpression());
        FlagCoding sourceFlagCoding = sourceBand.getFlagCoding();
        IndexCoding sourceIndexCoding = sourceBand.getIndexCoding();
        if (sourceFlagCoding != null) {
          String flagCodingName = sourceFlagCoding.getName();
          FlagCoding destFlagCoding = product.getFlagCodingGroup().get(flagCodingName);
          Debug.assertNotNull(
              destFlagCoding); // should not happen because flag codings should be already in
                               // product
          destBand.setSampleCoding(destFlagCoding);
        } else if (sourceIndexCoding != null) {
          String indexCodingName = sourceIndexCoding.getName();
          IndexCoding destIndexCoding = product.getIndexCodingGroup().get(indexCodingName);
          Debug.assertNotNull(
              destIndexCoding); // should not happen because index codings should be already in
                                // product
          destBand.setSampleCoding(destIndexCoding);
        } else {
          destBand.setSampleCoding(null);
        }
        if (isFullScene(getSubsetDef()) && sourceBand.isStxSet()) {
          copyStx(sourceBand, destBand);
        }
        product.addBand(destBand);
        bandMap.put(destBand, sourceBand);
      }
    }
    for (final Map.Entry<Band, RasterDataNode> entry : bandMap.entrySet()) {
      copyImageInfo(entry.getValue(), entry.getKey());
    }
  }