Skip to content

geo_grid

Collection of function for determining and setting the geogrid

assign_check_epsg(epsg, epsg_default)

Assign and check user-defined epsg

Parameters:

Name Type Description Default
epsg

User-defined EPSG code to check

required
epsg_default

Default epsg code to assign

required

Returns:

Name Type Description
epsg int

Checked EPSG code to use in geogrid

Source code in src/compass/utils/geo_grid.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def assign_check_epsg(epsg, epsg_default):
    '''
    Assign and check user-defined epsg

    Parameters
    ----------
    epsg: int
        User-defined EPSG code to check
    epsg_default: int
        Default epsg code to assign

    Returns
    -------
    epsg: int
        Checked EPSG code to use in geogrid
    '''
    if epsg is None: epsg = epsg_default
    assert 1024 <= epsg <= 32767
    return epsg

assign_check_geogrid(geo_grid, x_start=None, y_start=None, x_end=None, y_end=None)

Initialize geogrid with user defined parameters. Check the validity of user-defined parameters

Parameters:

Name Type Description Default
geo_grid

ISCE3 object defining the geogrid

required
x_start

Geogrid top-left X coordinate

None
y_start

Geogrid top-left Y coordinate

None
x_end

Geogrid bottom-right X coordinate

None
y_end

Geogrid bottom-right Y coordinate

None

Returns:

Name Type Description
geo_grid geogrid

ISCE3 geogrid initialized with user-defined inputs

Source code in src/compass/utils/geo_grid.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
def assign_check_geogrid(geo_grid, x_start=None, y_start=None,
                         x_end=None, y_end=None):
    '''
    Initialize geogrid with user defined parameters.
    Check the validity of user-defined parameters

    Parameters
    ----------
    geo_grid: isce3.product.geogrid
        ISCE3 object defining the geogrid
    x_start: float
        Geogrid top-left X coordinate
    y_start: float
        Geogrid top-left Y coordinate
    x_end: float
        Geogrid bottom-right X coordinate
    y_end: float
        Geogrid bottom-right Y coordinate

    Returns
    -------
    geo_grid: isce3.product.geogrid
        ISCE3 geogrid initialized with user-defined inputs
    '''

    # Check assigned input coordinates and initialize geogrid accordingly
    if None in [x_start, y_start, x_end, y_end]:
        if x_start is not None:
            new_end_x = geo_grid.start_x + geo_grid.spacing_x * geo_grid.width
            geo_grid.start_x = x_start
            geo_grid.width = int(np.ceil((new_end_x - x_start) /
                                         geo_grid.spacing_x))
        # Restore geogrid end point if provided by the user
        if x_end is not None:
            geo_grid.width = int(np.ceil((x_end - geo_grid.start_x) /
                                         geo_grid.spacing_x))
        if y_start is not None:
            new_end_y = geo_grid.start_y + geo_grid.spacing_y * geo_grid.length
            geo_grid.start_y = y_start
            geo_grid.length = int(np.ceil((new_end_y - y_start) /
                                          geo_grid.spacing_y))
        if y_end is not None:
            geo_grid.length = int(np.ceil((y_end - geo_grid.start_y) /
                                          geo_grid.spacing_y))
    else:
        # If all the start/end coordinates have been assigned,
        # initialize the geogrid with them
        width = _grid_size(x_end, x_start, geo_grid.spacing_x)
        length = _grid_size(y_end, y_start, geo_grid.spacing_y)
        geo_grid = isce3.product.GeoGridParameters(x_start, y_start,
                                                   geo_grid.spacing_x,
                                                   geo_grid.spacing_y,
                                                   width, length,
                                                   geo_grid.epsg)
    return geo_grid

assign_check_spacing(x_spacing, y_spacing, x_default_spacing, y_default_spacing)

Check validity of input spacings and assign default spacings if one or both input spacings are None

Parameters:

Name Type Description Default
x_spacing

Input spacing of the geogrid along X-direction

required
y_spacing

Input spacing of the geogrid along Y-direction

required
x_default_spacing

Default spacing of the geogrid along X-direction

required
y_default_spacing

Default spacing of the geogrid along Y-direction

required

Returns:

Name Type Description
x_spacing float

Verified geogrid spacing along X-direction

y_spacing float

Verified geogrid spacing along Y-direction

