Skip to content

Commit b7884a8

Browse files
hfattahiHeresh Fattahi
authored andcommitted
Allow passing topo output rasters from python (#808)
* allow passing topo output rasters from python * remove unused tempfile * add sanity checks * import isce3 instead of pybind_isce3 * add more sanity checks * clang-format Co-authored-by: Heresh Fattahi <[email protected]>
1 parent 3de04a9 commit b7884a8

File tree

5 files changed

+454
-111
lines changed

5 files changed

+454
-111
lines changed

cxx/isce3/geometry/TopoLayers.h

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,64 @@ class isce3::geometry::TopoLayers {
114114
_localIncRaster = &localIncRaster;
115115
_localPsiRaster = &localPsiRaster;
116116
_simRaster = &simRaster;
117+
118+
// Update sizes
119+
_width = xRaster.width();
120+
_length = xRaster.length();
121+
122+
if ((yRaster.width() != _width) || (yRaster.length() != _length)) {
123+
throw isce3::except::DomainError(ISCE_SRCINFO(),
124+
"The shape of the input y raster is different from x "
125+
"raster "
126+
"All input rasters must have the same shape.");
127+
}
128+
129+
if ((zRaster.width() != _width) || (zRaster.length() != _length)) {
130+
throw isce3::except::DomainError(ISCE_SRCINFO(),
131+
"The shape of the input z raster is different from x "
132+
"raster "
133+
"All input rasters must have the same shape.");
134+
}
135+
136+
if ((incRaster.width() != _width) ||
137+
(incRaster.length() != _length)) {
138+
throw isce3::except::DomainError(ISCE_SRCINFO(),
139+
"The shape of the input incidence angle raster is "
140+
"different from x raster "
141+
"All input rasters must have the same shape.");
142+
}
143+
144+
if ((hdgRaster.width() != _width) ||
145+
(hdgRaster.length() != _length)) {
146+
throw isce3::except::DomainError(ISCE_SRCINFO(),
147+
"The shape of the input heading raster is different "
148+
"from x raster "
149+
"All input rasters must have the same shape.");
150+
}
151+
152+
if ((localIncRaster.width() != _width) ||
153+
(localIncRaster.length() != _length)) {
154+
throw isce3::except::DomainError(ISCE_SRCINFO(),
155+
"The shape of the input local incidence angle raster "
156+
"is different from x raster "
157+
"All input rasters must have the same shape.");
158+
}
159+
160+
if ((localPsiRaster.width() != _width) ||
161+
(localPsiRaster.length() != _length)) {
162+
throw isce3::except::DomainError(ISCE_SRCINFO(),
163+
"The shape of the input local Psi raster is different "
164+
"from x raster "
165+
"All input rasters must have the same shape.");
166+
}
167+
168+
if ((simRaster.width() != _width) ||
169+
(simRaster.length() != _length)) {
170+
throw isce3::except::DomainError(ISCE_SRCINFO(),
171+
"The shape of the input simulated amplitude raster is "
172+
"different from x raster "
173+
"All input rasters must have the same shape.");
174+
}
117175
}
118176

119177
// Set rasters (plus mask raster) from externally created rasters
@@ -131,6 +189,70 @@ class isce3::geometry::TopoLayers {
131189
_localPsiRaster = &localPsiRaster;
132190
_simRaster = &simRaster;
133191
_maskRaster = &maskRaster;
192+
193+
// Update sizes
194+
_width = xRaster.width();
195+
_length = xRaster.length();
196+
197+
if ((yRaster.width() != _width) || (yRaster.length() != _length)) {
198+
throw isce3::except::DomainError(ISCE_SRCINFO(),
199+
"The shape of the y raster is different from x raster "
200+
"All input rasters must have the same shape.");
201+
}
202+
203+
if ((zRaster.width() != _width) || (zRaster.length() != _length)) {
204+
throw isce3::except::DomainError(ISCE_SRCINFO(),
205+
"The shape of the z raster is different from x raster "
206+
"All input rasters must have the same shape.");
207+
}
208+
209+
if ((incRaster.width() != _width) ||
210+
(incRaster.length() != _length)) {
211+
throw isce3::except::DomainError(ISCE_SRCINFO(),
212+
"The shape of the incidence angle raster is different "
213+
"from x raster "
214+
"All input rasters must have the same shape.");
215+
}
216+
217+
if ((hdgRaster.width() != _width) ||
218+
(hdgRaster.length() != _length)) {
219+
throw isce3::except::DomainError(ISCE_SRCINFO(),
220+
"The shape of the heading raster is different from x "
221+
"raster "
222+
"All input rasters must have the same shape.");
223+
}
224+
225+
if ((localIncRaster.width() != _width) ||
226+
(localIncRaster.length() != _length)) {
227+
throw isce3::except::DomainError(ISCE_SRCINFO(),
228+
"The shape of the local incidence angle raster is "
229+
"different from x raster "
230+
"All input rasters must have the same shape.");
231+
}
232+
233+
if ((localPsiRaster.width() != _width) ||
234+
(localPsiRaster.length() != _length)) {
235+
throw isce3::except::DomainError(ISCE_SRCINFO(),
236+
"The shape of the local Psi raster is different from x "
237+
"raster "
238+
"All input rasters must have the same shape.");
239+
}
240+
241+
if ((simRaster.width() != _width) ||
242+
(simRaster.length() != _length)) {
243+
throw isce3::except::DomainError(ISCE_SRCINFO(),
244+
"The shape of the simulated amplitude raster is "
245+
"different from x raster "
246+
"All input rasters must have the same shape.");
247+
}
248+
249+
if ((maskRaster.width() != _width) ||
250+
(maskRaster.length() != _length)) {
251+
throw isce3::except::DomainError(ISCE_SRCINFO(),
252+
"The shape of the shadow/layover raster is different "
253+
"from x raster "
254+
"All input rasters must have the same shape.");
255+
}
134256
}
135257

136258
// Get array references
@@ -259,6 +381,11 @@ class isce3::geometry::TopoLayers {
259381

260382
// Directory for placing rasters
261383
std::string _topodir;
384+
385+
// Flag indicates if the Class owns the Rasters
386+
// Should be True when initRasters is called
387+
// Should be false when the Rasters are passed
388+
// from outside and setRaster method is called
262389
bool _haveRasters;
263390

264391
};

python/extensions/pybind_isce3/cuda/geometry/rdr2geo.cpp

Lines changed: 71 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,15 @@ namespace py = pybind11;
1717
void addbinding(py::class_<Topo> & pyRdr2Geo)
1818
{
1919
pyRdr2Geo
20-
.def(py::init([](const isce3::product::RadarGridParameters & radar_grid,
21-
const isce3::core::Orbit & orbit,
22-
const isce3::core::Ellipsoid & ellipsoid,
23-
const isce3::core::LUT2d<double> & doppler,
24-
const double threshold,
25-
const int numiter,
26-
const int extraiter,
27-
const dataInterpMethod dem_interp_method,
28-
const int epsg_out,
29-
const bool compute_mask)
30-
{
20+
.def(py::init([](const isce3::product::RadarGridParameters&
21+
radar_grid,
22+
const isce3::core::Orbit& orbit,
23+
const isce3::core::Ellipsoid& ellipsoid,
24+
const isce3::core::LUT2d<double>& doppler,
25+
const double threshold, const int numiter,
26+
const int extraiter,
27+
const dataInterpMethod dem_interp_method,
28+
const int epsg_out, const bool compute_mask) {
3129
auto rdr2geo_obj = Topo(radar_grid, orbit, ellipsoid, doppler);
3230
rdr2geo_obj.threshold(threshold);
3331
rdr2geo_obj.numiter(numiter);
@@ -37,41 +35,66 @@ void addbinding(py::class_<Topo> & pyRdr2Geo)
3735
rdr2geo_obj.computeMask(compute_mask);
3836
return rdr2geo_obj;
3937
}),
40-
py::arg("radar_grid"),
41-
py::arg("orbit"),
42-
py::arg("ellipsoid"),
43-
py::arg("doppler") = isce3::core::LUT2d<double>(),
44-
py::arg("threshold") = 0.05,
45-
py::arg("numiter") = 25,
46-
py::arg("extraiter") = 10,
47-
py::arg("dem_interp_method") = isce3::core::BIQUINTIC_METHOD,
48-
py::arg("epsg_out") = 4326,
49-
py::arg("compute_mask") = true)
50-
.def("topo", py::overload_cast<isce3::io::Raster &, const std::string &>
51-
(&Topo::topo),
52-
py::arg("dem_raster"),
53-
py::arg("outdir"))
54-
.def_property_readonly("orbit", &Topo::orbit)
55-
.def_property_readonly("ellipsoid", &Topo::ellipsoid)
56-
.def_property_readonly("doppler", &Topo::doppler)
57-
.def_property_readonly("radar_grid", &Topo::radarGridParameters)
58-
.def_property("threshold",
59-
py::overload_cast<>(&Topo::threshold, py::const_),
60-
py::overload_cast<double>(&Topo::threshold))
61-
.def_property("numiter",
62-
py::overload_cast<>(&Topo::numiter, py::const_),
63-
py::overload_cast<int>(&Topo::numiter))
64-
.def_property("extraiter",
65-
py::overload_cast<>(&Topo::extraiter, py::const_),
66-
py::overload_cast<int>(&Topo::extraiter))
67-
.def_property("dem_interp_method",
68-
py::overload_cast<>(&Topo::demMethod, py::const_),
69-
py::overload_cast<dataInterpMethod>(&Topo::demMethod))
70-
.def_property("epsg_out",
71-
py::overload_cast<>(&Topo::epsgOut, py::const_),
72-
py::overload_cast<int>(&Topo::epsgOut))
73-
.def_property("compute_mask",
74-
py::overload_cast<>(&Topo::computeMask, py::const_),
75-
py::overload_cast<bool>(&Topo::computeMask))
76-
;
38+
py::arg("radar_grid"), py::arg("orbit"),
39+
py::arg("ellipsoid"),
40+
py::arg("doppler") = isce3::core::LUT2d<double>(),
41+
py::arg("threshold") = 0.05, py::arg("numiter") = 25,
42+
py::arg("extraiter") = 10,
43+
py::arg("dem_interp_method") =
44+
isce3::core::BIQUINTIC_METHOD,
45+
py::arg("epsg_out") = 4326, py::arg("compute_mask") = true)
46+
.def("topo",
47+
py::overload_cast<isce3::io::Raster&, const std::string&>(
48+
&Topo::topo),
49+
py::arg("dem_raster"), py::arg("outdir"))
50+
.def("topo",
51+
py::overload_cast<isce3::io::Raster&, isce3::io::Raster&,
52+
isce3::io::Raster&, isce3::io::Raster&,
53+
isce3::io::Raster&, isce3::io::Raster&,
54+
isce3::io::Raster&, isce3::io::Raster&,
55+
isce3::io::Raster&, isce3::io::Raster&>(
56+
&Topo::topo),
57+
py::arg("dem_raster"), py::arg("x_raster"),
58+
py::arg("y_raster"), py::arg("height_raster"),
59+
py::arg("incidence_angle_raster"),
60+
py::arg("heading_angle_raster"),
61+
py::arg("local_incidence_angle_raster"),
62+
py::arg("local_Psi_raster"),
63+
py::arg("simulated_amplitude_raster"),
64+
py::arg("shadow_layover_raster"))
65+
.def("topo",
66+
py::overload_cast<isce3::io::Raster&, isce3::io::Raster&,
67+
isce3::io::Raster&, isce3::io::Raster&,
68+
isce3::io::Raster&, isce3::io::Raster&,
69+
isce3::io::Raster&, isce3::io::Raster&,
70+
isce3::io::Raster&>(&Topo::topo),
71+
py::arg("dem_raster"), py::arg("x_raster"),
72+
py::arg("y_raster"), py::arg("height_raster"),
73+
py::arg("incidence_angle_raster"),
74+
py::arg("heading_angle_raster"),
75+
py::arg("local_incidence_angle_raster"),
76+
py::arg("local_Psi_raster"),
77+
py::arg("simulated_amplitude_raster"))
78+
.def_property_readonly("orbit", &Topo::orbit)
79+
.def_property_readonly("ellipsoid", &Topo::ellipsoid)
80+
.def_property_readonly("doppler", &Topo::doppler)
81+
.def_property_readonly("radar_grid", &Topo::radarGridParameters)
82+
.def_property("threshold",
83+
py::overload_cast<>(&Topo::threshold, py::const_),
84+
py::overload_cast<double>(&Topo::threshold))
85+
.def_property("numiter",
86+
py::overload_cast<>(&Topo::numiter, py::const_),
87+
py::overload_cast<int>(&Topo::numiter))
88+
.def_property("extraiter",
89+
py::overload_cast<>(&Topo::extraiter, py::const_),
90+
py::overload_cast<int>(&Topo::extraiter))
91+
.def_property("dem_interp_method",
92+
py::overload_cast<>(&Topo::demMethod, py::const_),
93+
py::overload_cast<dataInterpMethod>(&Topo::demMethod))
94+
.def_property("epsg_out",
95+
py::overload_cast<>(&Topo::epsgOut, py::const_),
96+
py::overload_cast<int>(&Topo::epsgOut))
97+
.def_property("compute_mask",
98+
py::overload_cast<>(&Topo::computeMask, py::const_),
99+
py::overload_cast<bool>(&Topo::computeMask));
77100
}

0 commit comments

Comments
 (0)