Skip to content

Commit a9022bb

Browse files
committed
Idepix OLCI/SLSTR: combined cloud mask: OLCI NN || SLSTR cloud_an 1.37 thresh test || SLSTR cloud_an gross cloud; some cleanup
1 parent 2556a2f commit a9022bb

File tree

4 files changed

+27
-116
lines changed

4 files changed

+27
-116
lines changed

idepix-olcislstr/src/main/java/org/esa/snap/idepix/olcislstr/OlciSlstrClassificationOp.java

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ public class OlciSlstrClassificationOp extends Operator {
4545
@SourceProduct(alias = "reflOlci")
4646
private Product olciRad2reflProduct;
4747

48-
@SourceProduct(alias = "reflSlstr")
49-
private Product slstrRad2reflProduct;
50-
5148
@SourceProduct(alias = "waterMask")
5249
private Product waterMaskProduct;
5350

@@ -58,7 +55,6 @@ public class OlciSlstrClassificationOp extends Operator {
5855
Band cloudFlagBand;
5956

6057
private Band[] olciReflBands;
61-
private Band[] slstrReflBands;
6258

6359
private Band landWaterBand;
6460

@@ -94,16 +90,6 @@ public void setBands() {
9490
olciReflBands[i] = olciRad2reflProduct.getBand(reflBandname + "_reflectance");
9591
}
9692

97-
// e.g. S4_reflectance_an
98-
//make sure that these are all *_an bands, as the NN uses only these
99-
slstrReflBands = new Band[OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES.length];
100-
for (int i = 0; i < OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES.length; i++) {
101-
final int suffixStart = OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES[i].indexOf("_");
102-
final String reflBandname = OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES[i].substring(0, suffixStart);
103-
final int length = OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES[i].length();
104-
slstrReflBands[i] = slstrRad2reflProduct.getBand(reflBandname + "_reflectance_an");
105-
}
106-
10793
landWaterBand = waterMaskProduct.getBand("land_water_fraction");
10894
}
10995

@@ -141,18 +127,15 @@ public void computeTileStack(Map<Band, Tile> targetTiles, Rectangle rectangle, P
141127
final Band olciQualityFlagBand = sourceProduct.getBand(OlciSlstrConstants.OLCI_QUALITY_FLAGS_BAND_NAME);
142128
final Tile olciQualityFlagTile = getSourceTile(olciQualityFlagBand, rectangle);
143129

130+
final Band slstrCloudAnFlagBand = sourceProduct.getBand(OlciSlstrConstants.SLSTR_CLOUD_AN_FLAG_BAND_NAME);
131+
final Tile slstrCloudAnFlagTile = getSourceTile(slstrCloudAnFlagBand, rectangle);
132+
144133
Tile[] olciReflectanceTiles = new Tile[Rad2ReflConstants.OLCI_REFL_BAND_NAMES.length];
145134
float[] olciReflectance = new float[Rad2ReflConstants.OLCI_REFL_BAND_NAMES.length];
146135
for (int i = 0; i < Rad2ReflConstants.OLCI_REFL_BAND_NAMES.length; i++) {
147136
olciReflectanceTiles[i] = getSourceTile(olciReflBands[i], rectangle);
148137
}
149138

150-
Tile[] slstrReflectanceTiles = new Tile[OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES.length];
151-
float[] slstrReflectance = new float[OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES.length];
152-
for (int i = 0; i < OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES.length; i++) {
153-
slstrReflectanceTiles[i] = getSourceTile(slstrReflBands[i], rectangle);
154-
}
155-
156139
final Band cloudFlagTargetBand = targetProduct.getBand(IdepixConstants.CLASSIF_BAND_NAME);
157140
final Tile cloudFlagTargetTile = targetTiles.get(cloudFlagTargetBand);
158141

@@ -177,24 +160,18 @@ public void computeTileStack(Map<Band, Tile> targetTiles, Rectangle rectangle, P
177160
olciReflectance[i] = olciReflectanceTiles[i].getSampleFloat(x, y);
178161
}
179162

180-
for (int i = 0; i < OlciSlstrConstants.SLSTR_REFL_AN_BAND_NAMES.length; i++) {
181-
slstrReflectance[i] = slstrReflectanceTiles[i].getSampleFloat(x, y);
182-
}
183-
184163
final boolean l1Invalid = olciQualityFlagTile.getSampleBit(x, y, OlciSlstrConstants.L1_F_INVALID);
185164
boolean reflectancesValid = IdepixIO.areAllReflectancesValid(olciReflectance);
186-
reflectancesValid &= IdepixIO.areAllReflectancesValid(slstrReflectance);
187165
cloudFlagTargetTile.setSample(x, y, IdepixConstants.IDEPIX_INVALID, l1Invalid || !reflectancesValid);
188166

167+
final boolean isSlstrCloudAn137Thresh =
168+
slstrCloudAnFlagTile.getSampleBit(x, y, OlciSlstrConstants.CLOUD_AN_F_137_THRESH);
169+
final boolean isSlstrCloudAnGrossCloud =
170+
slstrCloudAnFlagTile.getSampleBit(x, y, OlciSlstrConstants.CLOUD_AN_F_GROSS_CLOUD);
171+
189172
if (reflectancesValid) {
190173
SchillerNeuralNetWrapper nnWrapper = olciSlstrAllNeuralNet.get();
191174
double[] inputVector = nnWrapper.getInputVector();
192-
// for (int i = 0; i < inputVector.length - 6; i++) {
193-
// inputVector[i] = Math.sqrt(olciReflectance[i]);
194-
// }
195-
// for (int i = inputVector.length - slstrReflectance.length; i < inputVector.length; i++) {
196-
// inputVector[i] = Math.sqrt(slstrReflectance[i - olciReflectance.length]);
197-
// }
198175
// use OLCI net instead of OLCI/SLSTR net:
199176
for (int i = 0; i < inputVector.length; i++) {
200177
inputVector[i] = Math.sqrt(olciReflectance[i]);
@@ -216,7 +193,11 @@ public void computeTileStack(Map<Band, Tile> targetTiles, Rectangle rectangle, P
216193

217194
cloudFlagTargetTile.setSample(x, y, IdepixConstants.IDEPIX_CLOUD_AMBIGUOUS, cloudAmbiguous);
218195
cloudFlagTargetTile.setSample(x, y, IdepixConstants.IDEPIX_CLOUD_SURE, cloudSure);
196+
// request RQ, GK, 20220111:
197+
final boolean isSynCloud = cloudAmbiguous || cloudSure || isSlstrCloudAn137Thresh ||
198+
isSlstrCloudAnGrossCloud;
219199
cloudFlagTargetTile.setSample(x, y, IdepixConstants.IDEPIX_CLOUD, cloudAmbiguous || cloudSure);
200+
cloudFlagTargetTile.setSample(x, y, IdepixConstants.IDEPIX_CLOUD, isSynCloud);
220201
cloudFlagTargetTile.setSample(x, y, IdepixConstants.IDEPIX_SNOW_ICE, nnInterpreter.isSnowIce(nnOutput));
221202
}
222203

idepix-olcislstr/src/main/java/org/esa/snap/idepix/olcislstr/OlciSlstrConstants.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ class OlciSlstrConstants {
1212
static final int L1_F_INVALID = 25;
1313
// static final int L1_F_GLINT = 22;
1414

15-
static final String OLCI_QUALITY_FLAGS_BAND_NAME = "quality_flags";
15+
/* SLSTR Cloud AN Flags Positions */
16+
static final int CLOUD_AN_F_137_THRESH = 1;
17+
static final int CLOUD_AN_F_GROSS_CLOUD = 7;
1618

17-
final static String[] SLSTR_REFL_AN_BAND_NAMES = new String[]{
18-
"S1_reflectance_an", "S2_reflectance_an", "S3_reflectance_an",
19-
"S4_reflectance_an", "S5_reflectance_an", "S6_reflectance_an"
20-
};
19+
static final String OLCI_QUALITY_FLAGS_BAND_NAME = "quality_flags";
20+
static final String SLSTR_CLOUD_AN_FLAG_BAND_NAME = "cloud_an";
2121

2222
// todo: RENOVATION: code duplication, move to core
2323
static final double[] referencePressureLevels = {

idepix-olcislstr/src/main/java/org/esa/snap/idepix/olcislstr/OlciSlstrOp.java

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@ public class OlciSlstrOp extends BasisOp {
4242
private Product targetProduct;
4343

4444
private boolean outputOlciRadiance;
45-
private boolean outputOlciRad2Refl;
4645
private boolean outputSlstrRadiance;
47-
private boolean outputSlstrRad2Refl;
4846

4947
@Parameter(description = "The list of OLCI radiance bands to write to target product.",
5048
label = "Select OLCI TOA radiances to write to the target product",
@@ -58,18 +56,6 @@ public class OlciSlstrOp extends BasisOp {
5856
defaultValue = "")
5957
private String[] olciRadianceBandsToCopy;
6058

61-
@Parameter(description = "The list of OLCI reflectance bands to write to target product.",
62-
label = "Select OLCI TOA reflectances to write to the target product",
63-
valueSet = {
64-
"Oa01_reflectance", "Oa02_reflectance", "Oa03_reflectance", "Oa04_reflectance", "Oa05_reflectance",
65-
"Oa06_reflectance", "Oa07_reflectance", "Oa08_reflectance", "Oa09_reflectance", "Oa10_reflectance",
66-
"Oa11_reflectance", "Oa12_reflectance", "Oa13_reflectance", "Oa14_reflectance", "Oa15_reflectance",
67-
"Oa16_reflectance", "Oa17_reflectance", "Oa18_reflectance", "Oa19_reflectance", "Oa20_reflectance",
68-
"Oa21_reflectance"
69-
},
70-
defaultValue = "")
71-
private String[] olciReflBandsToCopy;
72-
7359
@Parameter(description = "The list of SLSTR radiance bands to write to target product.",
7460
label = "Select SLSTR TOA radiances to write to the target product",
7561
valueSet = {
@@ -81,22 +67,6 @@ public class OlciSlstrOp extends BasisOp {
8167
defaultValue = "")
8268
private String[] slstrRadianceBandsToCopy;
8369

84-
@Parameter(description = "The list of SLSTR reflectance bands to write to target product.",
85-
label = "Select SLSTR TOA reflectances to write to the target product",
86-
valueSet = {
87-
"S1_reflectance_an", "S2_reflectance_an", "S3_reflectance_an",
88-
"S4_reflectance_an", "S5_reflectance_an", "S6_reflectance_an",
89-
"S4_reflectance_bn", "S5_reflectance_bn", "S6_reflectance_bn",
90-
"S4_reflectance_cn", "S5_reflectance_cn", "S6_reflectance_cn"
91-
},
92-
defaultValue = "")
93-
private String[] slstrReflBandsToCopy;
94-
95-
@Parameter(defaultValue = "false",
96-
label = " Copy cloud-related SLSTR flag bands to the target product",
97-
description = " If applied, cloud-related SLSTR flag bands and masks are copied to the target product ")
98-
private boolean copySlstrCloudFlagBands;
99-
10070
@Parameter(defaultValue = "false",
10171
label = " Write NN value to the target product",
10272
description = " If applied, write NN value to the target product ")
@@ -119,7 +89,6 @@ public class OlciSlstrOp extends BasisOp {
11989
private Product postProcessingProduct;
12090

12191
private Product olciRad2reflProduct;
122-
private Product slstrRad2reflProduct;
12392
private Product ctpProduct;
12493
private Product waterMaskProduct;
12594

@@ -135,10 +104,8 @@ public void initialize() throws OperatorException {
135104
}
136105

137106
outputOlciRadiance = olciRadianceBandsToCopy != null && olciRadianceBandsToCopy.length > 0;
138-
outputOlciRad2Refl = olciReflBandsToCopy != null && olciReflBandsToCopy.length > 0;
139107

140108
outputSlstrRadiance = slstrRadianceBandsToCopy != null && slstrRadianceBandsToCopy.length > 0;
141-
outputSlstrRad2Refl = slstrReflBandsToCopy != null && slstrReflBandsToCopy.length > 0;
142109

143110
preProcess();
144111

@@ -148,9 +115,7 @@ public void initialize() throws OperatorException {
148115
olciSlstrIdepixProduct.setName(sourceProduct.getName() + "_IDEPIX");
149116
olciSlstrIdepixProduct.setAutoGrouping("Oa*_radiance:Oa*_reflectance:S*_radiance:S*_reflectance");
150117

151-
if (copySlstrCloudFlagBands) {
152-
OlciSlstrUtils.copySlstrCloudFlagBands(sourceProduct, olciSlstrIdepixProduct);
153-
}
118+
OlciSlstrUtils.copySlstrCloudFlagBands(sourceProduct, olciSlstrIdepixProduct);
154119

155120
if (computeCloudBuffer || computeCloudShadow) {
156121
postProcess(olciSlstrIdepixProduct);
@@ -186,18 +151,10 @@ private Product createTargetProduct(Product idepixProduct) {
186151
IdepixIO.addRadianceBands(sourceProduct, targetProduct, olciRadianceBandsToCopy);
187152
}
188153

189-
if (outputOlciRad2Refl) {
190-
OlciSlstrUtils.addOlciRadiance2ReflectanceBands(olciRad2reflProduct, targetProduct, olciReflBandsToCopy);
191-
}
192-
193154
if (outputSlstrRadiance) {
194155
IdepixIO.addRadianceBands(sourceProduct, targetProduct, slstrRadianceBandsToCopy);
195156
}
196157

197-
if (outputSlstrRad2Refl) {
198-
OlciSlstrUtils.addSlstrRadiance2ReflectanceBands(slstrRad2reflProduct, targetProduct, slstrReflBandsToCopy);
199-
}
200-
201158
if (outputSchillerNNValue) {
202159
ProductUtils.copyBand(IdepixConstants.NN_OUTPUT_BAND_NAME, idepixProduct, targetProduct, true);
203160
}
@@ -207,7 +164,6 @@ private Product createTargetProduct(Product idepixProduct) {
207164

208165
private void preProcess() {
209166
olciRad2reflProduct = OlciSlstrUtils.computeRadiance2ReflectanceProduct(sourceProduct, Sensor.OLCI);
210-
slstrRad2reflProduct = OlciSlstrUtils.computeRadiance2ReflectanceProduct(sourceProduct, Sensor.SLSTR_500m);
211167

212168
HashMap<String, Object> waterMaskParameters = new HashMap<>();
213169
waterMaskParameters.put("resolution", IdepixConstants.LAND_WATER_MASK_RESOLUTION);
@@ -230,7 +186,6 @@ private void setClassificationInputProducts() {
230186
classificationInputProducts = new HashMap<>();
231187
classificationInputProducts.put("l1b", sourceProduct);
232188
classificationInputProducts.put("reflOlci", olciRad2reflProduct);
233-
classificationInputProducts.put("reflSlstr", slstrRad2reflProduct);
234189
classificationInputProducts.put("waterMask", waterMaskProduct);
235190
}
236191

idepix-olcislstr/src/main/java/org/esa/snap/idepix/olcislstr/OlciSlstrUtils.java

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
package org.esa.snap.idepix.olcislstr;
22

33
import com.bc.ceres.core.ProgressMonitor;
4+
import org.esa.s3tbx.processor.rad2refl.Rad2ReflOp;
5+
import org.esa.s3tbx.processor.rad2refl.Sensor;
46
import org.esa.snap.core.datamodel.*;
7+
import org.esa.snap.core.gpf.GPF;
8+
import org.esa.snap.core.gpf.OperatorSpi;
59
import org.esa.snap.core.util.Guardian;
10+
import org.esa.snap.core.util.ProductUtils;
611
import org.esa.snap.core.util.ResourceInstaller;
712
import org.esa.snap.core.util.SystemUtils;
813
import org.esa.snap.core.util.math.MathUtils;
914
import org.esa.snap.idepix.core.IdepixConstants;
1015
import org.esa.snap.idepix.core.IdepixFlagCoding;
11-
import org.esa.s3tbx.processor.rad2refl.Rad2ReflConstants;
12-
import org.esa.s3tbx.processor.rad2refl.Rad2ReflOp;
13-
import org.esa.s3tbx.processor.rad2refl.Sensor;
14-
import org.esa.snap.core.gpf.GPF;
15-
import org.esa.snap.core.gpf.OperatorSpi;
16-
import org.esa.snap.core.util.ProductUtils;
1716

1817
import java.io.IOException;
1918
import java.nio.file.Path;
@@ -61,30 +60,6 @@ static void setupOlciClassifBitmask(Product classifProduct) {
6160
IdepixFlagCoding.setupDefaultClassifBitmask(classifProduct);
6261
}
6362

64-
static void addOlciRadiance2ReflectanceBands(Product rad2reflProduct, Product targetProduct, String[] reflBandsToCopy) {
65-
for (int i = 1; i <= Rad2ReflConstants.OLCI_REFL_BAND_NAMES.length; i++) {
66-
for (String bandname : reflBandsToCopy) {
67-
// e.g. Oa01_reflectance
68-
if (!targetProduct.containsBand(bandname) && bandname.equals("Oa" + String.format("%02d", i) + "_reflectance")) {
69-
ProductUtils.copyBand(bandname, rad2reflProduct, targetProduct, true);
70-
targetProduct.getBand(bandname).setUnit("dl");
71-
}
72-
}
73-
}
74-
}
75-
76-
static void addSlstrRadiance2ReflectanceBands(Product rad2reflProduct, Product targetProduct, String[] reflBandsToCopy) {
77-
for (int i = 1; i <= Rad2ReflConstants.SLSTR_REFL_BAND_NAMES.length; i++) {
78-
for (String bandname : reflBandsToCopy) {
79-
// e.g. S1_reflectance_an
80-
if (!targetProduct.containsBand(bandname) && bandname.startsWith("S" + String.format("%01d", i) + "_reflectance")) {
81-
ProductUtils.copyBand(bandname, rad2reflProduct, targetProduct, true);
82-
targetProduct.getBand(bandname).setUnit("dl");
83-
}
84-
}
85-
}
86-
}
87-
8863
static Product computeRadiance2ReflectanceProduct(Product sourceProduct, Sensor sensor) {
8964
Map<String, Object> params = new HashMap<>(2);
9065
params.put("sensor", sensor);
@@ -107,8 +82,8 @@ public static void copySlstrCloudFlagBands(Product sourceProduct, Product target
10782
for (int i = 0; i < sourceProduct.getNumBands(); i++) {
10883
Band sourceBand = sourceProduct.getBandAt(i);
10984
String bandName = sourceBand.getName();
110-
// Use prefix 'cloud_' as identifier for SLSTR cloud flag band and copy only those.
111-
if (bandName.startsWith("cloud_") && sourceBand.isFlagBand() && targetProduct.getBand(bandName) == null) {
85+
// copy SLSTR 'cloud_an' flag band only, 20220113
86+
if (bandName.startsWith("cloud_an") && sourceBand.isFlagBand() && targetProduct.getBand(bandName) == null) {
11287
ProductUtils.copyBand(bandName, sourceProduct, targetProduct, true);
11388
}
11489
}
@@ -117,7 +92,6 @@ public static void copySlstrCloudFlagBands(Product sourceProduct, Product target
11792
// other wise the referenced bands, e.g. flag band, is not contained in the target product
11893
// and the mask is not copied
11994
copySlstrCloudMasks(sourceProduct, targetProduct);
120-
// ProductUtils.copyOverlayMasks(sourceProduct, targetProduct);
12195
}
12296
}
12397

@@ -127,7 +101,8 @@ private static void copySlstrCloudMasks(Product sourceProduct, Product targetPro
127101
for(int i = 0; i < sourceMaskGroup.getNodeCount(); ++i) {
128102
Mask mask = sourceMaskGroup.get(i);
129103
System.out.println("mask: " + mask.getName());
130-
final boolean isSlstrCloudMask = mask.getName().startsWith("cloud_");
104+
// SLSTR 'cloud_an' flag band only, 20220113
105+
final boolean isSlstrCloudMask = mask.getName().startsWith("cloud_an");
131106
if (isSlstrCloudMask) {
132107
System.out.println("true");
133108
}

0 commit comments

Comments
 (0)