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;
}
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++;
}
}
}
}
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);
}
}
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);
}
}
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");
}
}
Aggregations