Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/8.x' into 8.x
Browse files Browse the repository at this point in the history
# Conflicts:
#	idepix-meris/pom.xml
  • Loading branch information
marpet committed Jul 22, 2021
2 parents fc63e51 + ef53803 commit 4fa5ef9
Show file tree
Hide file tree
Showing 11 changed files with 1,006 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ public static void addRadianceBands(Product l1bProduct, Product targetProduct, S
}
}

public static boolean isMeris4thReprocessingL1bProduct(String productType) {
return productType.startsWith("ME_1"); // todo: discuss this criterion
}

/// END of public ///

static boolean isValidLandsat8Product(Product product) {
Expand Down Expand Up @@ -194,7 +198,11 @@ private static boolean isValidMerisProduct(Product product) {
// accept also ICOL L1N products...
final boolean merisIcolTypePatternMatches = isValidMerisIcolL1NProduct(product);
final boolean merisCCL1PTypePatternMatches = isValidMerisCCL1PProduct(product);
return merisL1TypePatternMatches || merisIcolTypePatternMatches || merisCCL1PTypePatternMatches;
// now accept also 4th reprocessing products (20210126):
final boolean meris4thReproTypePatternMatches = isValidMeris4thReprocessingL1bProduct(product);

return merisL1TypePatternMatches || merisIcolTypePatternMatches ||
merisCCL1PTypePatternMatches || meris4thReproTypePatternMatches;
}

private static boolean isValidOlciProduct(Product product) {
Expand All @@ -217,6 +225,10 @@ private static boolean isValidMerisIcolL1NProduct(Product product) {
}
}

private static boolean isValidMeris4thReprocessingL1bProduct(Product product) {
return isMeris4thReprocessingL1bProduct(product.getProductType()); // todo: discuss this criterion
}

private static boolean isValidMerisCCL1PProduct(Product product) {
return IdepixConstants.MERIS_CCL1P_TYPE_PATTERN.matcher(product.getProductType()).matches();
}
Expand Down
8 changes: 8 additions & 0 deletions idepix-meris/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@
<groupId>org.esa.snap</groupId>
<artifactId>ceres-core</artifactId>
</dependency>
<dependency>
<groupId>org.esa.snap</groupId>
<artifactId>ceres-glayer</artifactId>
</dependency>
<dependency>
<groupId>org.esa.snap</groupId>
<artifactId>ceres-jai</artifactId>
</dependency>
<dependency>
<groupId>org.esa.snap</groupId>
<artifactId>snap-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.esa.snap.core.datamodel.Band;
import org.esa.snap.core.datamodel.Product;
import org.esa.snap.core.datamodel.ProductData;
import org.esa.snap.core.gpf.GPF;
import org.esa.snap.core.gpf.OperatorException;
import org.esa.snap.core.gpf.OperatorSpi;
Expand All @@ -10,27 +11,26 @@
import org.esa.snap.core.gpf.annotations.SourceProduct;
import org.esa.snap.core.gpf.annotations.TargetProduct;
import org.esa.snap.core.util.ProductUtils;

import org.esa.snap.idepix.core.AlgorithmSelector;
import org.esa.snap.idepix.core.IdepixConstants;
import org.esa.snap.idepix.core.operators.BasisOp;
import org.esa.snap.idepix.core.operators.CloudBufferOp;
import org.esa.snap.idepix.core.util.IdepixIO;
import org.esa.snap.idepix.meris.reprocessing.Meris3rd4thReprocessingAdapter;

import java.util.HashMap;
import java.util.Map;

/**
* The IdePix pixel classification operator for MERIS products.
*
*
* @author olafd
*/
@OperatorMetadata(alias = "Idepix.Meris",
category = "Optical/Pre-Processing",
version = "3.0",
version = "3.1",
authors = "Olaf Danne",
copyright = "(c) 2016 by Brockmann Consult",
copyright = "(c) 2016-2021 by Brockmann Consult",
description = "Pixel identification and classification for MERIS.")
public class IdepixMerisOp extends BasisOp {

Expand Down Expand Up @@ -124,6 +124,8 @@ public class IdepixMerisOp extends BasisOp {
private Product ctpProduct;
private Product waterMaskProduct;

private Product inputProductToProcess;

private Map<String, Product> classificationInputProducts;
private Map<String, Object> waterClassificationParameters;
private Map<String, Object> landClassificationParameters;
Expand All @@ -135,6 +137,14 @@ public void initialize() throws OperatorException {
throw new OperatorException(IdepixConstants.INPUT_INCONSISTENCY_ERROR_MESSAGE);
}

if (IdepixIO.isMeris4thReprocessingL1bProduct(sourceProduct.getProductType())) {
// adapt to 3rd reprocessing...
Meris3rd4thReprocessingAdapter reprocessingAdapter = new Meris3rd4thReprocessingAdapter();
inputProductToProcess = reprocessingAdapter.convertToLowerVersion(sourceProduct);
} else {
inputProductToProcess = sourceProduct;
}

outputRadiance = radianceBandsToCopy != null && radianceBandsToCopy.length > 0;
outputRad2Refl = reflBandsToCopy != null && reflBandsToCopy.length > 0;

Expand All @@ -153,61 +163,81 @@ public void initialize() throws OperatorException {
cloudFlagBand.setSourceImage(postProcessingProduct.getBand(IdepixConstants.CLASSIF_BAND_NAME).getSourceImage());

copyOutputBands();
ProductUtils.copyFlagBands(sourceProduct, targetProduct, true); // we need the L1b flag!
if (!IdepixIO.isMeris4thReprocessingL1bProduct(sourceProduct.getProductType())) {
ProductUtils.copyFlagBands(inputProductToProcess, targetProduct, true); // we need the L1b flag!
}
}

// @Override
public void initialize_test() throws OperatorException {
final int[] testUInt8s = new int[]{1, 2, 3, 4, 5, 6};

Product targetProduct = new Product("x", "NO_TYPE", 3, 2);

Band bandUInt8 = new Band("bandUInt8", ProductData.TYPE_UINT8, 3, 2);
bandUInt8.ensureRasterData();
bandUInt8.setPixels(0, 0, 3, 2, testUInt8s);
bandUInt8.setSourceImage(bandUInt8.getSourceImage());
// alternative: this works certainly for INT32, but not as it is for UINT8
// bandUInt8.setSourceImage(ImageUtils.createRenderedImage(3, 2, ProductData.createInstance(testUInt8s)));
targetProduct.addBand(bandUInt8);
setTargetProduct(targetProduct);
}

private void preProcess() {
rad2reflProduct = IdepixMerisUtils.computeRadiance2ReflectanceProduct(sourceProduct);
ctpProduct = IdepixMerisUtils.computeCloudTopPressureProduct(sourceProduct);
rad2reflProduct = IdepixMerisUtils.computeRadiance2ReflectanceProduct(inputProductToProcess);
if (computeCloudShadow) {
ctpProduct = IdepixMerisUtils.computeCloudTopPressureProduct(inputProductToProcess);
}

HashMap<String, Object> waterMaskParameters = new HashMap<>();
waterMaskParameters.put("resolution", IdepixConstants.LAND_WATER_MASK_RESOLUTION);
waterMaskParameters.put("subSamplingFactorX", IdepixConstants.OVERSAMPLING_FACTOR_X);
waterMaskParameters.put("subSamplingFactorY", IdepixConstants.OVERSAMPLING_FACTOR_Y);
waterMaskProduct = GPF.createProduct("LandWaterMask", waterMaskParameters, sourceProduct);
waterMaskProduct = GPF.createProduct("LandWaterMask", waterMaskParameters, inputProductToProcess);
}

private void setLandClassificationParameters() {
landClassificationParameters = new HashMap<>();
landClassificationParameters.put("copyAllTiePoints", true);
landClassificationParameters.put("outputSchillerNNValue",
outputSchillerNNValue);
outputSchillerNNValue);
landClassificationParameters.put("ccSchillerNNCloudAmbiguousLowerBoundaryValue",
schillerLandNNCloudAmbiguousLowerBoundaryValue);
schillerLandNNCloudAmbiguousLowerBoundaryValue);
landClassificationParameters.put("ccSchillerNNCloudAmbiguousSureSeparationValue",
schillerLandNNCloudAmbiguousSureSeparationValue);
schillerLandNNCloudAmbiguousSureSeparationValue);
landClassificationParameters.put("ccSchillerNNCloudSureSnowSeparationValue",
schillerLandNNCloudSureSnowSeparationValue);
schillerLandNNCloudSureSnowSeparationValue);
}

