package org.esa.snap.rcp.util; import org.esa.snap.core.datamodel.Band; import org.esa.snap.core.datamodel.ConvolutionFilterBand; import org.esa.snap.core.datamodel.Kernel; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.datamodel.ProductData; import org.esa.snap.core.datamodel.ProductManager; import org.esa.snap.core.datamodel.Stx; import org.esa.snap.core.util.ProductUtils; import org.esa.snap.rcp.SnapApp; import org.openide.modules.OnStart; /** * @author Norman Fomferra */ public class FakeUncertaintyGenerator { public static final int UNCERTAINTY_KIND_COUNT = 2; private FakeUncertaintyGenerator() { } @OnStart public static class StartOp implements Runnable { int bandCount; @Override public void run() { if (Boolean.getBoolean("snap.uncertainty.test")) { SnapApp.getDefault().getProductManager().addListener(new ProductManager.Listener() { @Override public void productAdded(ProductManager.Event event) { bandCount = addUncertaintyBands(event.getProduct(), bandCount); } @Override public void productRemoved(ProductManager.Event event) { } }); } } } private static int addUncertaintyBands(Product product, int bandCount) { Band[] bands = product.getBands(); product.setAutoGrouping("radiance_*_variance:radiance_*_confidence:radiance_*_blur:radiance"); for (Band band : bands) { bandCount++; String bandName = band.getName(); if (bandName.startsWith("radiance") && !bandName.endsWith("_blur") && !bandName.endsWith("_variance") && !bandName.endsWith("_confidence")) { Band varianceBand = product.getBand(bandName + "_variance"); Band confidenceBand = product.getBand(bandName + "_confidence"); if (confidenceBand == null) { if (bandCount % UNCERTAINTY_KIND_COUNT == 0) { ConvolutionFilterBand blurredBand = new ConvolutionFilterBand(bandName + "_blur", band, new Kernel(11, 11, new double[]{ 0 / 720.0, 0 / 720.0, 1 / 720.0, 1 / 720.0, 2 / 720.0, 2 / 720.0, 2 / 720.0, 1 / 720.0, 1 / 720.0, 0 / 720.0, 0 / 720.0, 0 / 720.0, 1 / 720.0, 2 / 720.0, 3 / 720.0, 4 / 720.0, 5 / 720.0, 4 / 720.0, 3 / 720.0, 2 / 720.0, 1 / 720.0, 0 / 720.0, 1 / 720.0, 2 / 720.0, 4 / 720.0, 6 / 720.0, 9 / 720.0, 9 / 720.0, 9 / 720.0, 6 / 720.0, 4 / 720.0, 2 / 720.0, 1 / 720.0, 1 / 720.0, 3 / 720.0, 6 / 720.0, 11 / 720.0, 14 / 720.0, 16 / 720.0, 14 / 720.0, 11 / 720.0, 6 / 720.0, 3 / 720.0, 1 / 720.0, 2 / 720.0, 4 / 720.0, 9 / 720.0, 14 / 720.0, 20 / 720.0, 22 / 720.0, 20 / 720.0, 14 / 720.0, 9 / 720.0, 4 / 720.0, 2 / 720.0, 2 / 720.0, 5 / 720.0, 9 / 720.0, 16 / 720.0, 22 / 720.0, 24 / 720.0, 22 / 720.0, 16 / 720.0, 9 / 720.0, 5 / 720.0, 2 / 720.0, 2 / 720.0, 4 / 720.0, 9 / 720.0, 14 / 720.0, 20 / 720.0, 22 / 720.0, 20 / 720.0, 14 / 720.0, 9 / 720.0, 4 / 720.0, 2 / 720.0, 1 / 720.0, 3 / 720.0, 6 / 720.0, 11 / 720.0, 14 / 720.0, 16 / 720.0, 14 / 720.0, 11 / 720.0, 6 / 720.0, 3 / 720.0, 1 / 720.0, 1 / 720.0, 2 / 720.0, 4 / 720.0, 6 / 720.0, 9 / 720.0, 9 / 720.0, 9 / 720.0, 6 / 720.0, 4 / 720.0, 2 / 720.0, 1 / 720.0, 0 / 720.0, 1 / 720.0, 2 / 720.0, 3 / 720.0, 4 / 720.0, 5 / 720.0, 4 / 720.0, 3 / 720.0, 2 / 720.0, 1 / 720.0, 0 / 720.0, 0 / 720.0, 0 / 720.0, 1 / 720.0, 1 / 720.0, 2 / 720.0, 2 / 720.0, 2 / 720.0, 1 / 720.0, 1 / 720.0, 0 / 720.0, 0 / 720.0, }), 1); product.addBand(blurredBand); String varianceExpr = String.format("0.1 * (1 + 0.1 * min(max(random_gaussian(), 0), 10)) * %s", blurredBand.getName()); varianceBand = addVarianceBand(product, band, varianceExpr); confidenceBand = addConfidenceBand(product, band, varianceBand); } else if (bandCount % UNCERTAINTY_KIND_COUNT == 1) { int w2 = product.getSceneRasterWidth() / 2; int h2 = product.getSceneRasterHeight() / 2; int s = Math.min(w2, h2); String varianceExpr = String.format("100 * 0.5 * (1 + sin(4 * PI * sqrt(sq(X-%d) + sq(Y-%d)) / %d))", w2, h2, s); varianceBand = addVarianceBand(product, band, varianceExpr); confidenceBand = addConfidenceBand(product, band, varianceBand); } } band.addAncillaryVariable(varianceBand, "variance"); band.addAncillaryVariable(confidenceBand, "confidence"); } } return bandCount; } private static Band addVarianceBand(Product product, Band sourceBand, String varianceExpr) { Band varianceBand; varianceBand = product.addBand(sourceBand.getName() + "_variance", varianceExpr, ProductData.TYPE_FLOAT32); varianceBand.setUnit(sourceBand.getUnit()); ProductUtils.copySpectralBandProperties(sourceBand, varianceBand); return varianceBand; } private static Band addConfidenceBand(Product product, Band sourceBand, Band varianceBand) { Band confidenceBand; Stx varStx = varianceBand.getStx(); double minVar = Math.max(varStx.getMean() - 3 * varStx.getStandardDeviation(), varStx.getMinimum()); double maxVar = Math.min(varStx.getMean() + 3 * varStx.getStandardDeviation(), varStx.getMaximum()); double absVar = maxVar - minVar; confidenceBand = product.addBand(sourceBand.getName() + "_confidence", String.format("min(max((1 - (%s - %s) / %s), 0), 1)", varianceBand.getName(), minVar, absVar), ProductData.TYPE_FLOAT32); confidenceBand.setUnit("dl"); return confidenceBand; } }