/* * Copyright (C) 2014 by Array Systems Computing Inc. http://www.array.ca * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.s1tbx.sentinel1.gpf; import org.esa.snap.core.datamodel.Band; import org.esa.snap.core.datamodel.MetadataElement; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.datamodel.VirtualBand; import org.esa.snap.core.gpf.Operator; import org.esa.snap.core.gpf.OperatorException; import org.esa.snap.core.gpf.OperatorSpi; import org.esa.snap.core.gpf.annotations.OperatorMetadata; 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.engine_utilities.datamodel.AbstractMetadata; import org.esa.snap.engine_utilities.gpf.InputProductValidator; import org.esa.snap.engine_utilities.gpf.OperatorUtils; /** * Creates a new product with only selected bands */ @OperatorMetadata(alias = "GRD-Post", category = "Radar/Sentinel-1 TOPS", authors = "Jun Lu, Luis Veci", version = "1.0", copyright = "Copyright (C) 2014 by Array Systems Computing Inc.", description = "Applies GRD post-processing") public final class GRDPostProcessOp extends Operator { @SourceProduct(alias = "source") private Product sourceProduct; @TargetProduct private Product targetProduct; /** * 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 Product} annotated with the * {@link TargetProduct TargetProduct} annotation or * by calling {@link #setTargetProduct} method.</p> * <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.</p> * * @throws OperatorException If an error occurs during operator initialisation. * @see #getTargetProduct() */ @Override public void initialize() throws OperatorException { try { final InputProductValidator validator = new InputProductValidator(sourceProduct); validator.checkIfSARProduct(); validator.checkIfSentinel1Product(); validator.checkProductType(new String[]{"SLC"}); if(validator.isComplex()) { throw new OperatorException("Data should not be complex. Please first apply SLC to GRD processing."); } if(validator.isMultiSwath()) { throw new OperatorException("Data should not be in separate swaths. Please first apply SLC to GRD processing."); } String productName = sourceProduct.getName(); productName = productName.replace("SLC_", "GRDH"); targetProduct = new Product(productName, "GRD", sourceProduct.getSceneRasterWidth(), sourceProduct.getSceneRasterHeight()); ProductUtils.copyProductNodes(sourceProduct, targetProduct); for (Band srcBand : sourceProduct.getBands()) { if (srcBand instanceof VirtualBand) { ProductUtils.copyVirtualBand(targetProduct, (VirtualBand) srcBand, srcBand.getName()); } else { ProductUtils.copyBand(srcBand.getName(), sourceProduct, targetProduct, true); } } updateTargetProductMetadata(); } catch (Throwable e) { OperatorUtils.catchOperatorException(getId(), e); } } /** * Update the metadata in the target product. */ private void updateTargetProductMetadata() { final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(targetProduct); String productName = absRoot.getAttributeString(AbstractMetadata.PRODUCT); absRoot.setAttributeString(AbstractMetadata.PRODUCT, productName.replace("SLC_", "GRDH")); String description = absRoot.getAttributeString(AbstractMetadata.SPH_DESCRIPTOR); absRoot.setAttributeString(AbstractMetadata.SPH_DESCRIPTOR, description.replace("SLC", "GRD")); absRoot.setAttributeString(AbstractMetadata.PRODUCT_TYPE, "GRD"); } /** * The SPI is used to register this operator in the graph processing framework * via the SPI configuration file * {@code META-INF/services/org.esa.snap.core.gpf.OperatorSpi}. * This class may also serve as a factory for new operator instances. * * @see OperatorSpi#createOperator() * @see OperatorSpi#createOperator(java.util.Map, java.util.Map) */ public static class Spi extends OperatorSpi { public Spi() { super(GRDPostProcessOp.class); } } }