|
1 | 1 | #include "Topo.h" |
2 | 2 |
|
3 | 3 | #include <algorithm> |
| 4 | +#include <cassert> |
4 | 5 | #include <chrono> |
5 | 6 | #include <cmath> |
6 | 7 | #include <cstdio> |
@@ -179,59 +180,76 @@ topo(Raster & demRaster, TopoLayers & layers) |
179 | 180 | // Allocate vector for storing satellite position for each line |
180 | 181 | std::vector<Vec3> satPosition(blockLength); |
181 | 182 |
|
182 | | - // For each line in block |
183 | | - double tline; |
184 | | - for (size_t blockLine = 0; blockLine < blockLength; ++blockLine) { |
185 | | - |
186 | | - if (blockLine % std::max((int) (blockLength / 100), 1) == 0) |
187 | | - printf("\rTopo progress (block %d/%d): %d%%", |
188 | | - (int) block + 1, (int) nBlocks, |
189 | | - (int) (blockLine * 1e2 / blockLength)), |
190 | | - fflush(stdout); |
191 | | - |
192 | | - // Global line index |
193 | | - size_t line = lineStart + blockLine; |
194 | | - |
195 | | - // Initialize orbital data for this azimuth line |
196 | | - Basis TCNbasis; |
197 | | - Vec3 pos, vel; |
198 | | - _initAzimuthLine(line, tline, pos, vel, TCNbasis); |
199 | | - |
200 | | - satPosition[blockLine] = pos; |
201 | | - |
202 | | - // Compute velocity magnitude |
203 | | - const double satVmag = vel.norm(); |
204 | | - |
205 | | - // For each slant range bin |
206 | | - #pragma omp parallel for reduction(+:totalconv) |
207 | | - for (size_t rbin = 0; rbin < _radarGrid.width(); ++rbin) { |
208 | | - |
209 | | - // Get current slant range |
210 | | - const double rng = _radarGrid.slantRange(rbin); |
211 | | - |
212 | | - // Get current Doppler value |
213 | | - const double dopfact = (0.5 * _radarGrid.wavelength() |
214 | | - * (_doppler.eval(tline, rng) / satVmag)) * rng; |
215 | | - |
216 | | - // Store slant range bin data in Pixel |
217 | | - Pixel pixel(rng, dopfact, rbin); |
218 | | - |
219 | | - // Initialize LLH to middle of input DEM and average height |
220 | | - Vec3 llh = demInterp.midLonLat(); |
221 | | - |
222 | | - // Perform rdr->geo iterations |
223 | | - int geostat = rdr2geo( |
224 | | - pixel, TCNbasis, pos, vel, _ellipsoid, demInterp, llh, |
225 | | - _radarGrid.lookSide(), _threshold, _numiter, _extraiter); |
226 | | - totalconv += geostat; |
227 | | - |
228 | | - // Save data in output arrays |
229 | | - _setOutputTopoLayers(llh, layers, blockLine, pixel, pos, vel, |
230 | | - TCNbasis, demInterp); |
| 183 | + // Get the midpoint of the DEM block in LLH coordinates. |
| 184 | + // This should always be safe since the call to `computeDEMBounds()` |
| 185 | + // above loads a block of the DEM raster. |
| 186 | + assert(demInterp.haveRaster()); |
| 187 | + const auto dem_midpoint = demInterp.midLonLat(); |
| 188 | + |
| 189 | + #pragma omp parallel |
| 190 | + { |
| 191 | + // Thread-local count of the total number of rdr2geo calls that |
| 192 | + // converged successfully. |
| 193 | + size_t totalconv_thread = 0; |
| 194 | + |
| 195 | + // For each line in block |
| 196 | + #pragma omp for |
| 197 | + for (size_t blockLine = 0; blockLine < blockLength; ++blockLine) { |
| 198 | + // Global line index |
| 199 | + size_t line = lineStart + blockLine; |
| 200 | + |
| 201 | + // Initialize orbital data for this azimuth line |
| 202 | + Basis TCNbasis; |
| 203 | + double tline; |
| 204 | + Vec3 pos, vel; |
| 205 | + _initAzimuthLine(line, tline, pos, vel, TCNbasis); |
| 206 | + |
| 207 | + satPosition[blockLine] = pos; |
| 208 | + |
| 209 | + // Compute velocity magnitude |
| 210 | + const double satVmag = vel.norm(); |
| 211 | + |
| 212 | + // Initialize LLH to middle of input DEM block and average height. |
| 213 | + auto llh = dem_midpoint; |
| 214 | + |
| 215 | + for (size_t rbin = 0; rbin < _radarGrid.width(); ++rbin) { |
| 216 | + |
| 217 | + // Get current slant range |
| 218 | + const double rng = _radarGrid.slantRange(rbin); |
| 219 | + |
| 220 | + // Get current Doppler value |
| 221 | + const double dopfact = (0.5 * _radarGrid.wavelength() |
| 222 | + * (_doppler.eval(tline, rng) / satVmag)) |
| 223 | + * rng; |
| 224 | + |
| 225 | + // Store slant range bin data in Pixel |
| 226 | + Pixel pixel(rng, dopfact, rbin); |
| 227 | + |
| 228 | + // Perform rdr->geo iterations |
| 229 | + int geostat = rdr2geo( |
| 230 | + pixel, TCNbasis, pos, vel, _ellipsoid, demInterp, llh, |
| 231 | + _radarGrid.lookSide(), _threshold, _numiter, _extraiter); |
| 232 | + totalconv_thread += geostat; |
| 233 | + |
| 234 | + // Save data in output arrays |
| 235 | + _setOutputTopoLayers(llh, layers, blockLine, pixel, pos, vel, |
| 236 | + TCNbasis, demInterp); |
| 237 | + |
| 238 | + // If rdr2geo failed to converge, re-initialize the LLH estimate for |
| 239 | + // the next iteration. Otherwise, reuse the current solution as the |
| 240 | + // initial guess for the next range bin. |
| 241 | + if (geostat == 0) { |
| 242 | + llh = dem_midpoint; |
| 243 | + } |
| 244 | + } |
| 245 | + } |
231 | 246 |
|
232 | | - } // end OMP for loop pixels in block |
233 | | - } // end for loop lines in block |
234 | | - printf("\rTopo progress (block %d/%d): 100%%\n", |
| 247 | + // Collect the total number of converged rdr2geo calls from among all |
| 248 | + // threads. |
| 249 | + #pragma omp atomic |
| 250 | + totalconv += totalconv_thread; |
| 251 | + } |
| 252 | + printf("\rTopo progress (block %d/%d): Done\n", |
235 | 253 | (int) block + 1, (int) nBlocks), fflush(stdout); |
236 | 254 |
|
237 | 255 | // Compute layover/shadow masks for the block |
@@ -447,9 +465,9 @@ computeDEMBounds(Raster & demRaster, DEMInterpolator & demInterp, size_t lineOff |
447 | 465 | } |
448 | 466 |
|
449 | 467 | void isce3::geometry::Topo:: |
450 | | -_setOutputTopoLayers(Vec3 & targetLLH, TopoLayers & layers, size_t line, |
451 | | - Pixel & pixel, Vec3& pos, Vec3& vel, Basis & TCNbasis, |
452 | | - DEMInterpolator & demInterp) |
| 468 | +_setOutputTopoLayers(const Vec3& targetLLH, TopoLayers & layers, size_t line, |
| 469 | + const Pixel& pixel, const Vec3& pos, const Vec3& vel, |
| 470 | + const Basis& TCNbasis, const DEMInterpolator& demInterp) |
453 | 471 | { |
454 | 472 | const double degrees = 180.0 / M_PI; |
455 | 473 |
|
|
0 commit comments