예제 #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 float getAvePixel(Tile inputTile, int iTarX, int iTarY) {

    double value = 0;
    double noDataValue = 0;
    int n = 0;

    final int minX = Math.max(0, iTarX - aveBlock);
    final int minY = Math.max(0, iTarY - aveBlock);
    final int maxX = Math.min(synergyProduct.getSceneRasterWidth() - 1, iTarX + aveBlock);
    final int maxY = Math.min(synergyProduct.getSceneRasterHeight() - 1, iTarY + aveBlock);

    for (int iy = minY; iy <= maxY; iy++) {
      for (int ix = minX; ix <= maxX; ix++) {
        final double val = inputTile.getSampleDouble(ix, iy);
        noDataValue = inputTile.getRasterDataNode().getNoDataValue();
        final boolean valid = (Double.compare(val, noDataValue) != 0);
        if (valid) {
          n++;
          value += val;
        }
      }
    }
    if (!(n < minNAve)) {
      value /= n;
    } else {
      value = noDataValue;
    }

    return (float) value;
  }
  /** This method creates the target product */
  private void createTargetProduct() {

    final String productType = synergyProduct.getProductType();
    final String productName = synergyProduct.getName();
    final int sceneWidth = synergyProduct.getSceneRasterWidth();
    final int sceneHeight = synergyProduct.getSceneRasterHeight();

    final int downscaledRasterWidth = (int) (Math.ceil((float) (sceneWidth / scalingFactor) - 0.5));
    final int downscaledRasterHeight =
        (int) (Math.ceil((float) (sceneHeight / scalingFactor) - 0.5));

    targetProduct =
        new Product(productName, productType, downscaledRasterWidth, downscaledRasterHeight);
    //        targetProduct.setPreferredTileSize(128, 128);

    ProductUtils.copyGeoCoding(synergyProduct, targetProduct);
    ProductUtils.copyMetadata(synergyProduct, targetProduct);
    AerosolHelpers.copyDownscaledTiePointGrids(synergyProduct, targetProduct, scalingFactor);
    AerosolHelpers.copyDownscaledFlagBands(synergyProduct, targetProduct, scalingFactor);

    //        AerosolHelpers.addAerosolFlagBand(targetProduct, downscaledRasterWidth,
    // downscaledRasterHeight);

    final BandMathsOp bandArithmeticOp =
        BandMathsOp.createBooleanExpressionBand(INVALID_EXPRESSION, synergyProduct);
    invalidBand = bandArithmeticOp.getTargetProduct().getBandAt(0);

    setTargetBands();
  }
예제 #4
0
 /**
  * Checks if all source products share the same raster size, otherwise throws an exception. Called
  * by {@link #initialize()}.
  *
  * @throws OperatorException If the source product's raster sizes are not equal.
  */
 protected void checkRasterSize() throws OperatorException {
   Product[] sourceProducts = getSourceProducts();
   int w = 0;
   int h = 0;
   for (int i = 0; i < sourceProducts.length; i++) {
     Product sourceProduct = sourceProducts[i];
     if (i == 0) {
       w = sourceProduct.getSceneRasterWidth();
       h = sourceProduct.getSceneRasterHeight();
     } else {
       if (sourceProduct.getSceneRasterWidth() != w || sourceProduct.getSceneRasterHeight() != h) {
         throw new OperatorException("Source products must all have the same raster size.");
       }
     }
   }
 }
예제 #5
0
  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);

  }
예제 #6
0
  static void addBitmaskDefinitions(final Product product, final String flagsBandName) {
    for (final Flags flag : Flags.values()) {
      final String name =
          new StringBuilder(flagsBandName.split("flags")[0]).append(flag.name()).toString();

      final ProductNodeGroup<Mask> maskGroup = product.getMaskGroup();
      if (maskGroup.contains(name)) {
        continue;
      }

      final String expression =
          new StringBuilder(flagsBandName).append(".").append(flag.name()).toString();
      final int width = product.getSceneRasterWidth();
      final int height = product.getSceneRasterHeight();
      Mask mask =
          Mask.BandMathsType.create(
              name,
              flag.getDescription(),
              width,
              height,
              expression,
              flag.getColor(),
              flag.getTransparency());
      maskGroup.add(mask);
    }
  }
