Search in sources :

Example 1 with ProductContainer

use of org.jlinda.core.utils.ProductContainer in project s1tbx by senbox-org.

the class AzimuthShiftEstimationUsingESDOp method estimateAzimuthOffset.

/**
 * Estimate azimuth offset using ESD approach
 */
private synchronized void estimateAzimuthOffset() {
    if (isAzimuthOffsetAvailable) {
        return;
    }
    final int numPolarizations = polarizations.length;
    final int numOverlaps = subSwath[subSwathIndex - 1].numOfBursts - 1;
    final int numShifts = numOverlaps * numBlocksPerOverlap;
    final double spectralSeparation = computeSpectralSeparation();
    final StatusProgressMonitor status = new StatusProgressMonitor(StatusProgressMonitor.TYPE.SUBTASK);
    status.beginTask("Estimating azimuth offset... ", numShifts * numPolarizations);
    final ThreadExecutor executor = new ThreadExecutor();
    try {
        for (String key : targetMap.keySet()) {
            final ProductContainer container = targetMap.get(key);
            final CplxContainer master = container.sourceMaster;
            final CplxContainer slave = container.sourceSlave;
            final Band mBandI = master.realBand;
            final Band mBandQ = master.imagBand;
            final Band sBandI = slave.realBand;
            final Band sBandQ = slave.imagBand;
            final List<AzimuthShiftData> azShiftArray = new ArrayList<>(numShifts);
            final double[][] shiftLUT = new double[numOverlaps][numBlocksPerOverlap];
            for (int i = 0; i < numOverlaps; i++) {
                final Rectangle overlapInBurstOneRectangle = new Rectangle();
                final Rectangle overlapInBurstTwoRectangle = new Rectangle();
                getOverlappedRectangles(i, overlapInBurstOneRectangle, overlapInBurstTwoRectangle);
                final double[][] coherence = computeCoherence(overlapInBurstOneRectangle, mBandI, mBandQ, sBandI, sBandQ, cohWin);
                // block width
                final int w = overlapInBurstOneRectangle.width / numBlocksPerOverlap;
                final int h = overlapInBurstOneRectangle.height;
                final int x0BurstOne = overlapInBurstOneRectangle.x;
                final int y0BurstOne = overlapInBurstOneRectangle.y;
                final int y0BurstTwo = overlapInBurstTwoRectangle.y;
                final int overlapIndex = i;
                for (int j = 0; j < numBlocksPerOverlap; j++) {
                    checkForCancellation();
                    final int x0 = x0BurstOne + j * w;
                    final int blockIndex = j;
                    final ThreadRunnable worker = new ThreadRunnable() {

                        @Override
                        public void process() {
                            try {
                                final Rectangle blockInBurstOneRectangle = new Rectangle(x0, y0BurstOne, w, h);
                                final Rectangle blockInBurstTwoRectangle = new Rectangle(x0, y0BurstTwo, w, h);
                                final double[] blockCoherence = getBlockCoherence(blockIndex, w, h, coherence);
                                final double azShift = estimateAzOffsets(mBandI, mBandQ, sBandI, sBandQ, blockCoherence, blockInBurstTwoRectangle, blockInBurstOneRectangle, spectralSeparation);
                                synchronized (azShiftArray) {
                                    azShiftArray.add(new AzimuthShiftData(overlapIndex, blockIndex, azShift));
                                    shiftLUT[overlapIndex][blockIndex] = azShift;
                                }
                            } catch (Throwable e) {
                                OperatorUtils.catchOperatorException("estimateOffset", e);
                            }
                        }
                    };
                    executor.execute(worker);
                    status.worked(1);
                }
            }
            status.done();
            executor.complete();
            // todo The following simple average should be replaced by weighted average using coherence as weight
            final double[] averagedAzShiftArray = new double[numOverlaps];
            double totalOffset = 0.0;
            for (int i = 0; i < numOverlaps; i++) {
                double sumAzOffset = 0.0;
                for (int j = 0; j < numShifts; j++) {
                    if (azShiftArray.get(j).overlapIndex == i) {
                        sumAzOffset += azShiftArray.get(j).shift;
                    }
                }
                averagedAzShiftArray[i] = sumAzOffset / numBlocksPerOverlap;
                totalOffset += sumAzOffset;
                SystemUtils.LOG.fine("AzimuthShiftOp: overlap area = " + i + ", azimuth offset = " + averagedAzShiftArray[i]);
            }
            final double azOffset = -totalOffset / numShifts;
            SystemUtils.LOG.fine("AzimuthShiftOp: Overall azimuth shift = " + azOffset);
            if (targetOffsetMap.get(key) == null) {
                targetOffsetMap.put(key, new AzRgOffsets(azOffset, 0.0));
            } else {
                targetOffsetMap.get(key).setAzOffset(azOffset);
            }
            final String mstSlvTag = getMasterSlavePairTag(master, slave);
            saveOverallAzimuthShift(mstSlvTag, azOffset);
            saveAzimuthShiftPerOverlap(mstSlvTag, averagedAzShiftArray);
            saveAzimuthShiftPerBlock(mstSlvTag, azShiftArray);
            if (outputESDEstimationToFile) {
                final String fileName = mstSlvTag + "_azimuth_shift.txt";
                outputESDEstimationToFile(fileName, shiftLUT, -azOffset);
            }
        }
    } catch (Throwable e) {
        OperatorUtils.catchOperatorException("estimateAzimuthOffset", e);
    }
    isAzimuthOffsetAvailable = true;
}
Also used : StatusProgressMonitor(org.esa.snap.core.dataop.downloadable.StatusProgressMonitor) ArrayList(java.util.ArrayList) ProductContainer(org.jlinda.core.utils.ProductContainer) CplxContainer(org.jlinda.core.utils.CplxContainer) ThreadRunnable(org.esa.snap.core.util.ThreadRunnable) ThreadExecutor(org.esa.snap.core.util.ThreadExecutor)

