@@ -79,14 +79,12 @@ class represents a polynomial function of range
79
79
A = A / snr [:, None ]
80
80
z = z / snr
81
81
82
- return_val = True
83
- val , res , _ , eigs = np .linalg .lstsq (A , z , rcond = cond )
82
+ val , res , _ , _ = np .linalg .lstsq (A , z , rcond = cond )
84
83
if len (res ) > 0 :
85
84
print ('Chi squared: %f' % (np .sqrt (res / (1.0 * len (z )))))
86
85
else :
87
86
print ('No chi squared value....' )
88
87
print ('Try reducing rank of polynomial.' )
89
- return_val = False
90
88
91
89
coeffs = []
92
90
count = 0
@@ -252,7 +250,7 @@ def slc_to_vrt_file(self, out_path):
252
250
Path of output VRT file.
253
251
'''
254
252
if not self .tiff_path :
255
- warn_str = f 'Unable write SLC to file. Burst does not contain image data; only metadata.'
253
+ warn_str = 'Unable write SLC to file. Burst does not contain image data; only metadata.'
256
254
warnings .warn (warn_str )
257
255
return
258
256
@@ -404,7 +402,42 @@ def as_dict(self):
404
402
self_as_dict [key ] = val
405
403
return self_as_dict
406
404
407
- def bistatic_delay (self , xstep = 1 , ystep = 1 ):
405
+
406
+ def _steps_to_vecs (self , range_step , az_step ):
407
+ ''' convert range_step (meters) and az_step (seconds) into aranges to
408
+ generate LUT2ds
409
+ '''
410
+ step_errs = []
411
+ if range_step <= 0 :
412
+ step_errs .append ('range' )
413
+ if az_step <= 0 :
414
+ step_errs .append ('azimuth' )
415
+ if step_errs :
416
+ step_errs = ', ' .join (step_errs )
417
+ err_str = f'Following step size(s) <=0: { step_errs } '
418
+ raise ValueError (err_str )
419
+
420
+ n_range = np .ceil (self .width * self .range_pixel_spacing / range_step ).astype (int )
421
+ range_vec = self .starting_range + np .arange (0 , n_range ) * range_step
422
+
423
+ n_az = np .ceil (self .length * self .azimuth_time_interval / az_step ).astype (int )
424
+ rdrgrid = self .as_isce3_radargrid ()
425
+ az_vec = rdrgrid .sensing_start + np .arange (0 , n_az ) * az_step
426
+
427
+ vec_errs = []
428
+ if not range_vec :
429
+ vec_errs .append ('range' )
430
+ if not az_vec :
431
+ vec_errs .append ('azimuth' )
432
+ if vec_errs :
433
+ vec_errs = ', ' .join (vec_errs )
434
+ err_str = f'Cannot build aranges from following step(s): { vec_errs } '
435
+ raise ValueError (err_str )
436
+
437
+ return range_vec , az_vec
438
+
439
+
440
+ def bistatic_delay (self , range_step = 1 , az_step = 1 ):
408
441
'''Computes the bistatic delay correction in azimuth direction
409
442
due to the movement of the platform between pulse transmission and echo reception
410
443
as described in equation (21) in Gisinger et al. (2021, TGRS).
@@ -421,30 +454,26 @@ def bistatic_delay(self, xstep=1, ystep=1):
421
454
422
455
Parameters
423
456
-------
424
- xstep : int
425
- spacing along x direction (range direction) in units of pixels
426
-
427
- ystep : int
428
- spacing along y direction (azimuth direction) in units of pixels
457
+ range_step : int
458
+ Spacing along x/range direction [meters]
459
+ az_step : int
460
+ Spacing along y/azimuth direction [seconds]
429
461
430
462
Returns
431
463
-------
432
464
LUT2D object of bistatic delay correction in seconds as a function
433
- of the range and zimuth indices. This correction needs to be added
434
- to the SLC tagged azimuth time to get the corrected azimuth times.
465
+ of the azimuth time and slant range, or range and azimuth indices.
466
+ This correction needs to be added to the SLC tagged azimuth time to
467
+ get the corrected azimuth times.
435
468
'''
436
469
437
470
pri = 1.0 / self .prf_raw_data
438
471
tau0 = self .rank * pri
439
472
tau_mid = self .iw2_mid_range * 2.0 / isce3 .core .speed_of_light
440
473
441
- nx = np .ceil (self .width / xstep ).astype (int )
442
- ny = np .ceil (self .length / ystep ).astype (int )
443
- x = np .arange (0 , nx * xstep , xstep , dtype = int )
444
- y = np .arange (0 , ny * ystep , ystep , dtype = int )
474
+ slant_vec , az_vec = self ._steps_to_vecs (range_step , az_step )
445
475
446
- slant_range = self .starting_range + x * self .range_pixel_spacing
447
- tau = slant_range * 2.0 / isce3 .core .speed_of_light
476
+ tau = slant_vec * 2.0 / isce3 .core .speed_of_light
448
477
449
478
# the first term (tau_mid/2) is the bulk bistatic delay which was
450
479
# removed from the orginial azimuth time by the ESA IPF. Based on
@@ -454,11 +483,13 @@ def bistatic_delay(self, xstep=1, ystep=1):
454
483
# This implementation follows the Gisinger et al. (2021) for now, we
455
484
# can revise when we hear back from ESA folks.
456
485
bistatic_correction_vec = tau_mid / 2 + tau / 2 - tau0
457
- bistatic_correction = np .tile (bistatic_correction_vec .reshape (1 ,- 1 ), (ny ,1 ))
486
+ ny = az_vec .size
487
+ bistatic_correction = np .tile (bistatic_correction_vec .reshape (1 ,- 1 ),
488
+ (ny ,1 ))
458
489
459
- return isce3 .core .LUT2d (x , y , bistatic_correction )
490
+ return isce3 .core .LUT2d (slant_vec , az_vec , bistatic_correction )
460
491
461
- def geometrical_and_steering_doppler (self , xstep = 500 , ystep = 50 ):
492
+ def geometrical_and_steering_doppler (self , range_step = 500 , az_step = 50 ):
462
493
"""
463
494
Compute total Doppler which is the sum of two components:
464
495
(1) the geometrical Doppler induced by the relative movement
@@ -468,61 +499,65 @@ def geometrical_and_steering_doppler(self, xstep=500, ystep=50):
468
499
with azimuth time.
469
500
Parameters
470
501
----------
471
- xstep : int
472
- Spacing along x direction [pixels ]
473
- ystep : int
474
- Spacing along y direction [pixels ]
502
+ range_step : int
503
+ Spacing along x/range direction [meters ]
504
+ az_step : int
505
+ Spacing along y/azimuth direction [seconds ]
475
506
476
507
Returns
477
508
-------
478
- x : int
479
- The index of samples in range direction as an 1D array
480
- y : int
481
- The index of samples in azimuth direction as an 1D array
482
- total_doppler : float
483
- Total Doppler which is the sum of the geometrical Doppler and
484
- beam steering induced Doppler [Hz] as a 2D array
509
+ LUT2D object of total doppler in Hz as a function of the azimuth
510
+ time and slant range, or range and azimuth indices.
511
+ This correction needs to be added to the SLC tagged azimuth time to
512
+ get the corrected azimuth times.
485
513
"""
514
+ range_vec , az_vec = self ._steps_to_vecs (range_step , az_step )
486
515
487
- x = np .arange (0 , self .width , xstep , dtype = int )
488
- y = np .arange (0 , self .length , ystep , dtype = int )
489
- x_mesh , y_mesh = np .meshgrid (x , y )
516
+ # convert from meters to pixels
517
+ x_vec = (range_vec - self .starting_range ) / self .range_pixel_spacing
518
+
519
+ # convert from seconds to pixels
520
+ rdrgrid = self .as_isce3_radargrid ()
521
+ y_vec = (az_vec - rdrgrid .sensing_start ) / self .azimuth_time_interval
522
+
523
+ # compute az carrier components with pixels
524
+ x_mesh , y_mesh = np .meshgrid (x_vec , y_vec )
490
525
az_carr_comp = self .az_carrier_components (
491
526
offset = 0.0 ,
492
527
position = (y_mesh , x_mesh ))
493
528
494
- slant_range = self .starting_range + x * self .range_pixel_spacing
495
- geometrical_doppler = self .doppler .poly1d .eval (slant_range )
529
+ geometrical_doppler = self .doppler .poly1d .eval (range_vec )
496
530
497
531
total_doppler = az_carr_comp .antenna_steering_doppler + geometrical_doppler
498
532
499
- return x , y , total_doppler
533
+ return isce3 . core . LUT2d ( range_vec , az_vec , total_doppler )
500
534
501
- def doppler_induced_range_shift (self , xstep = 500 , ystep = 50 ):
535
+ def doppler_induced_range_shift (self , range_step = 500 , az_step = 50 ):
502
536
"""
503
537
Computes the range delay caused by the Doppler shift as described
504
538
by Gisinger et al 2021
505
539
506
540
Parameters
507
541
----------
508
- xstep : int
509
- Spacing along x direction [pixels ]
510
- ystep : int
511
- Spacing along y direction [pixels ]
542
+ range_step : int
543
+ Spacing along x/range direction [meters ]
544
+ az_step : int
545
+ Spacing along y/azimuth direction [seconds ]
512
546
513
547
Returns
514
548
-------
515
549
isce3.core.LUT2d:
516
550
LUT2D object of range delay correction [seconds] as a function
517
- of the x and y indices.
551
+ of the azimuth time and slant range, or x and y indices.
518
552
519
553
"""
554
+ range_vec , az_vec = self ._steps_to_vecs (range_step , az_step )
520
555
521
- x , y , doppler_shift = self .geometrical_and_steering_doppler (
522
- xstep = xstep , ystep = ystep )
523
- tau_corr = doppler_shift / self .range_chirp_rate
556
+ doppler_shift = self .geometrical_and_steering_doppler (range_step = range_step ,
557
+ az_step = az_step )
558
+ tau_corr = doppler_shift . data / self .range_chirp_rate
524
559
525
- return isce3 .core .LUT2d (x , y , tau_corr )
560
+ return isce3 .core .LUT2d (range_vec , az_vec , tau_corr )
526
561
527
562
def az_carrier_components (self , offset , position ):
528
563
'''
@@ -534,7 +569,7 @@ def az_carrier_components(self, offset, position):
534
569
offset: float
535
570
Offset between reference and secondary burst
536
571
position: tuple
537
- Tuple of locations along y and x directions
572
+ Tuple of locations along y and x directions in pixels
538
573
539
574
Returns
540
575
-------
@@ -576,7 +611,6 @@ def az_carrier_components(self, offset, position):
576
611
self .starting_range )) - (f_etac / ka )
577
612
kt = ks / (1.0 - ks / ka )
578
613
579
-
580
614
return AzimuthCarrierComponents (kt , eta , eta_ref )
581
615
582
616
0 commit comments