예제 #7
0
 private void setSceneRasterStartAndStopTime(Product product) {
   final Product sourceProduct = getSourceProduct();
   final ProductData.UTC startTime = sourceProduct.getStartTime();
   final ProductData.UTC stopTime = sourceProduct.getEndTime();
   final ProductSubsetDef subsetDef = getSubsetDef();
   if (startTime != null
       && stopTime != null
       && subsetDef != null
       && subsetDef.getRegion() != null) {
     final double height = sourceProduct.getSceneRasterHeight();
     final Rectangle region = subsetDef.getRegion();
     final double regionY = region.getY();
     final double regionHeight = region.getHeight();
     final double dStart = startTime.getMJD();
     final double dStop = stopTime.getMJD();
     final double vPerLine = (dStop - dStart) / (height - 1);
     final double newStart = vPerLine * regionY + dStart;
     final double newStop = vPerLine * (regionHeight - 1) + newStart;
     product.setStartTime(new ProductData.UTC(newStart));
     product.setEndTime(new ProductData.UTC(newStop));
   } else {
     product.setStartTime(startTime);
     product.setEndTime(stopTime);
   }
 }
예제 #8
0
  /** Calls the given handler for all frames of the product the operator executor product. */
  public Object execute(Handler handler) throws Exception {
    int parallelism = Runtime.getRuntime().availableProcessors();
    System.out.println("parallelism = " + parallelism);
    JAI.getDefaultInstance().getTileScheduler().setParallelism(parallelism);
    Dimension frameSize = getFrameSize();
    int numXFrames = 1 + (product.getSceneRasterWidth() - 1) / frameSize.width;
    int numYFrames = 1 + (product.getSceneRasterHeight() - 1) / frameSize.height;

    Rectangle sceneRegion =
        new Rectangle(product.getSceneRasterWidth(), product.getSceneRasterHeight());

    for (int frameY = 0; frameY < numYFrames; frameY++) {
      for (int frameX = 0; frameX < numXFrames; frameX++) {

        Rectangle frameRegion =
            new Rectangle(
                    frameX * frameSize.width,
                    frameY * frameSize.height,
                    frameSize.width,
                    frameSize.height)
                .intersection(sceneRegion);

        int numBands = product.getNumBands();
        Band[] bandArray = new Band[numBands];
        ProductData[] dataArray = new ProductData[numBands];
        for (int b = 0; b < numBands; b++) {
          Band band = product.getBandAt(b);
          PlanarImage planarImage = band.getSourceImage();
          Point[] indices = planarImage.getTileIndices(null);
          System.out.println("indices = " + indices.length);
          TileRequest tileRequest = planarImage.queueTiles(indices);
          Raster raster = planarImage.getData();
          System.out.println("raster = " + raster);
          ProductData data = band.createCompatibleRasterData(frameRegion.width, frameRegion.height);
          band.readRasterData(
              frameRegion.x, frameRegion.y, frameRegion.width, frameRegion.height, data);
          bandArray[b] = band;
          dataArray[b] = data;
        }

        MyFrame frame = new MyFrame(frameRegion, bandArray, dataArray);
        handler.frameComputed(frame);
      }
    }

    return new Object();
  }