private void setWaterClassificationParameters() {
waterClassificationParameters = new HashMap<>();
waterClassificationParameters.put("copyAllTiePoints", true);
waterClassificationParameters.put("outputSchillerNNValue",
outputSchillerNNValue);
outputSchillerNNValue);
waterClassificationParameters.put("ccSchillerNNCloudAmbiguousLowerBoundaryValue",
schillerWaterNNCloudAmbiguousLowerBoundaryValue);
schillerWaterNNCloudAmbiguousLowerBoundaryValue);
waterClassificationParameters.put("ccSchillerNNCloudAmbiguousSureSeparationValue",
schillerWaterNNCloudAmbiguousSureSeparationValue);
schillerWaterNNCloudAmbiguousSureSeparationValue);
waterClassificationParameters.put("ccSchillerNNCloudSureSnowSeparationValue",
schillerWaterNNCloudSureSnowSeparationValue);
schillerWaterNNCloudSureSnowSeparationValue);
}

private void computeWaterCloudProduct() {
setWaterClassificationParameters();
classificationInputProducts = new HashMap<>();
classificationInputProducts.put("l1b", sourceProduct);
classificationInputProducts.put("l1b", inputProductToProcess);
classificationInputProducts.put("rhotoa", rad2reflProduct);
classificationInputProducts.put("waterMask", waterMaskProduct);

waterClassificationProduct = GPF.createProduct(OperatorSpi.getOperatorAlias(IdepixMerisWaterClassificationOp.class),
waterClassificationParameters, classificationInputProducts);
waterClassificationParameters, classificationInputProducts);
}

