1
1
#include " GeocodeCov.h"
2
+ #include " GeocodeHelpers.h"
2
3
3
4
#include < algorithm>
4
5
#include < cmath>
@@ -22,48 +23,6 @@ using isce3::core::Vec3;
22
23
23
24
namespace isce3 { namespace geocode {
24
25
25
- template <typename T1, typename T2>
26
- auto operator *(const std::complex <T1>& lhs, const T2& rhs)
27
- {
28
- using U = typename std::common_type_t <T1, T2>;
29
- return std::complex <U>(lhs) * U (rhs);
30
- }
31
-
32
- template <typename T1, typename T2>
33
- auto operator *(const T1& lhs, const std::complex <T2>& rhs)
34
- {
35
- using U = typename std::common_type_t <T1, T2>;
36
- return U (lhs) * std::complex <U>(rhs);
37
- }
38
-
39
- template <typename T, typename T_out>
40
- void _convertToOutputType (T a, T_out& b)
41
- {
42
- b = a;
43
- }
44
-
45
- template <typename T, typename T_out>
46
- void _convertToOutputType (std::complex <T> a, T_out& b)
47
- {
48
- b = std::norm (a);
49
- }
50
-
51
- template <typename T, typename T_out>
52
- void _convertToOutputType (std::complex <T> a, std::complex <T_out>& b)
53
- {
54
- b = a;
55
- }
56
-
57
- template <typename T, typename T_out>
58
- void _accumulate (T_out& band_value, T a, double b)
59
- {
60
- if (b == 0 )
61
- return ;
62
- T_out a2;
63
- _convertToOutputType (a, a2);
64
- band_value += a2 * b;
65
- }
66
-
67
26
template <class T >
68
27
void Geocode<T>::updateGeoGrid(
69
28
const isce3::product::RadarGridParameters& radar_grid,
@@ -1903,312 +1862,6 @@ template class Geocode<double>;
1903
1862
template class Geocode <std::complex <float >>;
1904
1863
template class Geocode <std::complex <double >>;
1905
1864
1906
- // template <typename T>
1907
- std::vector<float > getGeoAreaElementMean (
1908
- const std::vector<double >& x_vect, const std::vector<double >& y_vect,
1909
- const isce3::product::RadarGridParameters& radar_grid,
1910
- const isce3::core::Orbit& orbit,
1911
- const isce3::core::LUT2d<double >& input_dop,
1912
- isce3::io::Raster& input_raster, isce3::io::Raster& dem_raster,
1913
- bool flag_apply_rtc,
1914
- isce3::geometry::rtcInputTerrainRadiometry input_terrain_radiometry,
1915
- isce3::geometry::rtcOutputTerrainRadiometry output_terrain_radiometry,
1916
- int exponent, geocodeOutputMode output_mode, double geogrid_upsampling,
1917
- float rtc_min_value_db, double abs_cal_factor, float radar_grid_nlooks,
1918
- float * out_nlooks, isce3::core::dataInterpMethod dem_interp_method,
1919
- double threshold, int num_iter, double delta_range)
1920
- {
1921
-
1922
- pyre::journal::info_t info (" isce.geometry.getGeoAreaElementMean" );
1923
-
1924
- if (std::isnan (geogrid_upsampling))
1925
- geogrid_upsampling = 1 ;
1926
- assert (geogrid_upsampling > 0 );
1927
-
1928
- const double x0 = std::min_element (x_vect.begin (), x_vect.end ())[0 ];
1929
- const double xf = std::max_element (x_vect.begin (), x_vect.end ())[0 ];
1930
-
1931
- const double y0 = std::min_element (y_vect.begin (), y_vect.end ())[0 ];
1932
- const double yf = std::max_element (y_vect.begin (), y_vect.end ())[0 ];
1933
-
1934
- const double dx = dem_raster.dx ();
1935
- const double dy = dem_raster.dy ();
1936
-
1937
- std::string input_terrain_radiometry_str =
1938
- get_input_terrain_radiometry_str (input_terrain_radiometry);
1939
-
1940
- info << " input radiometry: " << input_terrain_radiometry_str
1941
- << pyre::journal::newline << " look side: " << radar_grid.lookSide ()
1942
- << pyre::journal::newline
1943
- << " radar_grid length: " << radar_grid.length ()
1944
- << " , width: " << radar_grid.width () << pyre::journal::newline
1945
- << " RTC min value [dB]: " << rtc_min_value_db << pyre::journal::endl;
1946
-
1947
- const double margin_x = std::abs (dx) * 10 ;
1948
- const double margin_y = std::abs (dy) * 10 ;
1949
- isce3::geometry::DEMInterpolator dem_interp;
1950
-
1951
- dem_interp.loadDEM (dem_raster, x0 - margin_x, xf + margin_x,
1952
- std::min (y0, yf) - margin_y,
1953
- std::max (y0, yf) + margin_y);
1954
-
1955
- isce3::core::Ellipsoid ellipsoid =
1956
- isce3::core::Ellipsoid (isce3::core::EarthSemiMajorAxis,
1957
- isce3::core::EarthEccentricitySquared);
1958
-
1959
- int epsg = dem_raster.getEPSG ();
1960
- std::unique_ptr<isce3::core::ProjectionBase> proj (
1961
- isce3::core::createProj (epsg));
1962
- const double pixazm = radar_grid.azimuthTimeInterval ();
1963
- const double start = radar_grid.sensingStart () - 0.5 * pixazm;
1964
- const double dr = radar_grid.rangePixelSpacing ();
1965
- double r0 = radar_grid.startingRange () - 0.5 * dr;
1966
-
1967
- double a = radar_grid.sensingMid ();
1968
- double r = radar_grid.midRange ();
1969
-
1970
- if (x_vect.size () != y_vect.size ()) {
1971
- std::string error_message =
1972
- " ERROR x and y vectors have a different number of elements." ;
1973
- throw isce3::except::InvalidArgument (ISCE_SRCINFO (), error_message);
1974
- }
1975
- int n_elements = x_vect.size ();
1976
- std::vector<double > a_vect, r_vect;
1977
- a_vect.reserve (n_elements);
1978
- r_vect.reserve (n_elements);
1979
-
1980
- info << " polygon indexes (a, r): " ;
1981
-
1982
- for (int i = 0 ; i < n_elements; ++i) {
1983
-
1984
- const double x = x_vect[i];
1985
- const double y = y_vect[i];
1986
-
1987
- const Vec3 dem11 = {x, y, dem_interp.interpolateXY (x, y)};
1988
- int converged = isce3::geometry::geo2rdr (
1989
- proj->inverse (dem11), ellipsoid, orbit, input_dop, a, r,
1990
- radar_grid.wavelength (), radar_grid.lookSide (), threshold,
1991
- num_iter, delta_range);
1992
- if (!converged) {
1993
- info << " WARNING convergence not found for vertex (x, y): " << x
1994
- << " , " << y << pyre::journal::endl;
1995
- continue ;
1996
- }
1997
- double a_index = (a - start) / pixazm;
1998
- double r_index = (r - r0) / dr;
1999
-
2000
- info << " (" << a_index << " , " << r_index << " ), " ;
2001
-
2002
- a_vect.emplace_back (a_index);
2003
- r_vect.emplace_back (r_index);
2004
- }
2005
-
2006
- info << pyre::journal::endl;
2007
-
2008
- const double a_min = std::min_element (a_vect.begin (), a_vect.end ())[0 ];
2009
- const double a_max = std::max_element (a_vect.begin (), a_vect.end ())[0 ];
2010
-
2011
- const double r_min = std::min_element (r_vect.begin (), r_vect.end ())[0 ];
2012
- const double r_max = std::max_element (r_vect.begin (), r_vect.end ())[0 ];
2013
-
2014
- const int y_min = std::max (0 , (int ) std::floor (a_min));
2015
- const int x_min = std::max (0 , (int ) std::floor (r_min));
2016
- const int ysize =
2017
- std::min ((int ) radar_grid.length (), (int ) std::ceil (a_max)) - y_min;
2018
- const int xsize =
2019
- std::min ((int ) radar_grid.width (), (int ) std::ceil (r_max)) - x_min;
2020
-
2021
- info << " cropping radar grid from index (a0: " << y_min;
2022
- info << " , r0: " << x_min << " ) to index (af: " << y_min + ysize;
2023
- info << " , rf: " << x_min + xsize << " )" << pyre::journal::endl;
2024
-
2025
- isce3::product::RadarGridParameters radar_grid_cropped =
2026
- radar_grid.offsetAndResize (y_min, x_min, ysize, xsize);
2027
-
2028
- info << " cropped radar_grid length: " << radar_grid_cropped.length ()
2029
- << " , width: " << radar_grid_cropped.width () << pyre::journal::newline;
2030
-
2031
- if (output_mode == geocodeOutputMode::INTERP) {
2032
- std::string error_msg = " invalid option" ;
2033
- throw isce3::except::InvalidArgument (ISCE_SRCINFO (), error_msg);
2034
- }
2035
-
2036
- if (abs_cal_factor != 1 )
2037
- info << " absolute calibration factor: " << abs_cal_factor
2038
- << pyre::journal::endl;
2039
-
2040
- if (flag_apply_rtc) {
2041
-
2042
- std::string input_terrain_radiometry_str =
2043
- get_input_terrain_radiometry_str (input_terrain_radiometry);
2044
- info << " input radiometry: " << input_terrain_radiometry_str
2045
- << pyre::journal::endl;
2046
- }
2047
-
2048
- isce3::core::Matrix<float > rtc_area;
2049
- std::unique_ptr<isce3::io::Raster> rtc_raster_unique_ptr;
2050
- if (flag_apply_rtc) {
2051
-
2052
- info << " computing RTC area factor..." << pyre::journal::endl;
2053
- rtc_raster_unique_ptr = std::make_unique<isce3::io::Raster>(
2054
- " /vsimem/dummy" , radar_grid_cropped.width (),
2055
- radar_grid_cropped.length (), 1 , GDT_Float32, " ENVI" );
2056
- isce3::geometry::rtcAreaMode rtc_area_mode =
2057
- isce3::geometry::rtcAreaMode::AREA_FACTOR;
2058
- isce3::geometry::rtcAlgorithm rtc_algorithm =
2059
- isce3::geometry::rtcAlgorithm::RTC_AREA_PROJECTION;
2060
-
2061
- isce3::geometry::rtcMemoryMode rtc_memory_mode =
2062
- isce3::geometry::rtcMemoryMode::RTC_SINGLE_BLOCK;
2063
-
2064
- computeRtc (radar_grid_cropped, orbit, input_dop, dem_raster,
2065
- *rtc_raster_unique_ptr.get (), input_terrain_radiometry,
2066
- output_terrain_radiometry, rtc_area_mode, rtc_algorithm,
2067
- geogrid_upsampling * 2 , rtc_min_value_db, radar_grid_nlooks,
2068
- nullptr , rtc_memory_mode, dem_interp_method, threshold, num_iter,
2069
- delta_range);
2070
-
2071
- rtc_area.resize (radar_grid_cropped.length (),
2072
- radar_grid_cropped.width ());
2073
-
2074
- rtc_raster_unique_ptr->getBlock (rtc_area.data (), 0 , 0 ,
2075
- radar_grid_cropped.width (),
2076
- radar_grid_cropped.length (), 1 );
2077
-
2078
- info << " ... done (RTC) " << pyre::journal::endl;
2079
- }
2080
-
2081
- double rtc_min_value = 0 ;
2082
- if (!std::isnan (rtc_min_value_db) && flag_apply_rtc) {
2083
- rtc_min_value = std::pow (10 ., (rtc_min_value_db / 10 .));
2084
- info << " RTC min. value: " << rtc_min_value_db
2085
- << " [dB] = " << rtc_min_value << pyre::journal::endl;
2086
- }
2087
-
2088
- GDALDataType input_dtype = input_raster.dtype ();
2089
- if (exponent == 0 && GDALDataTypeIsComplex (input_dtype))
2090
- exponent = 2 ;
2091
-
2092
- if (input_raster.dtype () == GDT_Float32) {
2093
- info << " dtype: GDT_Float32" << pyre::journal::endl;
2094
- return _getGeoAreaElementMean<float >(
2095
- r_vect, a_vect, x_min, y_min, flag_apply_rtc,
2096
- rtc_area, radar_grid_cropped,
2097
- input_raster, rtc_min_value, out_nlooks,
2098
- abs_cal_factor, radar_grid_nlooks);
2099
- } else if (input_raster.dtype () == GDT_CFloat32) {
2100
- info << " dtype: GDT_CFloat32" << pyre::journal::endl;
2101
- return _getGeoAreaElementMean<std::complex <float >>(
2102
- r_vect, a_vect, x_min, y_min, flag_apply_rtc,
2103
- rtc_area, radar_grid_cropped,
2104
- input_raster, rtc_min_value, out_nlooks,
2105
- abs_cal_factor, radar_grid_nlooks);
2106
- } else
2107
- info << " ERROR not implemented for datatype: " << input_raster.dtype ()
2108
- << pyre::journal::endl;
2109
-
2110
- std::vector<float > empty_vector;
2111
- return empty_vector;
2112
- }
2113
-
2114
- template <typename T>
2115
- std::vector<float > _getGeoAreaElementMean (
2116
- const std::vector<double >& r_vect, const std::vector<double >& a_vect,
2117
- int x_min, int y_min, bool flag_apply_rtc,
2118
- isce3::core::Matrix<float >& rtc_area,
2119
- const isce3::product::RadarGridParameters& radar_grid,
2120
- isce3::io::Raster& input_raster,
2121
- float rtc_min_value, float * out_nlooks, double abs_cal_factor,
2122
- float radar_grid_nlooks)
2123
- {
2124
-
2125
- pyre::journal::info_t info (" isce.geometry._getGeoAreaElementMean" );
2126
-
2127
- // number of bands in the input raster
2128
- const int nbands = input_raster.numBands ();
2129
- const int size_y = radar_grid.length ();
2130
- const int size_x = radar_grid.width ();
2131
- info << " nbands: " << nbands << pyre::journal::endl;
2132
-
2133
- std::vector<std::unique_ptr<isce3::core::Matrix<T>>> rdrDataBlock;
2134
- rdrDataBlock.reserve (nbands);
2135
-
2136
- for (int band = 0 ; band < nbands; ++band) {
2137
- if (nbands == 1 )
2138
- info << " loading slant-range image..." << pyre::journal::endl;
2139
- else
2140
- info << " loading slant-range band: " << band << pyre::journal::endl;
2141
- rdrDataBlock.emplace_back (
2142
- std::make_unique<isce3::core::Matrix<T>>(size_y, size_x));
2143
-
2144
- input_raster.getBlock (rdrDataBlock[band]->data (), x_min, y_min,
2145
- size_x, size_y, band + 1 );
2146
- }
2147
-
2148
- isce3::core::Matrix<double > w_arr (size_y, size_x);
2149
- w_arr.fill (0 );
2150
-
2151
- int plane_orientation;
2152
- if (radar_grid.lookSide () == isce3::core::LookSide::Left)
2153
- plane_orientation = -1 ;
2154
- else
2155
- plane_orientation = 1 ;
2156
-
2157
- double w_total = 0 ;
2158
- for (int i = 0 ; i < r_vect.size (); ++i) {
2159
-
2160
- double x00, y00, x01, y01;
2161
- y00 = a_vect[i];
2162
- x00 = r_vect[i];
2163
-
2164
- if (i < r_vect.size () - 1 ) {
2165
- y01 = a_vect[i + 1 ];
2166
- x01 = r_vect[i + 1 ];
2167
- } else {
2168
- y01 = a_vect[0 ];
2169
- x01 = r_vect[0 ];
2170
- }
2171
- isce3::geometry::areaProjIntegrateSegment (
2172
- y00 - y_min, y01 - y_min, x00 - x_min, x01 - x_min, size_y,
2173
- size_x, w_arr, w_total, plane_orientation);
2174
- }
2175
- std::vector<float > cumulative_sum (nbands);
2176
- double nlooks = 0 ;
2177
-
2178
- Geocode<T> geo_obj;
2179
- for (int y = 0 ; y < size_y; ++y)
2180
- for (int x = 0 ; x < size_x; ++x) {
2181
- double w = w_arr (y, x);
2182
- if (w == 0 )
2183
- continue ;
2184
- if (flag_apply_rtc) {
2185
- const float rtc_value = rtc_area (y, x);
2186
- if (std::isnan (rtc_value) || rtc_value < rtc_min_value)
2187
- continue ;
2188
- nlooks += w;
2189
- w /= rtc_value;
2190
- } else {
2191
- nlooks += w;
2192
- }
2193
-
2194
- for (int band = 0 ; band < nbands; ++band)
2195
- _accumulate (cumulative_sum[band],
2196
- rdrDataBlock[band]->operator ()(y, x), w);
2197
- }
2198
-
2199
- info << " nlooks: " << radar_grid_nlooks * std::abs (nlooks)
2200
- << pyre::journal::endl;
2201
- for (int band = 0 ; band < nbands; ++band) {
2202
- cumulative_sum[band] = (cumulative_sum[band] * abs_cal_factor / nlooks);
2203
- info << " mean value (band = " << band << " ): " << cumulative_sum[band]
2204
- << pyre::journal::endl;
2205
- }
2206
-
2207
- if (out_nlooks != nullptr ) {
2208
- *out_nlooks = radar_grid_nlooks * std::abs (nlooks);
2209
- }
2210
-
2211
- return cumulative_sum;
2212
- }
2213
1865
2214
- }} // namespace isce3::geocode
1866
+ } // namespace geocode
1867
+ } // namespace isce3
0 commit comments