예제 #9
0
 /**
  * Creates the target product instance. Called by {@link #initialize()}.
  *
  * <p>The default implementation creates a target product instance given the raster size of the
  * (first) source product.
  *
  * @return A new target product instance.
  * @throws OperatorException If the target product cannot be created.
  */
 protected Product createTargetProduct() throws OperatorException {
   Product sourceProduct = getSourceProduct();
   return new Product(
       getId(),
       getClass().getName(),
       sourceProduct.getSceneRasterWidth(),
       sourceProduct.getSceneRasterHeight());
 }
  /**
   * 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()));
  }
예제 #11
0
파일: SubsetOp.java 프로젝트: syedimam/beam
 public static Rectangle computePixelRegion(
     Product product, Geometry geoRegion, int numBorderPixels) {
   final Geometry productGeometry = computeProductGeometry(product);
   final Geometry regionIntersection = geoRegion.intersection(productGeometry);
   if (regionIntersection.isEmpty()) {
     return new Rectangle();
   }
   final PixelRegionFinder pixelRegionFinder = new PixelRegionFinder(product.getGeoCoding());
   regionIntersection.apply(pixelRegionFinder);
   final Rectangle pixelRegion = pixelRegionFinder.getPixelRegion();
   pixelRegion.grow(numBorderPixels, numBorderPixels);
   return pixelRegion.intersection(
       new Rectangle(product.getSceneRasterWidth(), product.getSceneRasterHeight()));
 }
예제 #12
0
  protected void addGeoCoding(Product product) throws IOException {
    GeoPos ulPos = getUpperLeftPosition();
    final Rectangle rect =
        new Rectangle(product.getSceneRasterWidth(), product.getSceneRasterHeight());
    AffineTransform transform = new AffineTransform();
    transform.translate(ulPos.getLon(), ulPos.getLat());
    transform.scale(PIXEL_SIZE_DEG, -PIXEL_SIZE_DEG);
    transform.translate(-PIXEL_CENTER, -PIXEL_CENTER);

    try {
      product.setGeoCoding(new CrsGeoCoding(DefaultGeographicCRS.WGS84, rect, transform));
    } catch (Exception e) {
      throw new IOException("Cannot create GeoCoding: ", e);
    }
  }
예제 #13
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;
 }
예제 #14
0
 private void addMask(
     MetadataAttribute metadataSample, String expression, Color color, Product product) {
   final ProductNodeGroup<Mask> maskGroup = product.getMaskGroup();
   final int width = product.getSceneRasterWidth();
   final int height = product.getSceneRasterHeight();
   Mask mask =
       Mask.BandMathsType.create(
           metadataSample.getName().toLowerCase(),
           metadataSample.getDescription(),
           width,
           height,
           expression,
           color,
           0.5);
   maskGroup.add(mask);
 }
예제 #15
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;
  }
예제 #16
0
  private Product createClostProduct(RenderedOp blueAerosolPanCirrusImage) {

    Product product =
        new Product(
            sourceProduct.getName() + "_clost",
            sourceProduct.getProductType() + " (clost)",
            sourceProduct.getSceneRasterWidth(),
            sourceProduct.getSceneRasterHeight());

    product.setGeoCoding(sourceProduct.getGeoCoding());
    product.setDescription("Product holding Clost Image");

    Band band = product.addBand(CLOST_BAND_NAME, ProductData.TYPE_FLOAT32);
    band.setSourceImage(blueAerosolPanCirrusImage);
    band.setUnit("dl");
    band.setDescription("CLOST Image: aerosol * blue * pan * cirrus ");

    return product;
  }
예제 #17
0
 protected void addBands(Product product, GCTileFile gcTileFile) {
   final List<BandDescriptor> bandDescriptorList = gcTileFile.getBandDescriptorList();
   for (BandDescriptor descriptor : bandDescriptorList) {
     final Band band =
         new Band(
             descriptor.getName(),
             descriptor.getDataType(),
             product.getSceneRasterWidth(),
             product.getSceneRasterHeight());
     band.setScalingFactor(descriptor.getScaleFactor());
     band.setScalingOffset(descriptor.getOffsetValue());
     band.setDescription(descriptor.getDescription());
     band.setUnit(descriptor.getUnit());
     band.setNoDataValueUsed(descriptor.isFillValueUsed());
     band.setNoDataValue(descriptor.getFillValue());
     product.addBand(band);
     band.setSourceImage(getMultiLevelImage(band));
   }
 }
예제 #18
0
  // Creates the output product for the given request.
  private void createOutputProduct(ProgressMonitor pm) throws IOException, ProcessorException {

    // take only the first output product. There might be more but we will ignore
    // these in SMAC.
    ProductRef prod = getRequest().getOutputProductAt(0);
    checkParamNotNull(prod, "output product");

    String productType = _inputProduct.getProductType() + "_SMAC";
    String productName = getOutputProductNameSafe();
    int sceneWidth = _inputProduct.getSceneRasterWidth();
    int sceneHeight = _inputProduct.getSceneRasterHeight();
    _outputProduct = new Product(productName, productType, sceneWidth, sceneHeight);

    ProductWriter writer = ProcessorUtils.createProductWriter(prod);
    _outputProduct.setProductWriter(writer);

    // loop over bands and create them
    // -------------------------------
    if (ObjectUtils.equalObjects(_sensorType, SensorCoefficientManager.MERIS_NAME)) {
      addBandsToOutput("Atmosphere corrected MERIS band ", true);
    } else {
      addBandsToOutput("Atmosphere corrected band ");
    }
    ProductUtils.copyTiePointGrids(_inputProduct, _outputProduct);
    copyRequestMetaData(_outputProduct);
    copyFlagBands(_inputProduct, _outputProduct);

    // for MERIS FSG / FRG products
    copyBand(
        EnvisatConstants.MERIS_AMORGOS_L1B_CORR_LATITUDE_BAND_NAME, _inputProduct, _outputProduct);
    copyBand(
        EnvisatConstants.MERIS_AMORGOS_L1B_CORR_LONGITUDE_BAND_NAME, _inputProduct, _outputProduct);
    copyBand(EnvisatConstants.MERIS_AMORGOS_L1B_ALTIUDE_BAND_NAME, _inputProduct, _outputProduct);

    copyGeoCoding(_inputProduct, _outputProduct);

    // and initialize the disk represenation
    writer.writeProductNodes(_outputProduct, new File(prod.getFilePath()));
    copyBandData(getBandNamesToCopy(), _inputProduct, _outputProduct, pm);
  }
예제 #19
0
  @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);
  }
예제 #20
0
  @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));
    }
  }
예제 #21
0
  public void addGeocoding(Product product) throws IOException {

    double pixelX = 0.5;
    double pixelY = 0.5;
    double easting;
    double northing;
    double pixelSizeX;
    double pixelSizeY;
    boolean pixelRegistered = true;
    if (productReader.getProductType() == SeadasProductReader.ProductType.ANCNRT) {
      pixelRegistered = false;
    }
    if (productReader.getProductType() == SeadasProductReader.ProductType.OISST) {

      Variable lon = ncFile.findVariable("lon");
      Variable lat = ncFile.findVariable("lat");
      Array lonData = lon.read();
      // TODO: handle the 180 degree shift with the NOAA products - need to modify
      // SeaDasFileReader:readBandData
      // Below is a snippet from elsewhere in BEAM that deals with this issue...
      // SPECIAL CASE: check if we have a global geographic lat/lon with lon from 0..360 instead of
      // -180..180
      //            if (isShifted180(lonData)) {
      //                // if this is true, subtract 180 from all longitudes and
      //                // add a global attribute which will be analyzed when setting up the
      // image(s)
      //                final List<Variable> variables = ncFile.getVariables();
      //                for (Variable next : variables) {
      //                    next.getAttributes().add(new Attribute("LONGITUDE_SHIFTED_180", 1));
      //                }
      //                for (int i = 0; i < lonData.getSize(); i++) {
      //                    final Index ii = lonData.getIndex().set(i);
      //                    final double theLon = lonData.getDouble(ii) - 180.0;
      //                    lonData.setDouble(ii, theLon);
      //                }
      //            }
      final Array latData = lat.read();

      final int lonSize = lon.getShape(0);
      final Index i0 = lonData.getIndex().set(0);
      final Index i1 = lonData.getIndex().set(lonSize - 1);

      pixelSizeX =
          (lonData.getDouble(i1) - lonData.getDouble(i0)) / (product.getSceneRasterWidth() - 1);
      easting = lonData.getDouble(i0);

      final int latSize = lat.getShape(0);
      final Index j0 = latData.getIndex().set(0);
      final Index j1 = latData.getIndex().set(latSize - 1);
      pixelSizeY =
          (latData.getDouble(j1) - latData.getDouble(j0)) / (product.getSceneRasterHeight() - 1);

      // this should be the 'normal' case
      if (pixelSizeY < 0) {
        pixelSizeY = -pixelSizeY;
        northing = latData.getDouble(latData.getIndex().set(0));
      } else {
        northing = latData.getDouble(latData.getIndex().set(latSize - 1));
      }
      northing -= pixelSizeX / 2.0;
      easting += pixelSizeY / 2.0;

      try {
        product.setGeoCoding(
            new CrsGeoCoding(
                DefaultGeographicCRS.WGS84,
                product.getSceneRasterWidth(),
                product.getSceneRasterHeight(),
                easting,
                northing,
                pixelSizeX,
                pixelSizeY,
                pixelX,
                pixelY));
      } catch (FactoryException e) {
        throw new IllegalStateException(e);
      } catch (TransformException e) {
        throw new IllegalStateException(e);
      }

    } else {

      String east = "Easternmost_Longitude";
      String west = "Westernmost_Longitude";
      String north = "Northernmost_Latitude";
      String south = "Southernmost_Latitude";
      Attribute latmax = ncFile.findGlobalAttributeIgnoreCase("geospatial_lat_max");
      if (latmax != null) {
        east = "geospatial_lon_max";
        west = "geospatial_lon_min";
        north = "geospatial_lat_max";
        south = "geospatial_lat_min";
      } else {
        latmax = ncFile.findGlobalAttributeIgnoreCase("upper_lat");
        if (latmax != null) {
          east = "right_lon";
          west = "left_lon";
          north = "upper_lat";
          south = "lower_lat";
        }
      }

      final MetadataElement globalAttributes =
          product.getMetadataRoot().getElement("Global_Attributes");
      easting = (float) globalAttributes.getAttribute(east).getData().getElemDouble();
      float westing = (float) globalAttributes.getAttribute(west).getData().getElemDouble();
      pixelSizeX = Math.abs(easting - westing) / product.getSceneRasterWidth();
      northing = (float) globalAttributes.getAttribute(north).getData().getElemDouble();
      float southing = (float) globalAttributes.getAttribute(south).getData().getElemDouble();
      if (northing < southing) {
        mustFlipY = true;
        northing = (float) globalAttributes.getAttribute(south).getData().getElemDouble();
        southing = (float) globalAttributes.getAttribute(north).getData().getElemDouble();
      }
      pixelSizeY = Math.abs(northing - southing) / product.getSceneRasterHeight();
      if (pixelRegistered) {
        northing -= pixelSizeY / 2.0;
        westing += pixelSizeX / 2.0;
      } else {
        pixelX = 0.0;
        pixelY = 0.0;
      }
      try {
        product.setGeoCoding(
            new CrsGeoCoding(
                DefaultGeographicCRS.WGS84,
                product.getSceneRasterWidth(),
                product.getSceneRasterHeight(),
                westing,
                northing,
                pixelSizeX,
                pixelSizeY,
                pixelX,
                pixelY));
      } catch (FactoryException e) {
        throw new IllegalStateException(e);
      } catch (TransformException e) {
        throw new IllegalStateException(e);
      }
    }
  }
예제 #22
0
  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;
  }
예제 #23
0
파일: EnviHeader.java 프로젝트: pmar/nest
  /**
   * Writes the systems byte order to the out stream. In java only high byte first.
   *
   * @param out the stream to write to
   * @param rasterDataNode
   */
  private static void writeMapProjectionInfo(PrintWriter out, RasterDataNode rasterDataNode) {
    Product product = rasterDataNode.getProduct();
    if (product == null) {
      return;
    }

    String mapProjectionName = "Arbitrary";
    String mapUnits = "Meters";
    double referencePixelX = 0, referencePixelY = 0;
    double easting = 0, northing = 0;
    double pixelSizeX = 0, pixelSizeY = 0;
    String datumName = "";
    int utmZone = -1;
    String utmHemisphere = "";
    MapProjection mapProjection = null;

    if (product.getGeoCoding() instanceof CrsGeoCoding) {
      final CrsGeoCoding crsGeoCoding = (CrsGeoCoding) product.getGeoCoding();
      final CoordinateReferenceSystem crs = crsGeoCoding.getMapCRS();

      final ImageGeometry imgGeom =
          ImageGeometry.createTargetGeometry(
              product, crs, null, null, null, null, null, null, null, null, null);

      final String crsName = crs.getName().toString().toUpperCase();
      if (crsName.equals("WGS84(DD)")) {
        mapProjectionName = "Geographic Lat/Lon";
        mapUnits = "Degrees";
      } else if (crsName.contains("UTM")) {
        mapProjectionName = "UTM";
        String zoneStr = crsName.substring(crsName.indexOf("ZONE") + 5, crsName.length()).trim();
        int i = 0;
        String zoneNumStr = "";
        while (Character.isDigit(zoneStr.charAt(i))) {
          zoneNumStr += zoneStr.charAt(i++);
        }
        utmZone = Integer.parseInt(zoneNumStr);

        GeoPos centrePos =
            crsGeoCoding.getGeoPos(
                new PixelPos(product.getSceneRasterWidth() / 2, product.getSceneRasterHeight() / 2),
                null);
        utmHemisphere = centrePos.getLat() > 0 ? "North" : "South";
      }
      referencePixelX = imgGeom.getReferencePixelX();
      referencePixelY = imgGeom.getReferencePixelY();
      easting = imgGeom.getEasting();
      northing = imgGeom.getNorthing();
      pixelSizeX = imgGeom.getPixelSizeX();
      pixelSizeY = imgGeom.getPixelSizeY();
      datumName = crsGeoCoding.getDatum().getName();

    } else if (product.getGeoCoding() instanceof MapGeoCoding) {
      final MapGeoCoding mapGeoCoding = (MapGeoCoding) product.getGeoCoding();

      final MapInfo info = mapGeoCoding.getMapInfo();
      if (info == null) {
        return;
      }
      mapProjection = info.getMapProjection();

      if (mapProjection instanceof UTMProjection) {
        mapProjectionName = "UTM";
        final UTMProjection utmProjection = (UTMProjection) mapProjection;
        utmZone = utmProjection.getZone();
        utmHemisphere = utmProjection.isNorth() ? "North" : "South";
      } else if (mapProjection.isPreDefined()) {
        mapProjectionName = mapProjection.getName();
      }

      if ("meter".equals(mapProjection.getMapUnit())) {
        mapUnits = "Meters";
      } else if ("degree".equals(mapProjection.getMapUnit())) {
        mapUnits = "Degrees";
      } else {
        mapUnits = mapProjection.getMapUnit();
      }

      datumName = mapGeoCoding.getDatum().getName();
    } else {
      return;
    }

    out.print(_enviMapInfo);
    out.print(" = {");
    out.print(mapProjectionName);
    out.print(",");
    out.print(referencePixelX + 1.0f);
    out.print(",");
    out.print(referencePixelY + 1.0f);
    out.print(",");
    out.print(easting);
    out.print(",");
    out.print(northing);
    out.print(",");
    out.print(pixelSizeX);
    out.print(",");
    out.print(pixelSizeY);
    out.print(",");
    if (utmZone != -1) {
      out.print(utmZone);
      out.print(",");
      out.print(utmHemisphere);
      out.print(",");
    }
    out.print(datumName);
    out.print(",");
    out.print("units=" + mapUnits);
    out.print("}");
    out.println();

    if (mapProjection != null && !mapProjection.isPreDefined()) {
      final MapTransform mapTransform = mapProjection.getMapTransform();
      final double[] parameterValues = mapTransform.getParameterValues();
      final String transformName = mapTransform.getDescriptor().getName();
      out.print(_enviProjectionInfo);
      out.print(" = {");
      if (transformName.equals(TransverseMercatorDescriptor.NAME)) {
        out.print(3);
        out.print(",");
        out.print(parameterValues[0]); // semi_major (meters)
        out.print(",");
        out.print(parameterValues[1]); // semi_minor (meters)
        out.print(",");
        out.print(parameterValues[2]); // latitude_of_origin (degree)
        out.print(",");
        out.print(parameterValues[3]); // central_meridian (degree)
        out.print(",");
        out.print(parameterValues[5]); // false_easting (meters)
        out.print(",");
        out.print(parameterValues[6]); // false_northing (meters)
        out.print(",");
        out.print(parameterValues[4]); //  scaling_factor (no unit)
        out.print(",");
      } else if (transformName.equals(LambertConformalConicDescriptor.NAME)) {
        out.print(4);
        out.print(",");
        out.print(parameterValues[0]); // semi_major (meters)
        out.print(",");
        out.print(parameterValues[1]); // semi_minor (meters)
        out.print(",");
        out.print(parameterValues[2]); // latitude_of_origin (degree)
        out.print(",");
        out.print(parameterValues[3]); // central_meridian (degree)
        out.print(",");
        out.print(0.0); // false_easting (meters)
        out.print(",");
        out.print(0.0); // false_northing (meters)
        out.print(",");
        out.print(parameterValues[4]); // latitude_of_intersection_1 (meters)
        out.print(",");
        out.print(parameterValues[5]); // latitude_of_intersection_2 (meters)
        out.print(",");
      }
      out.print(mapProjectionName);
      out.print(",");
      out.print("units=" + mapUnits);
      out.print("}");
      out.println();
    }
  }