private void computeLandCloudProduct() {
setLandClassificationParameters();
landClassificationProduct = GPF.createProduct(OperatorSpi.getOperatorAlias(IdepixMerisLandClassificationOp.class),
landClassificationParameters, classificationInputProducts);
landClassificationParameters, classificationInputProducts);
}

private void mergeLandWater() {
Expand All @@ -218,12 +248,12 @@ private void mergeLandWater() {
Map<String, Object> mergeClassificationParameters = new HashMap<>();
mergeClassificationParameters.put("copyAllTiePoints", true);
mergedClassificationProduct = GPF.createProduct(OperatorSpi.getOperatorAlias(IdepixMerisMergeLandWaterOp.class),
mergeClassificationParameters, mergeInputProducts);
mergeClassificationParameters, mergeInputProducts);
}

private void postProcess() {
HashMap<String, Product> input = new HashMap<>();
input.put("l1b", sourceProduct);
input.put("l1b", inputProductToProcess);
input.put("merisCloud", mergedClassificationProduct);
input.put("ctp", ctpProduct);
input.put("waterMask", waterMaskProduct);
Expand All @@ -233,25 +263,25 @@ private void postProcess() {
params.put("refineClassificationNearCoastlines", true); // always an improvement

final Product classifiedProduct = GPF.createProduct(OperatorSpi.getOperatorAlias(IdepixMerisPostProcessOp.class),
params, input);
params, input);

if (computeCloudBuffer) {
input = new HashMap<>();
input.put("classifiedProduct", classifiedProduct);
params = new HashMap<>();
params.put("cloudBufferWidth", cloudBufferWidth);
postProcessingProduct = GPF.createProduct(OperatorSpi.getOperatorAlias(CloudBufferOp.class),
params, input);
params, input);
} else {
postProcessingProduct = classifiedProduct;
}
}

private void copyOutputBands() {
ProductUtils.copyMetadata(sourceProduct, targetProduct);
ProductUtils.copyMetadata(inputProductToProcess, targetProduct);
IdepixMerisUtils.setupMerisClassifBitmask(targetProduct);
if (outputRadiance) {
IdepixIO.addRadianceBands(sourceProduct, targetProduct, radianceBandsToCopy);
IdepixIO.addRadianceBands(inputProductToProcess, targetProduct, radianceBandsToCopy);
}
if (outputRad2Refl) {
IdepixMerisUtils.addMerisRadiance2ReflectanceBands(rad2reflProduct, targetProduct, reflBandsToCopy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ public class IdepixMerisPostProcessOp extends Operator {
private Product l1bProduct;
@SourceProduct(alias = "merisCloud")
private Product merisCloudProduct;
// @SourceProduct(alias = "ctp", optional = true)
@SourceProduct(alias = "ctp")
@SourceProduct(alias = "ctp", optional = true)
// @SourceProduct(alias = "ctp")
private Product ctpProduct;
@SourceProduct(alias = "waterMask")
private Product waterMaskProduct;
Expand Down Expand Up @@ -80,7 +80,9 @@ public void initialize() throws OperatorException {
szaTPG = l1bProduct.getTiePointGrid(EnvisatConstants.MERIS_SUN_ZENITH_DS_NAME);
saaTPG = l1bProduct.getTiePointGrid(EnvisatConstants.MERIS_SUN_AZIMUTH_DS_NAME);
altTPG = l1bProduct.getTiePointGrid(EnvisatConstants.MERIS_DEM_ALTITUDE_DS_NAME);
ctpBand = ctpProduct.getBand("cloud_top_press");
if (ctpProduct != null) {
ctpBand = ctpProduct.getBand("cloud_top_press");
}

int extendedWidth;
int extendedHeight;
Expand Down Expand Up @@ -110,7 +112,10 @@ public void computeTile(Band targetBand, final Tile targetTile, ProgressMonitor
final Tile sourceFlagTile = getSourceTile(origCloudFlagBand, srcRectangle);
Tile szaTile = getSourceTile(szaTPG, srcRectangle);
Tile saaTile = getSourceTile(saaTPG, srcRectangle);
Tile ctpTile = getSourceTile(ctpBand, srcRectangle);
Tile ctpTile = null;
if (ctpBand != null) {
ctpTile = getSourceTile(ctpBand, srcRectangle);
}

Tile altTile = getSourceTile(altTPG, targetRectangle);
final Tile waterFractionTile = getSourceTile(waterFractionBand, srcRectangle);
Expand Down
Loading

0 comments on commit 4fa5ef9

Please sign in to comment.