Example 2 with ProductContainer

use of org.jlinda.core.utils.ProductContainer in project s1tbx by senbox-org.

the class DInSAROp method constructTargetMetadata.

private void constructTargetMetadata() {
    for (Integer keyMaster : masterMap.keySet()) {
        CplxContainer master = masterMap.get(keyMaster);
        int counter = 0;
        for (Integer keySlave : slaveDefoMap.keySet()) {
            if (counter == 0) {
                // generate name for product bands
                final String productName = keyMaster.toString() + "_" + keySlave.toString();
                final CplxContainer slave = slaveDefoMap.get(keySlave);
                final ProductContainer product = new ProductContainer(productName, master, slave, true);
                product.targetBandName_I = "i_" + PRODUCT_TAG + "_" + master.date + "_" + slave.date;
                product.targetBandName_Q = "q_" + PRODUCT_TAG + "_" + master.date + "_" + slave.date;
                // put ifg-product bands into map
                targetMap.put(productName, product);
                counter++;
            }
        }
    }
}
Also used : ProductContainer(org.jlinda.core.utils.ProductContainer) CplxContainer(org.jlinda.core.utils.CplxContainer)

Example 3 with ProductContainer

use of org.jlinda.core.utils.ProductContainer in project s1tbx by senbox-org.

the class DInSAROp method computeTileStack.

@Override
public void computeTileStack(Map<Band, Tile> targetTileMap, Rectangle targetRectangle, ProgressMonitor pm) throws OperatorException {
    try {
        int y0 = targetRectangle.y;
        int yN = y0 + targetRectangle.height - 1;
        int x0 = targetRectangle.x;
        int xN = targetRectangle.x + targetRectangle.width - 1;
        final Window tileWindow = new Window(y0, yN, x0, xN);
        Band targetBand_I;
        Band targetBand_Q;
        ComplexDoubleMatrix complexDefoPair = null;
        DoubleMatrix doubleTopoPair = null;
        ProductContainer product = null;
        for (String ifgKey : targetMap.keySet()) {
            product = targetMap.get(ifgKey);
            // / check out results from source ///
            Tile tileReal = getSourceTile(product.sourceMaster.realBand, targetRectangle);
            Tile tileImag = getSourceTile(product.sourceMaster.imagBand, targetRectangle);
            complexDefoPair = TileUtilsDoris.pullComplexDoubleMatrix(tileReal, tileImag);
        }
        // always pull from topoProduct
        for (Band band : topoProduct.getBands()) {
            if (band.getName().contains("unw") || band.getUnit().contains(Unit.ABS_PHASE)) {
                // / check out results from source ///
                Tile tileReal = getSourceTile(band, targetRectangle);
                doubleTopoPair = TileUtilsDoris.pullDoubleMatrix(tileReal);
            }
        }
        dinsar.applyDInSAR(tileWindow, complexDefoPair, doubleTopoPair);
        // / commit complexDefoPair back to target ///
        targetBand_I = targetProduct.getBand(product.targetBandName_I);
        Tile tileOutReal = targetTileMap.get(targetBand_I);
        TileUtilsDoris.pushDoubleMatrix(complexDefoPair.real(), tileOutReal, targetRectangle);
        targetBand_Q = targetProduct.getBand(product.targetBandName_Q);
        Tile tileOutImag = targetTileMap.get(targetBand_Q);
        TileUtilsDoris.pushDoubleMatrix(complexDefoPair.imag(), tileOutImag, targetRectangle);
    } catch (Throwable e) {
        OperatorUtils.catchOperatorException(getId(), e);
    }
}
Also used : Window(org.jlinda.core.Window) DoubleMatrix(org.jblas.DoubleMatrix) ComplexDoubleMatrix(org.jblas.ComplexDoubleMatrix) ProductContainer(org.jlinda.core.utils.ProductContainer) Tile(org.esa.snap.core.gpf.Tile) Band(org.esa.snap.core.datamodel.Band) ComplexDoubleMatrix(org.jblas.ComplexDoubleMatrix)