Source code in src/compass/utils/geo_grid.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
def assign_check_spacing(x_spacing, y_spacing,
                         x_default_spacing, y_default_spacing):
    '''
    Check validity of input spacings and assign default spacings
    if one or both input spacings are None

    Parameters
    ----------
    x_spacing: float
        Input spacing of the geogrid along X-direction
    y_spacing: float
        Input spacing of the geogrid along Y-direction
    x_default_spacing: float
        Default spacing of the geogrid along X-direction
    y_default_spacing: float
        Default spacing of the geogrid along Y-direction

    Returns
    -------
    x_spacing: float
        Verified geogrid spacing along X-direction
    y_spacing: float
        Verified geogrid spacing along Y-direction
    '''
    error_channel = journal.error('geogrid.assign_check_spacing')

    # Check tha x-y_spacings are valid (positive)
    if y_spacing is not None:
        assert y_spacing > 0.0
        y_spacing = -1.0 * y_spacing
    else:
        assert y_default_spacing > 0.0
        y_spacing = -1.0 * y_default_spacing
    if x_spacing is not None:
        assert x_spacing > 0.0
    else:
        assert x_default_spacing > 0.0
        x_spacing = x_default_spacing

    # Check that x-y_spacings have been correctly assigned
    # (check on default spacings)
    if x_spacing <= 0:
        err_str = f'Pixel spacing in X/longitude direction needs to be >=0 (x_spacing: {x_spacing})'
        error_channel.log(err_str)
        raise ValueError(err_str)
    if y_spacing >= 0:
        err_str = f'Pixel spacing in Y/latitude direction needs to be <=0 (y_spacing: {y_spacing})'
        error_channel.log(err_str)
        raise ValueError(err_str)
    return x_spacing, y_spacing

check_geogrid_endpoints(geo_grid, x_end=None, y_end=None)

Check validity of geogrid end points

Parameters:

Name Type Description Default
geo_grid

ISCE3 object defining the geogrid

required
x_end

Geogrid bottom right X coordinate

None
y_end

Geogrid bottom right Y coordinates

None

Returns:

Name Type Description
x_end float

Verified geogrid bottom-right X coordinate

y_end float

Verified geogrid bottom-right Y coordinate

Source code in src/compass/utils/geo_grid.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
def check_geogrid_endpoints(geo_grid, x_end=None, y_end=None):
    '''
    Check validity of geogrid end points

    Parameters
    -----------
    geo_grid: isce3.product.geogrid
        ISCE3 object defining the geogrid
    x_end: float
        Geogrid bottom right X coordinate
    y_end: float
        Geogrid bottom right Y coordinates

    Returns
    -------
    x_end: float
        Verified geogrid bottom-right X coordinate
    y_end: float
        Verified geogrid bottom-right Y coordinate
    '''
    end_pt = lambda start, sz, spacing: start + spacing * sz

    if x_end is None:
        x_end = end_pt(geo_grid.start_x, geo_grid.spacing_x, geo_grid.width)
    if y_end is None:
        y_end = end_pt(geo_grid.start_y, geo_grid.spacing_y, geo_grid.length)
    return x_end, y_end

check_snap_values(x_snap, y_snap, x_spacing, y_spacing)

Check validity of snap values

Parameters:

Name Type Description Default
x_snap

Snap value along X-direction

required
y_snap

Snap value along Y-direction

required
x_spacing

Spacing of the geogrid along X-direction

required
y_spacing

Spacing of the geogrid along Y-direction

required
Source code in src/compass/utils/geo_grid.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
def check_snap_values(x_snap, y_snap, x_spacing, y_spacing):
    '''
    Check validity of snap values

    Parameters
    ----------
    x_snap: float
        Snap value along X-direction
    y_snap: float
        Snap value along Y-direction
    x_spacing: float
        Spacing of the geogrid along X-direction
    y_spacing: float
        Spacing of the geogrid along Y-direction
    '''
    error_channel = journal.error('geogrid.check_snap_values')

    # Check that snap values in X/Y-directions are positive
    if x_snap is not None and x_snap <= 0:
        err_str = f'Snap value in X direction must be > 0 (x_snap: {x_snap})'
        error_channel.log(err_str)
        raise ValueError(err_str)
    if y_snap is not None and y_snap <= 0:
        err_str = f'Snap value in Y direction must be > 0 (y_snap: {y_snap})'
        error_channel.log(err_str)
        raise ValueError(err_str)

    # Check that snap values in X/Y are integer multiples of the geogrid
    # spacings in X/Y directions
    if x_snap is not None and x_snap % x_spacing != 0.0:
        err_str = 'x_snap must be exact multiple of spacing in X direction (x_snap % x_spacing !=0)'
        error_channel.log(err_str)
        raise ValueError(err_str)
    if y_snap is not None and y_snap % y_spacing != 0.0:
        err_str = 'y_snap must be exact multiple of spacing in Y direction (y_snap % y_spacing !=0)'
        error_channel.log(err_str)
        raise ValueError(err_str)

