From e19432dee48aad99094cb114710cebe5dc9ae70c Mon Sep 17 00:00:00 2001 From: thudson Date: Thu, 6 Jun 2024 23:03:47 +0000 Subject: [PATCH 1/9] Add flattening to the C++ code --- python/extensions/pybind_isce3/Sources.cmake | 1 + .../extensions/pybind_isce3/image/Flatten.cpp | 107 ++++++++++++++++++ .../extensions/pybind_isce3/image/Flatten.h | 42 +++++++ 3 files changed, 150 insertions(+) create mode 100644 python/extensions/pybind_isce3/image/Flatten.cpp create mode 100644 python/extensions/pybind_isce3/image/Flatten.h diff --git a/python/extensions/pybind_isce3/Sources.cmake b/python/extensions/pybind_isce3/Sources.cmake index 6732d3dcc..eabe822e3 100644 --- a/python/extensions/pybind_isce3/Sources.cmake +++ b/python/extensions/pybind_isce3/Sources.cmake @@ -58,6 +58,7 @@ geogrid/getRadarGrid.cpp geogrid/relocateRaster.cpp geogrid/geogrid.cpp geometry/lookIncFromSr.cpp +image/Flatten.cpp image/image.cpp image/Resample.cpp image/ResampSlc.cpp diff --git a/python/extensions/pybind_isce3/image/Flatten.cpp b/python/extensions/pybind_isce3/image/Flatten.cpp new file mode 100644 index 000000000..1694e2ce8 --- /dev/null +++ b/python/extensions/pybind_isce3/image/Flatten.cpp @@ -0,0 +1,107 @@ + +#include "Flatten.h" + +#include + + +namespace isce3::image::flatten { + + +/** Calculate the phase flattening parameter for a given pixel + * + * This code assumes that the output and input grids have the same wavelength + * and pixel spacing. + * + * @returns double The flattening phase for this pixel. + * + * RadarGridParameters of output radar data + * @param[in] radarGridOut + * RadarGridParameters of input radar data + * @param[in] radarGridIn + * The difference between the input range index and its point on the output grid; + * unit: range column indices (int) + * @param[in] rangeOffset +*/ +double _pixelFlatteningPhase( + const isce3::product::RadarGridParameters& radarGridOut, + const isce3::product::RadarGridParameters& radarGridIn, + const double rangeOffset +) +{ + // Values from the output radar grid + // unit: distance (meters) + const auto startingRange = radarGridOut.startingRange(); + // unit: distance (meters) per range index position + const auto rangePixelSpacing = radarGridOut.rangePixelSpacing(); + // unit: distance (meters) per cycle + const auto wavelength = radarGridOut.wavelength(); + + // Values from the input radar grid + // unit: distance (meters) + const auto inStartingRange = radarGridIn.startingRange(); + // The number of cycles completed by this wavelength of light in a given unit + // distance. + // unit: cycles per unit distance + const auto spatialFrequency = 1. / wavelength; + + // The difference between the starting range and the input starting range. + // unit: distance (meters) + const auto startingRangeDifference = startingRange - inStartingRange; + // The distance from the point referenced at the range pixel grid and the point that + // its offset points to. + // unit: distance (meters) + const auto offsetDistance = rangeOffset * rangePixelSpacing; + // The total distance difference between the indexed point on the output radar + // grid and its offset point on the input radar grid. + // unit: distance (meters) + const auto distanceDiff = startingRangeDifference + offsetDistance; + + // The number of cycles covered over that distance. + // unit: cycles + const auto cycleDiff = distanceDiff * spatialFrequency; + + // The flattening phase parameter for this pixel is the cycles in a two-way trip, + // multiplied by 2 * pi. + // unit: radians + return 4. * M_PI * cycleDiff; +} + + +void flattenAtCoords( + ArrayRef2D> dataBlock, + const EArray2df64& rangeIndices, + const isce3::product::RadarGridParameters& radarGridOut, + const isce3::product::RadarGridParameters& radarGridIn, + const size_t inRgFirstPixel, + const size_t outRgFirstPixel +) +{ + const size_t outWidth = dataBlock.cols(); + const size_t outLength = dataBlock.rows(); + +#pragma omp parallel for collapse(2) + for (size_t azIndexIn = 0; azIndexIn < outLength; ++azIndexIn){ + for (size_t rgIndexIn = 0; rgIndexIn < outWidth; ++rgIndexIn){ + + // Get the range indices on the output grid corresponding to these indices + // on the input grid overall. + const double rgIndexOut = rangeIndices(azIndexIn, rgIndexIn); + + double rangeOffset = rgIndexOut - static_cast(rgIndexIn) - + static_cast(outRgFirstPixel); + + const double flattenPhase = _pixelFlatteningPhase( + radarGridOut, radarGridIn, rangeOffset + ); + + // Update dataBlock column and row from index + const std::complex cpxVal( + std::cos(flattenPhase), std::sin(flattenPhase) + ); + dataBlock(azIndexIn, rgIndexIn) *= cpxVal; + } + } // end multithreaded block +} + + +} // namespace isce3::image::flatten diff --git a/python/extensions/pybind_isce3/image/Flatten.h b/python/extensions/pybind_isce3/image/Flatten.h new file mode 100644 index 000000000..d82bd93cb --- /dev/null +++ b/python/extensions/pybind_isce3/image/Flatten.h @@ -0,0 +1,42 @@ + + +#include +#include +#include + +#include + +namespace isce3::image::flatten { + +template +using Array2D = Eigen::Array; + +template +using ArrayRef2D = Eigen::Ref>; + +template +using ArrayRefConst2D = Eigen::Ref>; + +/** + * Re-flatten a grid of SLC data from its' original grid parameters into a new set of + * grid parameters. + * + * @param[out] dataBlock The SLC data to flatten + * @param[in] nativeDopplerLUT native doppler of SLC image + * @param[in] rangeIndices range index of each coordinate pixel in the data block + * in the coordinate system of the alternate radar grid + * @param[in] radarGridOut radar grid parameters of the alternate grid + * @param[in] radarGridIn radar grid parameters of the original grid + * @param[in] inRgFirstPixel range index of the first sample of the original grid + * @param[in] outRgFirstPixel range index of the first sample of the alternate grid + */ +void flattenAtCoords( + ArrayRef2D> dataBlock, + const ArrayRefConst2D rangeIndices, + const isce3::product::RadarGridParameters& radarGridOut, + const isce3::product::RadarGridParameters& radarGridIn, + const size_t inRgFirstPixel, + const size_t outRgFirstPixel +); + +} // namespace isce3::image::flatten \ No newline at end of file From 897d89c1a1514c3bbd60aa2704003823ae863dbe Mon Sep 17 00:00:00 2001 From: thudson Date: Thu, 6 Jun 2024 23:22:12 +0000 Subject: [PATCH 2/9] Oops! Wrong directory. --- {python/extensions/pybind_isce3 => cxx/isce3}/image/Flatten.cpp | 0 {python/extensions/pybind_isce3 => cxx/isce3}/image/Flatten.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {python/extensions/pybind_isce3 => cxx/isce3}/image/Flatten.cpp (100%) rename {python/extensions/pybind_isce3 => cxx/isce3}/image/Flatten.h (100%) diff --git a/python/extensions/pybind_isce3/image/Flatten.cpp b/cxx/isce3/image/Flatten.cpp similarity index 100% rename from python/extensions/pybind_isce3/image/Flatten.cpp rename to cxx/isce3/image/Flatten.cpp diff --git a/python/extensions/pybind_isce3/image/Flatten.h b/cxx/isce3/image/Flatten.h similarity index 100% rename from python/extensions/pybind_isce3/image/Flatten.h rename to cxx/isce3/image/Flatten.h From c5fc9216cacdad50e473d5bd0c352b5870cff59f Mon Sep 17 00:00:00 2001 From: thudson Date: Thu, 6 Jun 2024 23:37:40 +0000 Subject: [PATCH 3/9] Flattening pybinds --- cxx/isce3/image/Flatten.h | 1 - .../extensions/pybind_isce3/image/Flatten.cpp | 45 +++++++++++++++++++ .../extensions/pybind_isce3/image/Flatten.h | 5 +++ .../extensions/pybind_isce3/image/image.cpp | 5 +++ 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 python/extensions/pybind_isce3/image/Flatten.cpp create mode 100644 python/extensions/pybind_isce3/image/Flatten.h diff --git a/cxx/isce3/image/Flatten.h b/cxx/isce3/image/Flatten.h index d82bd93cb..45fc1a9bd 100644 --- a/cxx/isce3/image/Flatten.h +++ b/cxx/isce3/image/Flatten.h @@ -22,7 +22,6 @@ using ArrayRefConst2D = Eigen::Ref>; * grid parameters. * * @param[out] dataBlock The SLC data to flatten - * @param[in] nativeDopplerLUT native doppler of SLC image * @param[in] rangeIndices range index of each coordinate pixel in the data block * in the coordinate system of the alternate radar grid * @param[in] radarGridOut radar grid parameters of the alternate grid diff --git a/python/extensions/pybind_isce3/image/Flatten.cpp b/python/extensions/pybind_isce3/image/Flatten.cpp new file mode 100644 index 000000000..4128fe22a --- /dev/null +++ b/python/extensions/pybind_isce3/image/Flatten.cpp @@ -0,0 +1,45 @@ +#include "Flatten.h" + +#include +#include + +#include +#include +#include + +namespace py = pybind11; + + +void addbindings_modulate(py::module & m) +{ + m.def( + "flatten_at_coords", + &isce3::image::flatten::flattenAtCoords, + py::arg("data_block"), + py::arg("range_indices"), + py::arg("radar_grid_out"), + py::arg("radar_grid_in"), + py::arg("in_rg_first_pixel"), + py::arg("out_rg_first_pixel"), + R"( + Re-flatten a grid of SLC data from its' original grid parameters into a new set + of grid parameters. + + Parameters + ---------- + data_block : np.ndarray (complex64) + The SLC data to flatten + range_indices : np.ndarray (float64) + range index of each coordinate pixel in the data block in the coordinate + system of the alternate radar grid + radar_grid_out : isce3.product.RadarGridParameters + radar grid parameters of the alternate grid + radar_grid_in : isce3.product.RadarGridParameters + radar grid parameters of the original grid + in_rg_first_pixel : int + range index of the first sample of the original grid + out_rg_first_pixel : int + range index of the first sample of the alternate grid + )" + ); +} diff --git a/python/extensions/pybind_isce3/image/Flatten.h b/python/extensions/pybind_isce3/image/Flatten.h new file mode 100644 index 000000000..7400460b9 --- /dev/null +++ b/python/extensions/pybind_isce3/image/Flatten.h @@ -0,0 +1,5 @@ + 5 lines (4 sloc) 112 Bytes +#pragma once +#include + +void addbindings_flatten(pybind11::module&); diff --git a/python/extensions/pybind_isce3/image/image.cpp b/python/extensions/pybind_isce3/image/image.cpp index c71d72910..1974c2e53 100644 --- a/python/extensions/pybind_isce3/image/image.cpp +++ b/python/extensions/pybind_isce3/image/image.cpp @@ -2,6 +2,7 @@ #include "Resample.h" #include "ResampSlc.h" +#include "Flatten.h" namespace py = pybind11; @@ -9,10 +10,14 @@ void addsubmodule_image(py::module & m) { py::module m_image = m.def_submodule("image"); py::module m_image_v2 = m_image.def_submodule("v2"); + py::module m_image_flatten = m_image.def_submodule("flatten"); // Add the resample v2 functionality to the v2 module. addbindings_resamp(m_image_v2); + // Add the flattening functionality to the image.flatten module + addbindings_flatten(m_image_flatten); + // forward declare bound classes for v1 py::class_ pyResampSlc(m_image, "ResampSlc"); From 84af966c0ccfc213c7418d9e4a1ea2a5ffe6cf8a Mon Sep 17 00:00:00 2001 From: thudson Date: Mon, 10 Jun 2024 15:57:52 +0000 Subject: [PATCH 4/9] Add a get_flattening_phase function --- cxx/isce3/image/Flatten.cpp | 37 +++++++++++++++++++ cxx/isce3/image/Flatten.h | 22 +++++++++++ .../extensions/pybind_isce3/image/Flatten.cpp | 32 ++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/cxx/isce3/image/Flatten.cpp b/cxx/isce3/image/Flatten.cpp index 1694e2ce8..55c4a47b0 100644 --- a/cxx/isce3/image/Flatten.cpp +++ b/cxx/isce3/image/Flatten.cpp @@ -104,4 +104,41 @@ void flattenAtCoords( } +void getFlatteningPhase( + ArrayRef2D> dataBlock, + const EArray2df64& rangeIndices, + const isce3::product::RadarGridParameters& radarGridOut, + const isce3::product::RadarGridParameters& radarGridIn, + const size_t inRgFirstPixel, + const size_t outRgFirstPixel +) +{ + const size_t outWidth = dataBlock.cols(); + const size_t outLength = dataBlock.rows(); + +#pragma omp parallel for collapse(2) + for (size_t azIndexIn = 0; azIndexIn < outLength; ++azIndexIn){ + for (size_t rgIndexIn = 0; rgIndexIn < outWidth; ++rgIndexIn){ + + // Get the range indices on the output grid corresponding to these indices + // on the input grid overall. + const double rgIndexOut = rangeIndices(azIndexIn, rgIndexIn); + + double rangeOffset = rgIndexOut - static_cast(rgIndexIn) - + static_cast(outRgFirstPixel); + + const double flattenPhase = _pixelFlatteningPhase( + radarGridOut, radarGridIn, rangeOffset + ); + + // Update dataBlock column and row from index + const std::complex cpxVal( + std::cos(flattenPhase), std::sin(flattenPhase) + ); + dataBlock(azIndexIn, rgIndexIn) = cpxVal; + } + } // end multithreaded block +} + + } // namespace isce3::image::flatten diff --git a/cxx/isce3/image/Flatten.h b/cxx/isce3/image/Flatten.h index 45fc1a9bd..9cc37a019 100644 --- a/cxx/isce3/image/Flatten.h +++ b/cxx/isce3/image/Flatten.h @@ -38,4 +38,26 @@ void flattenAtCoords( const size_t outRgFirstPixel ); +/** + * Get the relative flattening phase, in complex format, necessary to re-flatten a radar + * block from one radar grid to another. + * + * @param[out] dataBlock The data block to write the flattening phase to. + * Any values in this block may be overwritten. + * @param[in] rangeIndices range index of each coordinate pixel in the data block + * in the coordinate system of the alternate radar grid + * @param[in] radarGridOut radar grid parameters of the alternate grid + * @param[in] radarGridIn radar grid parameters of the original grid + * @param[in] inRgFirstPixel range index of the first sample of the original grid + * @param[in] outRgFirstPixel range index of the first sample of the alternate grid + */ +void getFlatteningPhase( + ArrayRef2D> dataBlock, + const ArrayRefConst2D rangeIndices, + const isce3::product::RadarGridParameters& radarGridOut, + const isce3::product::RadarGridParameters& radarGridIn, + const size_t inRgFirstPixel, + const size_t outRgFirstPixel +); + } // namespace isce3::image::flatten \ No newline at end of file diff --git a/python/extensions/pybind_isce3/image/Flatten.cpp b/python/extensions/pybind_isce3/image/Flatten.cpp index 4128fe22a..62c3ff6e8 100644 --- a/python/extensions/pybind_isce3/image/Flatten.cpp +++ b/python/extensions/pybind_isce3/image/Flatten.cpp @@ -42,4 +42,36 @@ void addbindings_modulate(py::module & m) range index of the first sample of the alternate grid )" ); + + m.def( + "get_flattening_phase", + &isce3::image::flatten::getFlatteningPhase, + py::arg("data_block"), + py::arg("range_indices"), + py::arg("radar_grid_out"), + py::arg("radar_grid_in"), + py::arg("in_rg_first_pixel"), + py::arg("out_rg_first_pixel"), + R"( + Re-flatten a grid of SLC data from its' original grid parameters into a new set + of grid parameters. + + Parameters + ---------- + data_block : np.ndarray (complex64) + The data block to write the flattening phase to. Any values in this block + may be overwritten. + range_indices : np.ndarray (float64) + range index of each coordinate pixel in the data block in the coordinate + system of the alternate radar grid + radar_grid_out : isce3.product.RadarGridParameters + radar grid parameters of the alternate grid + radar_grid_in : isce3.product.RadarGridParameters + radar grid parameters of the original grid + in_rg_first_pixel : int + range index of the first sample of the original grid + out_rg_first_pixel : int + range index of the first sample of the alternate grid + )" + ); } From f97aefc2228a686227ba475cea819523e5b11ca2 Mon Sep 17 00:00:00 2001 From: thudson Date: Mon, 10 Jun 2024 16:50:05 +0000 Subject: [PATCH 5/9] Add python shell functions --- .../extensions/pybind_isce3/image/Flatten.cpp | 14 +- python/packages/isce3/image/flatten.py | 139 ++++++++++++++++++ 2 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 python/packages/isce3/image/flatten.py diff --git a/python/extensions/pybind_isce3/image/Flatten.cpp b/python/extensions/pybind_isce3/image/Flatten.cpp index 62c3ff6e8..8df925de2 100644 --- a/python/extensions/pybind_isce3/image/Flatten.cpp +++ b/python/extensions/pybind_isce3/image/Flatten.cpp @@ -13,7 +13,7 @@ namespace py = pybind11; void addbindings_modulate(py::module & m) { m.def( - "flatten_at_coords", + "_flatten_at_coords", &isce3::image::flatten::flattenAtCoords, py::arg("data_block"), py::arg("range_indices"), @@ -25,6 +25,10 @@ void addbindings_modulate(py::module & m) Re-flatten a grid of SLC data from its' original grid parameters into a new set of grid parameters. + This function does not check the sizes of the input grids against each other, + and should be considered an implementation. See the Python function + isce3.image.flatten.flatten_at_coords for the full implementation. + Parameters ---------- data_block : np.ndarray (complex64) @@ -42,9 +46,9 @@ void addbindings_modulate(py::module & m) range index of the first sample of the alternate grid )" ); - + m.def( - "get_flattening_phase", + "_get_flattening_phase_at_coords", &isce3::image::flatten::getFlatteningPhase, py::arg("data_block"), py::arg("range_indices"), @@ -56,6 +60,10 @@ void addbindings_modulate(py::module & m) Re-flatten a grid of SLC data from its' original grid parameters into a new set of grid parameters. + This function does not check the sizes of the input grids against each other, + and should be considered an implementation. See the Python function + isce3.image.flatten.get_flattening_phase_at_coords for the full implementation. + Parameters ---------- data_block : np.ndarray (complex64) diff --git a/python/packages/isce3/image/flatten.py b/python/packages/isce3/image/flatten.py new file mode 100644 index 000000000..762f3963d --- /dev/null +++ b/python/packages/isce3/image/flatten.py @@ -0,0 +1,139 @@ +from __future__ import annotations + +import journal +import numpy as np + +from isce3.ext.isce3.image.flatten import ( + _get_flattening_phase_at_coords, + _flatten_at_coords, +) +from isce3.product import RadarGridParameters + + +def flatten_at_coords( + data_block: np.ndarray, + range_indices: np.ndarray, + radar_grid_out: RadarGridParameters, + radar_grid_in: RadarGridParameters, + in_rg_first_pixel: int, + out_rg_first_pixel: int, + out: np.ndarray | None = None, +) -> np.ndarray: + """ + Re-flatten a grid of SLC data from its' original grid parameters into a new set + of grid parameters. + + Parameters + ---------- + data_block : np.ndarray of complex64 + The SLC data to flatten + range_indices : np.ndarray of float64 + range index of each coordinate pixel in the data block in the coordinate + system of the alternate radar grid + radar_grid_out : isce3.product.RadarGridParameters + radar grid parameters of the alternate grid + radar_grid_in : isce3.product.RadarGridParameters + radar grid parameters of the original grid + in_rg_first_pixel : int + range index of the first sample of the original grid + out_rg_first_pixel : int + range index of the first sample of the alternate grid + out : np.ndarray of np.complex64 | None, optional + The array to output data to, or None. If given, must be the same size as + data_block. Any contents of this array will he overwritten. + Defaults to None. + + Returns + ------- + np.ndarray of np.complex64 + The flattened SLC block. If `out` was given, this will be the same array as + the `out` array. + """ + error_channel = journal.error("flatten.flatten_at_coords") + out_array = out if out is not None else np.full( + (radar_grid_out.length, radar_grid_out.width), + fill_value=np.nan + 1.0j * np.nan, + dtype=np.complex64, + ) + np.copyto(out_array, data_block) + + if out_array.shape != range_indices.shape: + err_log = ( + f"Output block shape {out_array.shape} and range indices block shape " + f"{range_indices.shape} are unequal." + ) + error_channel.log(err_log) + raise ValueError(err_log) + + _flatten_at_coords( + data_block=out_array, + range_indices=range_indices, + radar_grid_out=radar_grid_out, + radar_grid_in=radar_grid_in, + in_rg_first_pixel=in_rg_first_pixel, + out_rg_first_pixel=out_rg_first_pixel, + ) + + return out_array + + +def get_flattening_phase_at_coords( + range_indices: np.ndarray, + radar_grid_out: RadarGridParameters, + radar_grid_in: RadarGridParameters, + in_rg_first_pixel: int, + out_rg_first_pixel: int, + out: np.ndarray | None = None, +) -> np.ndarray[np.complex64]: + """ + Acquire the phase of the given carrier at each given index of a radar scene. + + Parameters + ---------- + range_indices : np.ndarray of float64 + range index of each coordinate pixel in the data block in the coordinate + system of the alternate radar grid + radar_grid_out : isce3.product.RadarGridParameters + radar grid parameters of the alternate grid + radar_grid_in : isce3.product.RadarGridParameters + radar grid parameters of the original grid + in_rg_first_pixel : int + range index of the first sample of the original grid + out_rg_first_pixel : int + range index of the first sample of the alternate grid + out : np.ndarray of np.complex64 | None, optional + The array to output data to, or None. If given, must be the same size as + data_block. Any contents of this array will he overwritten. + Defaults to None. + + Returns + ------- + np.ndarray of np.complex64 + The flattened SLC block. If `out` was given, this will be the same array as + the `out` array. + """ + error_channel = journal.error("modulate.get_modulation_phase_at_coords") + out_array = out if out is not None else np.full( + range_indices.shape, + fill_value=np.nan + 1.0j * np.nan, + dtype=np.complex64, + ) + + if out_array.shape != range_indices.shape: + err_log = ( + f"Output block shape {out_array.shape} and range indices block shape " + f"{range_indices.shape} are unequal." + ) + error_channel.log(err_log) + raise ValueError(err_log) + + _get_flattening_phase_at_coords( + data_block=out_array, + range_indices=range_indices, + radar_grid_out=radar_grid_out, + radar_grid_in=radar_grid_in, + in_rg_first_pixel=in_rg_first_pixel, + out_rg_first_pixel=out_rg_first_pixel, + ) + + return out_array From 07445ad99cf116808e0971090482479dcdad4c81 Mon Sep 17 00:00:00 2001 From: thudson Date: Mon, 10 Jun 2024 16:50:44 +0000 Subject: [PATCH 6/9] logging correction --- python/packages/isce3/image/flatten.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/packages/isce3/image/flatten.py b/python/packages/isce3/image/flatten.py index 762f3963d..e906c27f8 100644 --- a/python/packages/isce3/image/flatten.py +++ b/python/packages/isce3/image/flatten.py @@ -112,7 +112,7 @@ def get_flattening_phase_at_coords( The flattened SLC block. If `out` was given, this will be the same array as the `out` array. """ - error_channel = journal.error("modulate.get_modulation_phase_at_coords") + error_channel = journal.error("flatten.get_flattening_phase_at_coords") out_array = out if out is not None else np.full( range_indices.shape, fill_value=np.nan + 1.0j * np.nan, From 63a055bf7b27e6ba9a415df71733419660cabd38 Mon Sep 17 00:00:00 2001 From: thudson Date: Mon, 10 Jun 2024 18:33:08 +0000 Subject: [PATCH 7/9] Cleanup, fix compiler errors --- cxx/isce3/Headers.cmake | 1 + cxx/isce3/Sources.cmake | 1 + cxx/isce3/image/Flatten.cpp | 6 ++---- cxx/isce3/image/Flatten.h | 4 ---- python/extensions/pybind_isce3/image/Flatten.cpp | 6 ------ python/extensions/pybind_isce3/image/Flatten.h | 1 - python/packages/isce3/image/flatten.py | 8 -------- 7 files changed, 4 insertions(+), 23 deletions(-) diff --git a/cxx/isce3/Headers.cmake b/cxx/isce3/Headers.cmake index 5d2543079..3351f5b9a 100644 --- a/cxx/isce3/Headers.cmake +++ b/cxx/isce3/Headers.cmake @@ -114,6 +114,7 @@ geometry/metadataCubes.h geogrid/getRadarGrid.h geogrid/relocateRaster.h image/forward.h +image/Flatten.h image/Resample.h image/ResampSlc.h image/ResampSlc.icc diff --git a/cxx/isce3/Sources.cmake b/cxx/isce3/Sources.cmake index 171dbe5c2..21981b747 100644 --- a/cxx/isce3/Sources.cmake +++ b/cxx/isce3/Sources.cmake @@ -59,6 +59,7 @@ geometry/TopoLayers.cpp geometry/metadataCubes.cpp geogrid/getRadarGrid.cpp geogrid/relocateRaster.cpp +image/Flatten.cpp image/Resample.cpp image/ResampSlc.cpp io/gdal/Dataset.cpp diff --git a/cxx/isce3/image/Flatten.cpp b/cxx/isce3/image/Flatten.cpp index 55c4a47b0..ccc459c04 100644 --- a/cxx/isce3/image/Flatten.cpp +++ b/cxx/isce3/image/Flatten.cpp @@ -69,10 +69,9 @@ double _pixelFlatteningPhase( void flattenAtCoords( ArrayRef2D> dataBlock, - const EArray2df64& rangeIndices, + const ArrayRefConst2D rangeIndices, const isce3::product::RadarGridParameters& radarGridOut, const isce3::product::RadarGridParameters& radarGridIn, - const size_t inRgFirstPixel, const size_t outRgFirstPixel ) { @@ -106,10 +105,9 @@ void flattenAtCoords( void getFlatteningPhase( ArrayRef2D> dataBlock, - const EArray2df64& rangeIndices, + const ArrayRefConst2D rangeIndices, const isce3::product::RadarGridParameters& radarGridOut, const isce3::product::RadarGridParameters& radarGridIn, - const size_t inRgFirstPixel, const size_t outRgFirstPixel ) { diff --git a/cxx/isce3/image/Flatten.h b/cxx/isce3/image/Flatten.h index 9cc37a019..7692e1c03 100644 --- a/cxx/isce3/image/Flatten.h +++ b/cxx/isce3/image/Flatten.h @@ -26,7 +26,6 @@ using ArrayRefConst2D = Eigen::Ref>; * in the coordinate system of the alternate radar grid * @param[in] radarGridOut radar grid parameters of the alternate grid * @param[in] radarGridIn radar grid parameters of the original grid - * @param[in] inRgFirstPixel range index of the first sample of the original grid * @param[in] outRgFirstPixel range index of the first sample of the alternate grid */ void flattenAtCoords( @@ -34,7 +33,6 @@ void flattenAtCoords( const ArrayRefConst2D rangeIndices, const isce3::product::RadarGridParameters& radarGridOut, const isce3::product::RadarGridParameters& radarGridIn, - const size_t inRgFirstPixel, const size_t outRgFirstPixel ); @@ -48,7 +46,6 @@ void flattenAtCoords( * in the coordinate system of the alternate radar grid * @param[in] radarGridOut radar grid parameters of the alternate grid * @param[in] radarGridIn radar grid parameters of the original grid - * @param[in] inRgFirstPixel range index of the first sample of the original grid * @param[in] outRgFirstPixel range index of the first sample of the alternate grid */ void getFlatteningPhase( @@ -56,7 +53,6 @@ void getFlatteningPhase( const ArrayRefConst2D rangeIndices, const isce3::product::RadarGridParameters& radarGridOut, const isce3::product::RadarGridParameters& radarGridIn, - const size_t inRgFirstPixel, const size_t outRgFirstPixel ); diff --git a/python/extensions/pybind_isce3/image/Flatten.cpp b/python/extensions/pybind_isce3/image/Flatten.cpp index 8df925de2..7c2430f86 100644 --- a/python/extensions/pybind_isce3/image/Flatten.cpp +++ b/python/extensions/pybind_isce3/image/Flatten.cpp @@ -19,7 +19,6 @@ void addbindings_modulate(py::module & m) py::arg("range_indices"), py::arg("radar_grid_out"), py::arg("radar_grid_in"), - py::arg("in_rg_first_pixel"), py::arg("out_rg_first_pixel"), R"( Re-flatten a grid of SLC data from its' original grid parameters into a new set @@ -40,8 +39,6 @@ void addbindings_modulate(py::module & m) radar grid parameters of the alternate grid radar_grid_in : isce3.product.RadarGridParameters radar grid parameters of the original grid - in_rg_first_pixel : int - range index of the first sample of the original grid out_rg_first_pixel : int range index of the first sample of the alternate grid )" @@ -54,7 +51,6 @@ void addbindings_modulate(py::module & m) py::arg("range_indices"), py::arg("radar_grid_out"), py::arg("radar_grid_in"), - py::arg("in_rg_first_pixel"), py::arg("out_rg_first_pixel"), R"( Re-flatten a grid of SLC data from its' original grid parameters into a new set @@ -76,8 +72,6 @@ void addbindings_modulate(py::module & m) radar grid parameters of the alternate grid radar_grid_in : isce3.product.RadarGridParameters radar grid parameters of the original grid - in_rg_first_pixel : int - range index of the first sample of the original grid out_rg_first_pixel : int range index of the first sample of the alternate grid )" diff --git a/python/extensions/pybind_isce3/image/Flatten.h b/python/extensions/pybind_isce3/image/Flatten.h index 7400460b9..a702c6a55 100644 --- a/python/extensions/pybind_isce3/image/Flatten.h +++ b/python/extensions/pybind_isce3/image/Flatten.h @@ -1,4 +1,3 @@ - 5 lines (4 sloc) 112 Bytes #pragma once #include diff --git a/python/packages/isce3/image/flatten.py b/python/packages/isce3/image/flatten.py index e906c27f8..006ae3803 100644 --- a/python/packages/isce3/image/flatten.py +++ b/python/packages/isce3/image/flatten.py @@ -15,7 +15,6 @@ def flatten_at_coords( range_indices: np.ndarray, radar_grid_out: RadarGridParameters, radar_grid_in: RadarGridParameters, - in_rg_first_pixel: int, out_rg_first_pixel: int, out: np.ndarray | None = None, ) -> np.ndarray: @@ -34,8 +33,6 @@ def flatten_at_coords( radar grid parameters of the alternate grid radar_grid_in : isce3.product.RadarGridParameters radar grid parameters of the original grid - in_rg_first_pixel : int - range index of the first sample of the original grid out_rg_first_pixel : int range index of the first sample of the alternate grid out : np.ndarray of np.complex64 | None, optional @@ -70,7 +67,6 @@ def flatten_at_coords( range_indices=range_indices, radar_grid_out=radar_grid_out, radar_grid_in=radar_grid_in, - in_rg_first_pixel=in_rg_first_pixel, out_rg_first_pixel=out_rg_first_pixel, ) @@ -81,7 +77,6 @@ def get_flattening_phase_at_coords( range_indices: np.ndarray, radar_grid_out: RadarGridParameters, radar_grid_in: RadarGridParameters, - in_rg_first_pixel: int, out_rg_first_pixel: int, out: np.ndarray | None = None, ) -> np.ndarray[np.complex64]: @@ -97,8 +92,6 @@ def get_flattening_phase_at_coords( radar grid parameters of the alternate grid radar_grid_in : isce3.product.RadarGridParameters radar grid parameters of the original grid - in_rg_first_pixel : int - range index of the first sample of the original grid out_rg_first_pixel : int range index of the first sample of the alternate grid out : np.ndarray of np.complex64 | None, optional @@ -132,7 +125,6 @@ def get_flattening_phase_at_coords( range_indices=range_indices, radar_grid_out=radar_grid_out, radar_grid_in=radar_grid_in, - in_rg_first_pixel=in_rg_first_pixel, out_rg_first_pixel=out_rg_first_pixel, ) From 98b40ff6a74dcddc8029e314416d204fe4bfbf99 Mon Sep 17 00:00:00 2001 From: thudson Date: Thu, 10 Oct 2024 20:21:09 +0000 Subject: [PATCH 8/9] Bring shell function behavior up to speed with resample_slc --- python/packages/isce3/image/flatten.py | 46 ++++++++++---------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/python/packages/isce3/image/flatten.py b/python/packages/isce3/image/flatten.py index 006ae3803..e95997275 100644 --- a/python/packages/isce3/image/flatten.py +++ b/python/packages/isce3/image/flatten.py @@ -16,7 +16,6 @@ def flatten_at_coords( radar_grid_out: RadarGridParameters, radar_grid_in: RadarGridParameters, out_rg_first_pixel: int, - out: np.ndarray | None = None, ) -> np.ndarray: """ Re-flatten a grid of SLC data from its' original grid parameters into a new set @@ -35,10 +34,6 @@ def flatten_at_coords( radar grid parameters of the original grid out_rg_first_pixel : int range index of the first sample of the alternate grid - out : np.ndarray of np.complex64 | None, optional - The array to output data to, or None. If given, must be the same size as - data_block. Any contents of this array will he overwritten. - Defaults to None. Returns ------- @@ -47,21 +42,24 @@ def flatten_at_coords( the `out` array. """ error_channel = journal.error("flatten.flatten_at_coords") - out_array = out if out is not None else np.full( - (radar_grid_out.length, radar_grid_out.width), - fill_value=np.nan + 1.0j * np.nan, - dtype=np.complex64, - ) - np.copyto(out_array, data_block) - if out_array.shape != range_indices.shape: + if data_block.shape != range_indices.shape: err_log = ( - f"Output block shape {out_array.shape} and range indices block shape " + f"Data block shape {data_block.shape} and range indices block shape " f"{range_indices.shape} are unequal." ) error_channel.log(err_log) raise ValueError(err_log) + out_array = data_block.copy() + + # Ensure that all of the input data blocks meet the requirements of the + # _flatten_at_coords pybind (correct dtype, with flags C_CONTIGUOUS) + # These function calls will return conforming copies of the data blocks if they + # are not already conforming. + out_array = np.require(out_array, dtype=np.complex64, requirements=["C"]) + range_indices = np.require(range_indices, dtype=np.float64, requirements=["C"]) + _flatten_at_coords( data_block=out_array, range_indices=range_indices, @@ -78,8 +76,7 @@ def get_flattening_phase_at_coords( radar_grid_out: RadarGridParameters, radar_grid_in: RadarGridParameters, out_rg_first_pixel: int, - out: np.ndarray | None = None, -) -> np.ndarray[np.complex64]: +) -> np.ndarray: """ Acquire the phase of the given carrier at each given index of a radar scene. @@ -94,10 +91,6 @@ def get_flattening_phase_at_coords( radar grid parameters of the original grid out_rg_first_pixel : int range index of the first sample of the alternate grid - out : np.ndarray of np.complex64 | None, optional - The array to output data to, or None. If given, must be the same size as - data_block. Any contents of this array will he overwritten. - Defaults to None. Returns ------- @@ -105,20 +98,17 @@ def get_flattening_phase_at_coords( The flattened SLC block. If `out` was given, this will be the same array as the `out` array. """ - error_channel = journal.error("flatten.get_flattening_phase_at_coords") - out_array = out if out is not None else np.full( + out_array = np.full( range_indices.shape, fill_value=np.nan + 1.0j * np.nan, dtype=np.complex64, ) - if out_array.shape != range_indices.shape: - err_log = ( - f"Output block shape {out_array.shape} and range indices block shape " - f"{range_indices.shape} are unequal." - ) - error_channel.log(err_log) - raise ValueError(err_log) + # Ensure that all of the input data blocks meet the requirements of the + # _get_flattening_phase_at_coords pybind (correct dtype, with flags C_CONTIGUOUS) + # These function calls will return conforming copies of the data blocks if they + # are not already conforming. + range_indices = np.require(range_indices, dtype=np.float64, requirements=["C"]) _get_flattening_phase_at_coords( data_block=out_array, From 71e31af7c693cb935ecf9df5a186976c35c502f0 Mon Sep 17 00:00:00 2001 From: "Tyler G. Hudson" Date: Mon, 16 Mar 2026 16:54:40 -0700 Subject: [PATCH 9/9] Correct the docstring for the C++ flattening phase function. --- python/packages/isce3/image/flatten.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/packages/isce3/image/flatten.py b/python/packages/isce3/image/flatten.py index e95997275..6acf424d3 100644 --- a/python/packages/isce3/image/flatten.py +++ b/python/packages/isce3/image/flatten.py @@ -78,7 +78,7 @@ def get_flattening_phase_at_coords( out_rg_first_pixel: int, ) -> np.ndarray: """ - Acquire the phase of the given carrier at each given index of a radar scene. + Acquire the phase necessary to flatten an SLC at each given index of a radar scene. Parameters ----------