Example 4 with ProductContainer

use of org.jlinda.core.utils.ProductContainer in project s1tbx by senbox-org.

the class PhaseFilterOp method computeTileStack.

@Override
public void computeTileStack(Map<Band, Tile> targetTileMap, Rectangle targetRectangle, ProgressMonitor pm) throws OperatorException {
    try {
        // String filterType = "goldstein";
        // final float alpha = (float) 0.75;
        // final int overlap = 8;
        // final double[] kernel = new double[]{1. / 5, 1. / 5, 1. / 5, 1. / 5, 1. / 5};
        // final int blockSize = 64;
        Band targetBand_I;
        Band targetBand_Q;
        final Rectangle rectIn = new Rectangle(targetRectangle);
        final Rectangle rectOut = new Rectangle(targetRectangle);
        rectIn.y -= (overlap);
        rectIn.height += (2 * overlap);
        rectIn.x -= (overlap);
        rectIn.width += (2 * overlap);
        for (String ifgKey : targetMap.keySet()) {
            ProductContainer product = targetMap.get(ifgKey);
            Tile tileReal = getSourceTile(product.sourceMaster.realBand, rectIn);
            Tile tileImag = getSourceTile(product.sourceMaster.imagBand, rectIn);
            // put interferogram together
            ComplexDoubleMatrix complexIfg = TileUtilsDoris.pullComplexDoubleMatrix(tileReal, tileImag);
            PhaseFilter phaseFilter = new PhaseFilter(method, complexIfg, blockSize, overlap, kernelArray, alpha);
            phaseFilter.filter();
            complexIfg = phaseFilter.getData();
            // commit to target [note the tile overlap and boundary because of filter]
            // output [x0,y0] is shifted because of the tile overlap
            targetBand_I = targetProduct.getBand(product.targetBandName_I);
            Tile tileOutReal = targetTileMap.get(targetBand_I);
            TileUtilsDoris.pushDoubleMatrix(complexIfg.real(), tileOutReal, rectOut, overlap, overlap);
            targetBand_Q = targetProduct.getBand(product.targetBandName_Q);
            Tile tileOutImag = targetTileMap.get(targetBand_Q);
            TileUtilsDoris.pushDoubleMatrix(complexIfg.imag(), tileOutImag, rectOut, overlap, overlap);
        }
    } catch (Exception e) {
        throw new OperatorException(e);
    }
}
Also used : ProductContainer(org.jlinda.core.utils.ProductContainer) PhaseFilter(org.jlinda.core.filtering.PhaseFilter) Tile(org.esa.snap.core.gpf.Tile) Band(org.esa.snap.core.datamodel.Band) OperatorException(org.esa.snap.core.gpf.OperatorException) OperatorException(org.esa.snap.core.gpf.OperatorException) ComplexDoubleMatrix(org.jblas.ComplexDoubleMatrix)

Example 5 with ProductContainer

use of org.jlinda.core.utils.ProductContainer in project s1tbx by senbox-org.

the class SubtRefDemOp method createTargetProduct.