generate_geogrids(bursts, geo_dict, dem)

Create a geogrid for all bursts in given list

Parameters:

Name Type Description Default
burst

List of bursts

required
geo_dict

Dict of parameters that describe the area to be geocoded

required
dem

Path to DEM raster

required

Returns:

Name Type Description
geo_grids dict

Dict of burst ID keys to isce3.product.GeoGridParameters values

Source code in src/compass/utils/geo_grid.py
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
def generate_geogrids(bursts, geo_dict, dem):
    ''' Create a geogrid for all bursts in given list

    Parameters
    ----------
    burst: list[Sentinel1BurstSlc]
        List of bursts
    geo_dict: dict
        Dict of parameters that describe the area to be geocoded
    dem: str
        Path to DEM raster

    Returns
    -------
    geo_grids: dict
        Dict of burst ID keys to isce3.product.GeoGridParameters values
    '''
    dem_raster = isce3.io.Raster(dem)

    # Unpack values from geocoding dictionary
    x_spacing_dict = geo_dict['x_posting']
    y_spacing_dict = geo_dict['y_posting']
    x_snap_dict = geo_dict['x_snap']
    y_snap_dict = geo_dict['y_snap']

    geo_grids = {}
    for burst in bursts:
        burst_id = str(burst.burst_id)

        if burst_id in geo_grids:
            continue

        # Compute Burst epsg if not assigned in runconfig
        epsg = get_point_epsg(burst.center.y, burst.center.x)

        radar_grid = burst.as_isce3_radargrid()
        orbit = burst.orbit

        # Check spacing in X/Y direction
        if epsg == dem_raster.get_epsg():
            x_spacing, y_spacing = assign_check_spacing(x_spacing_dict,
                                                        y_spacing_dict,
                                                        4.5e-5, 9.0e-5)
        else:
            # Assign spacing in meters
            x_spacing, y_spacing = assign_check_spacing(x_spacing_dict,
                                                        y_spacing_dict,
                                                        5.0, 10.0)

        # Initialize geogrid with the info checked at this stage
        geo_grid = isce3.product.bbox_to_geogrid(radar_grid, orbit,
                                                 isce3.core.LUT2d(),
                                                 x_spacing, y_spacing, epsg)

        # Check end point of geogrid before compute snaps
        x_end, y_end = check_geogrid_endpoints(geo_grid)
        # Check snap values
        check_snap_values(x_snap_dict, y_snap_dict, x_spacing, y_spacing)
        # Snap coordinates
        geo_grid = snap_geogrid(geo_grid, x_snap_dict, y_snap_dict, x_end, y_end)

        geo_grids[burst_id] = geo_grid

    return geo_grids

generate_geogrids_from_db(bursts, geo_dict, dem, burst_db_file)

Create a geogrid for all bursts in given list from provided burst database

Parameters:

Name Type Description Default
burst

List of bursts

required
geo_dict

Dict of parameters that describe the area to be geocoded

required
dem

Path to DEM raster

required
burst_db_file str

Location of burst database sqlite file

required

Returns:

Name Type Description
geo_grids dict

Dict of burst ID keys to isce3.product.GeoGridParameters values