예제 #24
0
  private static void updateMetadata(
      final Product sourceProduct, final Product targetProduct, ProductSubsetDef subsetDef)
      throws IOException {

    try {
      final MetadataElement root = targetProduct.getMetadataRoot();
      if (root == null) return;

      final MetadataElement absRoot = root.getElement("Abstracted_Metadata");
      if (absRoot == null) return;

      boolean nearRangeOnLeft = isNearRangeOnLeft(targetProduct);

      final MetadataAttribute firstLineTime = absRoot.getAttribute("first_line_time");
      if (firstLineTime != null) {
        final ProductData.UTC startTime = targetProduct.getStartTime();
        if (startTime != null) firstLineTime.getData().setElems(startTime.getArray());
      }
      final MetadataAttribute lastLineTime = absRoot.getAttribute("last_line_time");
      if (lastLineTime != null) {
        final ProductData.UTC endTime = targetProduct.getEndTime();
        if (endTime != null) lastLineTime.getData().setElems(endTime.getArray());
      }
      final MetadataAttribute totalSize = absRoot.getAttribute("total_size");
      if (totalSize != null) totalSize.getData().setElemUInt(targetProduct.getRawStorageSize());

      if (nearRangeOnLeft) {
        setLatLongMetadata(targetProduct, absRoot, "first_near_lat", "first_near_long", 0.5f, 0.5f);
        setLatLongMetadata(
            targetProduct,
            absRoot,
            "first_far_lat",
            "first_far_long",
            targetProduct.getSceneRasterWidth() - 1 + 0.5f,
            0.5f);

        setLatLongMetadata(
            targetProduct,
            absRoot,
            "last_near_lat",
            "last_near_long",
            0.5f,
            targetProduct.getSceneRasterHeight() - 1 + 0.5f);
        setLatLongMetadata(
            targetProduct,
            absRoot,
            "last_far_lat",
            "last_far_long",
            targetProduct.getSceneRasterWidth() - 1 + 0.5f,
            targetProduct.getSceneRasterHeight() - 1 + 0.5f);
      } else {
        setLatLongMetadata(
            targetProduct,
            absRoot,
            "first_near_lat",
            "first_near_long",
            targetProduct.getSceneRasterWidth() - 1 + 0.5f,
            0.5f);
        setLatLongMetadata(targetProduct, absRoot, "first_far_lat", "first_far_long", 0.5f, 0.5f);

        setLatLongMetadata(
            targetProduct,
            absRoot,
            "last_near_lat",
            "last_near_long",
            targetProduct.getSceneRasterWidth() - 1 + 0.5f,
            targetProduct.getSceneRasterHeight() - 1 + 0.5f);
        setLatLongMetadata(
            targetProduct,
            absRoot,
            "last_far_lat",
            "last_far_long",
            0.5f,
            targetProduct.getSceneRasterHeight() - 1 + 0.5f);
      }

      final MetadataAttribute height = absRoot.getAttribute("num_output_lines");
      if (height != null) height.getData().setElemUInt(targetProduct.getSceneRasterHeight());

      final MetadataAttribute width = absRoot.getAttribute("num_samples_per_line");
      if (width != null) width.getData().setElemUInt(targetProduct.getSceneRasterWidth());

      final MetadataAttribute offsetX = absRoot.getAttribute("subset_offset_x");
      if (offsetX != null && subsetDef.getRegion() != null)
        offsetX.getData().setElemUInt(subsetDef.getRegion().x);

      final MetadataAttribute offsetY = absRoot.getAttribute("subset_offset_y");
      if (offsetY != null && subsetDef.getRegion() != null)
        offsetY.getData().setElemUInt(subsetDef.getRegion().y);

      final MetadataAttribute slantRange = absRoot.getAttribute("slant_range_to_first_pixel");
      if (slantRange != null) {
        final TiePointGrid srTPG = targetProduct.getTiePointGrid("slant_range_time");
        if (srTPG != null) {
          final double slantRangeTime;
          if (nearRangeOnLeft) {
            slantRangeTime = srTPG.getPixelDouble(0, 0) / 1000000000.0; // ns to s
          } else {
            slantRangeTime =
                srTPG.getPixelDouble(targetProduct.getSceneRasterWidth() - 1, 0)
                    / 1000000000.0; // ns to s
          }
          final double halfLightSpeed = 299792458.0 / 2.0;
          final double slantRangeDist = slantRangeTime * halfLightSpeed;
          slantRange.getData().setElemDouble(slantRangeDist);
        }
      }

      setSubsetSRGRCoefficients(sourceProduct, targetProduct, subsetDef, absRoot, nearRangeOnLeft);
    } catch (Exception e) {
      throw new IOException(e);
    }
  }
예제 #25
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));
    }
  }
예제 #26
0
 private void getSourceImageDimension() {
   sourceImageWidth = sourceProduct.getSceneRasterWidth();
   sourceImageHeight = sourceProduct.getSceneRasterHeight();
 }
  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);
  }