private void createTargetProduct() throws Exception {
    targetProduct = new Product(sourceProduct.getName() + PRODUCT_SUFFIX, sourceProduct.getProductType(), sourceProduct.getSceneRasterWidth(), sourceProduct.getSceneRasterHeight());
    ProductUtils.copyProductNodes(sourceProduct, targetProduct);
    for (String key : targetMap.keySet()) {
        final List<String> targetBandNames = new ArrayList<>();
        final ProductContainer container = targetMap.get(key);
        final CplxContainer master = container.sourceMaster;
        final CplxContainer slave = container.sourceSlave;
        final String pol = (master.polarisation == null || master.polarisation.isEmpty()) ? "" : '_' + master.polarisation.toUpperCase();
        final String tag = pol + '_' + master.date + '_' + slave.date;
        String targetBandName_I = "i_ifg" + tag;
        Band iBand = targetProduct.addBand(targetBandName_I, ProductData.TYPE_FLOAT32);
        container.addBand(Unit.REAL, iBand.getName());
        iBand.setUnit(Unit.REAL);
        targetBandNames.add(iBand.getName());
        String targetBandName_Q = "q_ifg" + tag;
        Band qBand = targetProduct.addBand(targetBandName_Q, ProductData.TYPE_FLOAT32);
        container.addBand(Unit.IMAGINARY, qBand.getName());
        qBand.setUnit(Unit.IMAGINARY);
        targetBandNames.add(qBand.getName());
        if (CREATE_VIRTUAL_BAND) {
            String countStr = productTag + tag;
            Band intensityBand = ReaderUtils.createVirtualIntensityBand(targetProduct, targetProduct.getBand(targetBandName_I), targetProduct.getBand(targetBandName_Q), countStr);
            targetBandNames.add(intensityBand.getName());
            Band phaseBand = ReaderUtils.createVirtualPhaseBand(targetProduct, targetProduct.getBand(targetBandName_I), targetProduct.getBand(targetBandName_Q), countStr);
            targetBandNames.add(phaseBand.getName());
            targetProduct.setQuicklookBandName(phaseBand.getName());
        }
        if (container.subProductsFlag) {
            if (outputTopoPhaseBand) {
                String topoBandName = "topo_phase" + tag;
                Band topoBand = targetProduct.addBand(topoBandName, ProductData.TYPE_FLOAT32);
                container.addBand(Unit.PHASE, topoBand.getName());
                topoBand.setNoDataValueUsed(true);
                topoBand.setNoDataValue(0);
                topoBand.setUnit(Unit.PHASE);
                topoBand.setDescription("topographic_phase");
                targetBandNames.add(topoBand.getName());
            }
        }
        // copy other bands through
        for (Band srcBand : sourceProduct.getBands()) {
            if (srcBand instanceof VirtualBand) {
                continue;
            }
            String srcBandName = srcBand.getName();
            if (srcBandName.endsWith(tag)) {
                if (srcBandName.startsWith("coh") || srcBandName.startsWith("elev")) {
                    Band band = ProductUtils.copyBand(srcBand.getName(), sourceProduct, targetProduct, true);
                    targetBandNames.add(band.getName());
                }
            }
        }
        String slvProductName = StackUtils.findOriginalSlaveProductName(sourceProduct, container.sourceSlave.realBand);
        StackUtils.saveSlaveProductBandNames(targetProduct, slvProductName, targetBandNames.toArray(new String[targetBandNames.size()]));
    }
    if (outputElevationBand) {
        Band elevBand = targetProduct.addBand("elevation", ProductData.TYPE_FLOAT32);
        elevBand.setNoDataValue(demNoDataValue);
        elevBand.setNoDataValueUsed(true);
        elevBand.setUnit(Unit.METERS);
        elevBand.setDescription("elevation");
    }
    if (outputLatLonBands) {
        Band latBand = targetProduct.addBand("orthorectifiedLat", ProductData.TYPE_FLOAT32);
        latBand.setNoDataValue(Double.NaN);
        latBand.setNoDataValueUsed(true);
        latBand.setUnit(Unit.DEGREES);
        latBand.setDescription("Orthorectified latitude");
        Band lonBand = targetProduct.addBand("orthorectifiedLon", ProductData.TYPE_FLOAT32);
        lonBand.setNoDataValue(Double.NaN);
        lonBand.setNoDataValueUsed(true);
        lonBand.setUnit(Unit.DEGREES);
        lonBand.setDescription("Orthorectified longitude");
    }
}
Also used : ProductContainer(org.jlinda.core.utils.ProductContainer) CplxContainer(org.jlinda.core.utils.CplxContainer) ArrayList(java.util.ArrayList) TargetProduct(org.esa.snap.core.gpf.annotations.TargetProduct) SourceProduct(org.esa.snap.core.gpf.annotations.SourceProduct)

Aggregations

ProductContainer (org.jlinda.core.utils.ProductContainer)12 CplxContainer (org.jlinda.core.utils.CplxContainer)8 Tile (org.esa.snap.core.gpf.Tile)4 OperatorException (org.esa.snap.core.gpf.OperatorException)3 ComplexDoubleMatrix (org.jblas.ComplexDoubleMatrix)3 DoubleMatrix (org.jblas.DoubleMatrix)3 Window (org.jlinda.core.Window)3 ArrayList (java.util.ArrayList)2 Band (org.esa.snap.core.datamodel.Band)2 IOException (java.io.IOException)1 StatusProgressMonitor (org.esa.snap.core.dataop.downloadable.StatusProgressMonitor)1 SourceProduct (org.esa.snap.core.gpf.annotations.SourceProduct)1 TargetProduct (org.esa.snap.core.gpf.annotations.TargetProduct)1 ThreadExecutor (org.esa.snap.core.util.ThreadExecutor)1 ThreadRunnable (org.esa.snap.core.util.ThreadRunnable)1 PhaseFilter (org.jlinda.core.filtering.PhaseFilter)1 Slant2Height (org.jlinda.core.geocode.Slant2Height)1 DemTile (org.jlinda.core.geom.DemTile)1 TopoPhase (org.jlinda.core.geom.TopoPhase)1