Source code in src/compass/utils/geo_grid.py
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
def generate_geogrids_from_db(bursts, geo_dict, dem, burst_db_file):
    ''' Create a geogrid for all bursts in given list from provided burst
    database

    Parameters
    ----------
    burst: list[Sentinel1BurstSlc]
        List of bursts
    geo_dict: dict
        Dict of parameters that describe the area to be geocoded
    dem: str
        Path to DEM raster
    burst_db_file : str
        Location of burst database sqlite file

    Returns
    -------
    geo_grids: dict
        Dict of burst ID keys to isce3.product.GeoGridParameters values
    '''
    dem_raster = isce3.io.Raster(dem)

    # Unpack values from geocoding dictionary
    x_spacing_dict = geo_dict['x_posting']
    y_spacing_dict = geo_dict['y_posting']
    x_snap_dict = geo_dict['x_snap']
    y_snap_dict = geo_dict['y_snap']

    geo_grids = {}

    # get all burst IDs and their EPSGs + bounding boxes
    burst_ids = [str(b.burst_id) for b in bursts]
    epsg_bbox_dict = helpers.burst_bboxes_from_db(burst_ids, burst_db_file)

    for burst in bursts:
        burst_id = str(burst.burst_id)

        # check geogrid already created for burst ID
        if burst_id in geo_grids:
            continue

        # extract EPSG and bbox for current burst from dict
        # bottom right = (xmax, ymin) and top left = (xmin, ymax)
        epsg, (xmin, ymin, xmax, ymax) = epsg_bbox_dict[burst_id]

        radar_grid = burst.as_isce3_radargrid()
        orbit = burst.orbit

        # Check spacing in X/Y direction
        if epsg == dem_raster.get_epsg():
            x_spacing, y_spacing = assign_check_spacing(x_spacing_dict,
                                                        y_spacing_dict,
                                                        4.5e-5, 9.0e-5)
        else:
            # Assign spacing in meters
            x_spacing, y_spacing = assign_check_spacing(x_spacing_dict,
                                                        y_spacing_dict,
                                                        5.0, 10.0)

        # Initialize geogrid with the info checked at this stage
        geo_grid_in = isce3.product.bbox_to_geogrid(radar_grid, orbit,
                                                    isce3.core.LUT2d(),
                                                    x_spacing, y_spacing, epsg)
        # Check and further initialize geo_grid
        geo_grid = assign_check_geogrid(geo_grid_in, xmin, ymax, xmax, ymin)

        # Check end point of geogrid before compute snaps
        x_end, y_end = check_geogrid_endpoints(geo_grid, xmax, ymin)
        # Check snap values
        check_snap_values(x_snap_dict, y_snap_dict, x_spacing, y_spacing)
        # Snap coordinates
        geo_grid = snap_geogrid(geo_grid, x_snap_dict, y_snap_dict, x_end, y_end)

        geo_grids[burst_id] = geo_grid

    return geo_grids

get_point_epsg(lat, lon)

Get EPSG code based on latitude and longitude coordinates of a point

Parameters:

Name Type Description Default
lat

Latitude coordinate of the point

required
lon

Longitude coordinate of the point

required

Returns:

Name Type Description
epsg int

UTM zone

Source code in src/compass/utils/geo_grid.py
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
def get_point_epsg(lat, lon):
    '''
    Get EPSG code based on latitude and longitude
    coordinates of a point

    Parameters
    ----------
    lat: float
        Latitude coordinate of the point
    lon: float
        Longitude coordinate of the point

    Returns
    -------
    epsg: int
        UTM zone
    '''
    error_channel = journal.error('geogrid.get_point_epsg')

    if lon >= 180.0:
        lon = lon - 360.0

    if lat >= 60.0:
        return 3413
    elif lat <= -60.0:
        return 3031
    elif lat > 0:
        return 32601 + int(np.round((lon + 177) / 6.0))
    elif lat < 0:
        return 32701 + int(np.round((lon + 177) / 6.0))
    else:
        err_str = "'Could not determine EPSG for {0}, {1}'.format(lon, lat))"
        error_channel.log(err_str)
        raise ValueError(err_str)

snap_geogrid(geo_grid, x_snap, y_snap, x_end, y_end)

Snap geogrid based on user-defined snapping values

Parameters:

Name Type Description Default
geo_grid

ISCE3 object defining the geogrid

required
x_snap

Snap value along X-direction

required
y_snap

Snap value along Y-direction

required
x_end

Bottom-right X coordinate

required
y_end

Bottom-right Y coordinate

required

Returns:

Name Type Description
geo_grid geogrid

ISCE3 object containing the snapped geogrid

Source code in src/compass/utils/geo_grid.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
def snap_geogrid(geo_grid, x_snap, y_snap, x_end, y_end):
    '''
    Snap geogrid based on user-defined snapping values

    Parameters
    ----------
    geo_grid: isce3.product.geogrid
        ISCE3 object defining the geogrid
    x_snap: float
        Snap value along X-direction
    y_snap: float
        Snap value along Y-direction
    x_end: float
        Bottom-right X coordinate
    y_end: float
        Bottom-right Y coordinate

    Returns
    -------
    geo_grid: isce3.product.geogrid
        ISCE3 object containing the snapped geogrid
    '''
    if x_end is None: x_end = geo_grid.end_x
    if y_end is None: y_end = geo_grid.end_y

    if x_snap is not None or y_snap is not None:
        snap_coord = lambda val, snap, round_func: round_func(
            float(val) / snap) * snap
        geo_grid.start_x = snap_coord(geo_grid.start_x, x_snap, np.floor)
        geo_grid.start_y = snap_coord(geo_grid.start_y, y_snap, np.ceil)
        end_x = snap_coord(x_end, x_snap, np.ceil)
        end_y = snap_coord(y_end, y_snap, np.floor)
        geo_grid.length = _grid_size(end_y, geo_grid.start_y,
                                     geo_grid.spacing_y)
        geo_grid.width = _grid_size(end_x, geo_grid.start_x, geo_grid.spacing_x)
    return geo_grid