sarkit-convert 0.2.0__py3-none-any.whl → 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sarkit_convert/_utils.py +15 -18
- sarkit_convert/_version.py +1 -1
- sarkit_convert/cosmo.py +172 -178
- sarkit_convert/create_arp_poly.py +1 -1
- sarkit_convert/iceye.py +196 -291
- sarkit_convert/sentinel.py +284 -326
- sarkit_convert/terrasar.py +179 -179
- {sarkit_convert-0.2.0.dist-info → sarkit_convert-0.3.1.dist-info}/METADATA +23 -13
- sarkit_convert-0.3.1.dist-info/RECORD +14 -0
- {sarkit_convert-0.2.0.dist-info → sarkit_convert-0.3.1.dist-info}/WHEEL +1 -1
- sarkit_convert-0.2.0.dist-info/RECORD +0 -14
- {sarkit_convert-0.2.0.dist-info → sarkit_convert-0.3.1.dist-info}/entry_points.txt +0 -0
- {sarkit_convert-0.2.0.dist-info → sarkit_convert-0.3.1.dist-info}/licenses/LICENSE +0 -0
sarkit_convert/sentinel.py
CHANGED
|
@@ -8,12 +8,13 @@ Convert a complex image(s) from the Sentinel SAFE to SICD(s).
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
import argparse
|
|
11
|
+
import contextlib
|
|
11
12
|
import datetime
|
|
13
|
+
import functools
|
|
12
14
|
import pathlib
|
|
13
15
|
|
|
14
16
|
import dateutil.parser
|
|
15
|
-
import lxml.
|
|
16
|
-
import lxml.etree as et
|
|
17
|
+
import lxml.etree
|
|
17
18
|
import numpy as np
|
|
18
19
|
import numpy.linalg as npl
|
|
19
20
|
import numpy.polynomial.polynomial as npp
|
|
@@ -176,7 +177,29 @@ def _collect_base_info(root_node):
|
|
|
176
177
|
return base_info
|
|
177
178
|
|
|
178
179
|
|
|
179
|
-
|
|
180
|
+
@functools.lru_cache
|
|
181
|
+
def _window_params(window_name, coefficient):
|
|
182
|
+
window_name = window_name.upper()
|
|
183
|
+
if window_name == "HAMMING":
|
|
184
|
+
wgts = scipy.signal.windows.general_hamming(512, float(coefficient), sym=True)
|
|
185
|
+
elif window_name == "KAISER":
|
|
186
|
+
wgts = scipy.signal.windows.kaiser(512, float(coefficient), sym=True)
|
|
187
|
+
else: # Default to UNIFORM
|
|
188
|
+
window_name = "UNIFORM"
|
|
189
|
+
coefficient = None
|
|
190
|
+
wgts = np.ones(256)
|
|
191
|
+
|
|
192
|
+
broadening_factor = utils.broadening_from_amp(wgts)
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
"window_name": window_name,
|
|
196
|
+
"coefficient": coefficient,
|
|
197
|
+
"wgts": wgts,
|
|
198
|
+
"broadening_factor": broadening_factor,
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def _collect_swath_info(product_root_node):
|
|
180
203
|
swath_info = dict()
|
|
181
204
|
burst_list = product_root_node.findall("./swathTiming/burstList/burst")
|
|
182
205
|
|
|
@@ -334,20 +357,15 @@ def _collect_swath_info(product_root_node, base_info):
|
|
|
334
357
|
range_proc = product_root_node.find(
|
|
335
358
|
"./imageAnnotation/processingInformation/swathProcParamsList/swathProcParams/rangeProcessing"
|
|
336
359
|
)
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
)
|
|
347
|
-
else: # Default to UNIFORM
|
|
348
|
-
swath_info["row_window_name"] = "UNIFORM"
|
|
349
|
-
swath_info["row_params"] = None
|
|
350
|
-
swath_info["row_wgts"] = np.ones(256)
|
|
360
|
+
|
|
361
|
+
window_info = _window_params(
|
|
362
|
+
range_proc.find("./windowType").text,
|
|
363
|
+
range_proc.find("./windowCoefficient").text,
|
|
364
|
+
)
|
|
365
|
+
swath_info["row_window_name"] = window_info["window_name"]
|
|
366
|
+
swath_info["row_params"] = window_info["coefficient"]
|
|
367
|
+
swath_info["row_wgts"] = window_info["wgts"]
|
|
368
|
+
swath_info["row_broadening_factor"] = window_info["broadening_factor"]
|
|
351
369
|
|
|
352
370
|
swath_info["row_ss"] = (_constants.speed_of_light / 2) * delta_tau_s
|
|
353
371
|
swath_info["row_sgn"] = -1
|
|
@@ -374,29 +392,24 @@ def _collect_swath_info(product_root_node, base_info):
|
|
|
374
392
|
).text
|
|
375
393
|
)
|
|
376
394
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
swath_info["col_wgts"] = scipy.signal.windows.kaiser(
|
|
385
|
-
512, float(swath_info["col_params"]), sym=True
|
|
386
|
-
)
|
|
387
|
-
else: # Default to UNIFORM
|
|
388
|
-
swath_info["col_window_name"] = "UNIFORM"
|
|
389
|
-
swath_info["col_params"] = None
|
|
390
|
-
swath_info["col_wgts"] = np.ones(256)
|
|
395
|
+
window_info = _window_params(
|
|
396
|
+
az_proc.find("./windowType").text, az_proc.find("./windowCoefficient").text
|
|
397
|
+
)
|
|
398
|
+
swath_info["col_window_name"] = window_info["window_name"]
|
|
399
|
+
swath_info["col_params"] = window_info["coefficient"]
|
|
400
|
+
swath_info["col_wgts"] = window_info["wgts"]
|
|
401
|
+
swath_info["col_broadening_factor"] = window_info["broadening_factor"]
|
|
391
402
|
|
|
392
403
|
swath_info["col_sgn"] = -1
|
|
393
404
|
swath_info["col_kctr"] = 0.0
|
|
394
405
|
swath_info["col_imp_res_bw"] = dop_bw * swath_info["ss_zd_s"] / swath_info["col_ss"]
|
|
395
406
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
swath_info["col_imp_res_wid"] =
|
|
407
|
+
swath_info["row_imp_res_wid"] = (
|
|
408
|
+
swath_info["row_broadening_factor"] / swath_info["row_imp_res_bw"]
|
|
409
|
+
)
|
|
410
|
+
swath_info["col_imp_res_wid"] = (
|
|
411
|
+
swath_info["col_broadening_factor"] / swath_info["col_imp_res_bw"]
|
|
412
|
+
)
|
|
400
413
|
|
|
401
414
|
return swath_info
|
|
402
415
|
|
|
@@ -907,7 +920,7 @@ def _collect_burst_info(product_root_node, base_info, swath_info):
|
|
|
907
920
|
|
|
908
921
|
def _calc_radiometric_info(cal_file_name, swath_info, burst_info_list):
|
|
909
922
|
"""Compute radiometric polys"""
|
|
910
|
-
cal_root_node =
|
|
923
|
+
cal_root_node = lxml.etree.parse(cal_file_name).getroot()
|
|
911
924
|
cal_vector_list = cal_root_node.findall(
|
|
912
925
|
"./{*}calibrationVectorList/{*}calibrationVector"
|
|
913
926
|
)
|
|
@@ -1023,7 +1036,7 @@ def _calc_radiometric_info(cal_file_name, swath_info, burst_info_list):
|
|
|
1023
1036
|
|
|
1024
1037
|
def _calc_noise_level_info(noise_file_name, swath_info, burst_info_list):
|
|
1025
1038
|
"""Compute noise poly"""
|
|
1026
|
-
noise_root_node =
|
|
1039
|
+
noise_root_node = lxml.etree.parse(noise_file_name).getroot()
|
|
1027
1040
|
mode_id = swath_info["mode_id"]
|
|
1028
1041
|
lines_per_burst = swath_info["num_cols"]
|
|
1029
1042
|
range_size_pixels = swath_info["num_rows"]
|
|
@@ -1169,232 +1182,165 @@ def _complete_filename(swath_info, burst_info, filename_template):
|
|
|
1169
1182
|
|
|
1170
1183
|
|
|
1171
1184
|
def _create_sicd_xml(base_info, swath_info, burst_info, classification):
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1185
|
+
sicd_xml_obj = lxml.etree.Element(
|
|
1186
|
+
f"{{{NSMAP['sicd']}}}SICD", nsmap={None: NSMAP["sicd"]}
|
|
1187
|
+
)
|
|
1175
1188
|
sicd_ew = sksicd.ElementWrapper(sicd_xml_obj)
|
|
1176
1189
|
|
|
1177
1190
|
# Collection Info
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
)
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
{"name": "ORBIT_SOURCE"}, swath_info["parameters"]["ORBIT_SOURCE"]
|
|
1192
|
-
),
|
|
1193
|
-
*(
|
|
1194
|
-
[
|
|
1195
|
-
em.Parameter(
|
|
1196
|
-
{"name": "BURST_ID"}, str(burst_info["parameters"]["BURST_ID"])
|
|
1197
|
-
)
|
|
1198
|
-
]
|
|
1199
|
-
if burst_info["parameters"].get("BURST_ID") is not None
|
|
1200
|
-
else []
|
|
1201
|
-
),
|
|
1202
|
-
em.Parameter(
|
|
1203
|
-
{"name": "MISSION_DATA_TAKE_ID"},
|
|
1204
|
-
swath_info["parameters"]["MISSION_DATA_TAKE_ID"],
|
|
1205
|
-
),
|
|
1206
|
-
em.Parameter(
|
|
1207
|
-
{"name": "RELATIVE_ORBIT_NUM"},
|
|
1208
|
-
str(base_info["parameters"]["RELATIVE_ORBIT_NUM"]),
|
|
1209
|
-
),
|
|
1210
|
-
)
|
|
1211
|
-
|
|
1212
|
-
# Image Creation
|
|
1213
|
-
sicd_ew["ImageCreation"] = em.ImageCreation(
|
|
1214
|
-
em.Application(base_info["creation_application"]),
|
|
1215
|
-
em.DateTime(base_info["creation_date_time"].strftime("%Y-%m-%dT%H:%M:%SZ")),
|
|
1216
|
-
)
|
|
1217
|
-
|
|
1218
|
-
# Image Data
|
|
1219
|
-
sicd_ew["ImageData"] = em.ImageData(
|
|
1220
|
-
em.PixelType(swath_info["pixel_type"]),
|
|
1221
|
-
em.NumRows(str(swath_info["num_rows"])),
|
|
1222
|
-
em.NumCols(str(swath_info["num_cols"])),
|
|
1223
|
-
em.FirstRow(str(swath_info["first_row"])),
|
|
1224
|
-
em.FirstCol(str(swath_info["first_col"])),
|
|
1225
|
-
em.FullImage(
|
|
1226
|
-
em.NumRows(str(swath_info["num_rows"])),
|
|
1227
|
-
em.NumCols(str(swath_info["num_cols"])),
|
|
1228
|
-
),
|
|
1229
|
-
em.SCPPixel(
|
|
1230
|
-
em.Row(str(swath_info["scp_pixel"][0])),
|
|
1231
|
-
em.Col(str(swath_info["scp_pixel"][1])),
|
|
1232
|
-
),
|
|
1233
|
-
em.ValidData(
|
|
1234
|
-
{"size": "4"},
|
|
1235
|
-
em.Vertex(
|
|
1236
|
-
{"index": "1"},
|
|
1237
|
-
em.Row(str(burst_info["valid_data"][0][0])),
|
|
1238
|
-
em.Col(str(burst_info["valid_data"][0][1])),
|
|
1239
|
-
),
|
|
1240
|
-
em.Vertex(
|
|
1241
|
-
{"index": "2"},
|
|
1242
|
-
em.Row(str(burst_info["valid_data"][1][0])),
|
|
1243
|
-
em.Col(str(burst_info["valid_data"][1][1])),
|
|
1244
|
-
),
|
|
1245
|
-
em.Vertex(
|
|
1246
|
-
{"index": "3"},
|
|
1247
|
-
em.Row(str(burst_info["valid_data"][2][0])),
|
|
1248
|
-
em.Col(str(burst_info["valid_data"][2][1])),
|
|
1249
|
-
),
|
|
1250
|
-
em.Vertex(
|
|
1251
|
-
{"index": "4"},
|
|
1252
|
-
em.Row(str(burst_info["valid_data"][3][0])),
|
|
1253
|
-
em.Col(str(burst_info["valid_data"][3][1])),
|
|
1254
|
-
),
|
|
1255
|
-
),
|
|
1191
|
+
parameter = [
|
|
1192
|
+
("SLICE", swath_info["parameters"]["SLICE"]),
|
|
1193
|
+
("BURST", burst_info["parameters"]["BURST"]),
|
|
1194
|
+
("SWATH", swath_info["parameters"]["SWATH"]),
|
|
1195
|
+
("ORBIT_SOURCE", swath_info["parameters"]["ORBIT_SOURCE"]),
|
|
1196
|
+
]
|
|
1197
|
+
if burst_info["parameters"].get("BURST_ID") is not None:
|
|
1198
|
+
parameter.append(("BURST_ID", str(burst_info["parameters"]["BURST_ID"])))
|
|
1199
|
+
parameter.extend(
|
|
1200
|
+
[
|
|
1201
|
+
("MISSION_DATA_TAKE_ID", swath_info["parameters"]["MISSION_DATA_TAKE_ID"]),
|
|
1202
|
+
("RELATIVE_ORBIT_NUM", str(base_info["parameters"]["RELATIVE_ORBIT_NUM"])),
|
|
1203
|
+
]
|
|
1256
1204
|
)
|
|
1205
|
+
sicd_ew["CollectionInfo"] = {
|
|
1206
|
+
"CollectorName": swath_info["collector_name"],
|
|
1207
|
+
"CoreName": burst_info["core_name"],
|
|
1208
|
+
"CollectType": base_info["collect_type"],
|
|
1209
|
+
"RadarMode": {
|
|
1210
|
+
"ModeType": base_info["mode_type"],
|
|
1211
|
+
"ModeID": swath_info["mode_id"],
|
|
1212
|
+
},
|
|
1213
|
+
"Classification": classification,
|
|
1214
|
+
"Parameter": parameter,
|
|
1215
|
+
}
|
|
1216
|
+
sicd_ew["ImageCreation"] = {
|
|
1217
|
+
"Application": base_info["creation_application"],
|
|
1218
|
+
"DateTime": base_info["creation_date_time"],
|
|
1219
|
+
}
|
|
1220
|
+
sicd_ew["ImageData"] = {
|
|
1221
|
+
"PixelType": swath_info["pixel_type"],
|
|
1222
|
+
"NumRows": swath_info["num_rows"],
|
|
1223
|
+
"NumCols": swath_info["num_cols"],
|
|
1224
|
+
"FirstRow": swath_info["first_row"],
|
|
1225
|
+
"FirstCol": swath_info["first_col"],
|
|
1226
|
+
"FullImage": {
|
|
1227
|
+
"NumRows": swath_info["num_rows"],
|
|
1228
|
+
"NumCols": swath_info["num_cols"],
|
|
1229
|
+
},
|
|
1230
|
+
"SCPPixel": swath_info["scp_pixel"],
|
|
1231
|
+
"ValidData": burst_info["valid_data"],
|
|
1232
|
+
}
|
|
1257
1233
|
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
sicd_ew["GeoData"] = em.GeoData(
|
|
1266
|
-
em.EarthModel("WGS_84"),
|
|
1267
|
-
em.SCP(
|
|
1268
|
-
em.ECF(*_make_xyz(burst_info["scp_ecf"])),
|
|
1269
|
-
em.LLH(*__make_llh(burst_info["scp_llh"])),
|
|
1270
|
-
),
|
|
1271
|
-
em.ImageCorners(),
|
|
1272
|
-
em.ValidData(),
|
|
1273
|
-
)
|
|
1234
|
+
sicd_ew["GeoData"] = {
|
|
1235
|
+
"EarthModel": "WGS_84",
|
|
1236
|
+
"SCP": {
|
|
1237
|
+
"ECF": burst_info["scp_ecf"],
|
|
1238
|
+
"LLH": burst_info["scp_llh"],
|
|
1239
|
+
},
|
|
1240
|
+
}
|
|
1274
1241
|
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
str(swath_info["col_window_name"]),
|
|
1319
|
-
),
|
|
1320
|
-
*(
|
|
1321
|
-
[
|
|
1322
|
-
em.Parameter(
|
|
1323
|
-
{"name": "COEFFICIENT"},
|
|
1324
|
-
str(swath_info["col_params"]),
|
|
1325
|
-
)
|
|
1326
|
-
]
|
|
1327
|
-
if swath_info["col_params"] is not None
|
|
1328
|
-
else []
|
|
1329
|
-
),
|
|
1330
|
-
),
|
|
1331
|
-
),
|
|
1332
|
-
)
|
|
1333
|
-
sicd_ew["Grid"]["TimeCOAPoly"] = burst_info["time_coa_poly_coefs"]
|
|
1334
|
-
sicd_ew["Grid"]["Row"]["DeltaKCOAPoly"] = swath_info["row_deltak_coa_poly"]
|
|
1335
|
-
sicd_ew["Grid"]["Col"]["DeltaKCOAPoly"] = burst_info["col_deltak_coa_poly"]
|
|
1336
|
-
sicd_ew["Grid"]["Row"]["WgtFunct"] = swath_info["row_wgts"]
|
|
1337
|
-
sicd_ew["Grid"]["Col"]["WgtFunct"] = swath_info["col_wgts"]
|
|
1242
|
+
sicd_ew["Grid"] = {
|
|
1243
|
+
"ImagePlane": swath_info["image_plane"],
|
|
1244
|
+
"Type": swath_info["grid_type"],
|
|
1245
|
+
"TimeCOAPoly": burst_info["time_coa_poly_coefs"],
|
|
1246
|
+
"Row": {
|
|
1247
|
+
"UVectECF": burst_info["row_uvect_ecf"],
|
|
1248
|
+
"SS": swath_info["row_ss"],
|
|
1249
|
+
"ImpRespWid": swath_info["row_imp_res_wid"],
|
|
1250
|
+
"Sgn": swath_info["row_sgn"],
|
|
1251
|
+
"ImpRespBW": swath_info["row_imp_res_bw"],
|
|
1252
|
+
"KCtr": swath_info["row_kctr"],
|
|
1253
|
+
"DeltaK1": burst_info["row_delta_k1"],
|
|
1254
|
+
"DeltaK2": burst_info["row_delta_k2"],
|
|
1255
|
+
"DeltaKCOAPoly": swath_info["row_deltak_coa_poly"],
|
|
1256
|
+
"WgtType": {
|
|
1257
|
+
"WindowName": swath_info["row_window_name"],
|
|
1258
|
+
},
|
|
1259
|
+
"WgtFunct": swath_info["row_wgts"],
|
|
1260
|
+
},
|
|
1261
|
+
"Col": {
|
|
1262
|
+
"UVectECF": burst_info["col_uvect_ecf"],
|
|
1263
|
+
"SS": swath_info["col_ss"],
|
|
1264
|
+
"ImpRespWid": swath_info["col_imp_res_wid"],
|
|
1265
|
+
"Sgn": swath_info["col_sgn"],
|
|
1266
|
+
"ImpRespBW": swath_info["col_imp_res_bw"],
|
|
1267
|
+
"KCtr": swath_info["col_kctr"],
|
|
1268
|
+
"DeltaK1": burst_info["col_delta_k1"],
|
|
1269
|
+
"DeltaK2": burst_info["col_delta_k2"],
|
|
1270
|
+
"DeltaKCOAPoly": burst_info["col_deltak_coa_poly"],
|
|
1271
|
+
"WgtType": {
|
|
1272
|
+
"WindowName": swath_info["col_window_name"],
|
|
1273
|
+
},
|
|
1274
|
+
"WgtFunct": swath_info["col_wgts"],
|
|
1275
|
+
},
|
|
1276
|
+
}
|
|
1277
|
+
if swath_info["row_params"] is not None:
|
|
1278
|
+
sicd_ew["Grid"]["Row"]["WgtType"]["Parameter"] = [
|
|
1279
|
+
("COEFFICIENT", str(swath_info["row_params"]))
|
|
1280
|
+
]
|
|
1281
|
+
if swath_info["col_params"] is not None:
|
|
1282
|
+
sicd_ew["Grid"]["Col"]["WgtType"]["Parameter"] = [
|
|
1283
|
+
("COEFFICIENT", str(swath_info["col_params"]))
|
|
1284
|
+
]
|
|
1338
1285
|
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1286
|
+
sicd_ew["Timeline"] = {
|
|
1287
|
+
"CollectStart": burst_info["collect_start"],
|
|
1288
|
+
"CollectDuration": burst_info["collect_duration"],
|
|
1289
|
+
"IPP": {
|
|
1290
|
+
"@size": 1,
|
|
1291
|
+
"Set": [
|
|
1292
|
+
{
|
|
1293
|
+
"@index": 1,
|
|
1294
|
+
"TStart": burst_info["ipp_set_tstart"],
|
|
1295
|
+
"TEnd": burst_info["ipp_set_tend"],
|
|
1296
|
+
"IPPStart": burst_info["ipp_set_ippstart"],
|
|
1297
|
+
"IPPEnd": burst_info["ipp_set_ippend"],
|
|
1298
|
+
"IPPPoly": swath_info["ipp_poly"],
|
|
1299
|
+
}
|
|
1300
|
+
],
|
|
1301
|
+
},
|
|
1302
|
+
}
|
|
1356
1303
|
|
|
1357
|
-
# Position
|
|
1358
1304
|
sicd_ew["Position"]["ARPPoly"] = burst_info["arp_poly_coefs"]
|
|
1359
1305
|
|
|
1360
1306
|
# Radar Collection
|
|
1361
|
-
sicd_ew["RadarCollection"] =
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1307
|
+
sicd_ew["RadarCollection"] = {
|
|
1308
|
+
"TxFrequency": {
|
|
1309
|
+
"Min": swath_info["tx_freq"][0],
|
|
1310
|
+
"Max": swath_info["tx_freq"][1],
|
|
1311
|
+
},
|
|
1312
|
+
"Waveform": {
|
|
1313
|
+
"@size": len(swath_info["rcv_window_length"]),
|
|
1314
|
+
"WFParameters": [
|
|
1315
|
+
{
|
|
1316
|
+
"@index": i,
|
|
1317
|
+
"TxPulseLength": swath_info["tx_pulse_length"],
|
|
1318
|
+
"TxRFBandwidth": swath_info["tx_rf_bw"],
|
|
1319
|
+
"TxFreqStart": swath_info["tx_freq_start"],
|
|
1320
|
+
"TxFMRate": swath_info["tx_fm_rate"],
|
|
1321
|
+
"RcvWindowLength": swl,
|
|
1322
|
+
"ADCSampleRate": swath_info["adc_sample_rate"],
|
|
1323
|
+
}
|
|
1378
1324
|
for i, swl in enumerate(swath_info["rcv_window_length"], start=1)
|
|
1379
1325
|
],
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1326
|
+
},
|
|
1327
|
+
"TxPolarization": swath_info["tx_polarization"],
|
|
1328
|
+
"RcvChannels": {
|
|
1329
|
+
"@size": len(base_info["tx_rcv_polarization"]),
|
|
1330
|
+
"ChanParameters": [
|
|
1331
|
+
{
|
|
1332
|
+
"@index": i,
|
|
1333
|
+
"TxRcvPolarization": entry,
|
|
1334
|
+
}
|
|
1389
1335
|
for i, entry in enumerate(base_info["tx_rcv_polarization"], start=1)
|
|
1390
1336
|
],
|
|
1391
|
-
|
|
1392
|
-
|
|
1337
|
+
},
|
|
1338
|
+
}
|
|
1393
1339
|
|
|
1394
|
-
|
|
1340
|
+
chan_index = None
|
|
1395
1341
|
for i, pol in enumerate(base_info["tx_rcv_polarization"], start=1):
|
|
1396
1342
|
if pol == swath_info["tx_rcv_polarization_proc"]:
|
|
1397
|
-
|
|
1343
|
+
chan_index = str(i)
|
|
1398
1344
|
|
|
1399
1345
|
# Image Formation
|
|
1400
1346
|
now = (
|
|
@@ -1402,48 +1348,44 @@ def _create_sicd_xml(base_info, swath_info, burst_info, classification):
|
|
|
1402
1348
|
.isoformat(timespec="microseconds")
|
|
1403
1349
|
.replace("+00:00", "Z")
|
|
1404
1350
|
)
|
|
1405
|
-
sicd_ew["ImageFormation"] =
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1351
|
+
sicd_ew["ImageFormation"] = {
|
|
1352
|
+
"RcvChanProc": {
|
|
1353
|
+
"NumChanProc": 1,
|
|
1354
|
+
"PRFScaleFactor": 1,
|
|
1355
|
+
"ChanIndex": [chan_index],
|
|
1356
|
+
},
|
|
1357
|
+
"TxRcvPolarizationProc": swath_info["tx_rcv_polarization_proc"],
|
|
1358
|
+
"TStartProc": burst_info["tstart_proc"],
|
|
1359
|
+
"TEndProc": burst_info["tend_proc"],
|
|
1360
|
+
"TxFrequencyProc": {
|
|
1361
|
+
"MinProc": swath_info["tx_freq_proc"][0],
|
|
1362
|
+
"MaxProc": swath_info["tx_freq_proc"][1],
|
|
1363
|
+
},
|
|
1364
|
+
"ImageFormAlgo": swath_info["image_form_algo"],
|
|
1365
|
+
"STBeamComp": swath_info["st_beam_comp"],
|
|
1366
|
+
"ImageBeamComp": swath_info["image_beam_comp"],
|
|
1367
|
+
"AzAutofocus": swath_info["az_autofocus"],
|
|
1368
|
+
"RgAutofocus": swath_info["rg_autofocus"],
|
|
1369
|
+
"Processing": [
|
|
1370
|
+
{
|
|
1371
|
+
"Type": f"sarkit-convert {__version__} @ {now}",
|
|
1372
|
+
"Applied": True,
|
|
1373
|
+
},
|
|
1374
|
+
],
|
|
1375
|
+
}
|
|
1428
1376
|
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
)
|
|
1442
|
-
sicd_ew["RMA"]["INCA"]["TimeCAPoly"] = burst_info["time_ca_poly_coefs"]
|
|
1443
|
-
sicd_ew["RMA"]["INCA"]["DRateSFPoly"] = burst_info["drsf_poly_coefs"]
|
|
1444
|
-
sicd_ew["RMA"]["INCA"]["DopCentroidPoly"] = burst_info[
|
|
1445
|
-
"doppler_centroid_poly_coefs"
|
|
1446
|
-
]
|
|
1377
|
+
sicd_ew["RMA"] = {
|
|
1378
|
+
"RMAlgoType": swath_info["rm_algo_type"],
|
|
1379
|
+
"ImageType": swath_info["image_type"],
|
|
1380
|
+
"INCA": {
|
|
1381
|
+
"TimeCAPoly": burst_info["time_ca_poly_coefs"],
|
|
1382
|
+
"R_CA_SCP": swath_info["r_ca_scp"],
|
|
1383
|
+
"FreqZero": swath_info["freq_zero"],
|
|
1384
|
+
"DRateSFPoly": burst_info["drsf_poly_coefs"],
|
|
1385
|
+
"DopCentroidPoly": burst_info["doppler_centroid_poly_coefs"],
|
|
1386
|
+
"DopCentroidCOA": swath_info["dop_centroid_coa"],
|
|
1387
|
+
},
|
|
1388
|
+
}
|
|
1447
1389
|
|
|
1448
1390
|
# Add Radiometric after Sentinel baseline processing calibration update on 25 Nov 2015.
|
|
1449
1391
|
if "radiometric" in burst_info:
|
|
@@ -1470,14 +1412,14 @@ def _create_sicd_xml(base_info, swath_info, burst_info, classification):
|
|
|
1470
1412
|
return sicd_xml_obj
|
|
1471
1413
|
|
|
1472
1414
|
|
|
1473
|
-
def _update_geo_data(
|
|
1415
|
+
def _update_geo_data(sicd_ew):
|
|
1474
1416
|
# Update ImageCorners
|
|
1475
|
-
num_rows =
|
|
1476
|
-
num_cols =
|
|
1477
|
-
row_ss =
|
|
1478
|
-
col_ss =
|
|
1479
|
-
scp_pixel =
|
|
1480
|
-
scp_ecf =
|
|
1417
|
+
num_rows = sicd_ew["ImageData"]["NumRows"]
|
|
1418
|
+
num_cols = sicd_ew["ImageData"]["NumCols"]
|
|
1419
|
+
row_ss = sicd_ew["Grid"]["Row"]["SS"]
|
|
1420
|
+
col_ss = sicd_ew["Grid"]["Col"]["SS"]
|
|
1421
|
+
scp_pixel = sicd_ew["ImageData"]["SCPPixel"]
|
|
1422
|
+
scp_ecf = sicd_ew["GeoData"]["SCP"]["ECF"]
|
|
1481
1423
|
image_grid_locations = (
|
|
1482
1424
|
np.array(
|
|
1483
1425
|
[
|
|
@@ -1491,27 +1433,39 @@ def _update_geo_data(xml_helper):
|
|
|
1491
1433
|
) * [row_ss, col_ss]
|
|
1492
1434
|
|
|
1493
1435
|
icp_ecef, _, _ = sksicd.image_to_ground_plane(
|
|
1494
|
-
|
|
1436
|
+
sicd_ew.elem.getroottree(),
|
|
1495
1437
|
image_grid_locations,
|
|
1496
1438
|
scp_ecf,
|
|
1497
1439
|
sarkit.wgs84.up(sarkit.wgs84.cartesian_to_geodetic(scp_ecf)),
|
|
1498
1440
|
)
|
|
1499
1441
|
icp_llh = sarkit.wgs84.cartesian_to_geodetic(icp_ecef)
|
|
1500
|
-
|
|
1501
|
-
|
|
1442
|
+
sicd_ew["GeoData"]["ImageCorners"] = icp_llh[:, :2]
|
|
1443
|
+
sicd_ew["GeoData"]["ValidData"] = icp_llh[:, :2]
|
|
1502
1444
|
|
|
1503
1445
|
|
|
1504
|
-
def _update_rniirs_info(
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1446
|
+
def _update_rniirs_info(sicd_ew):
|
|
1447
|
+
info_density, predicted_rniirs = utils.get_rniirs_estimate(sicd_ew)
|
|
1448
|
+
sicd_ew["CollectionInfo"].add(
|
|
1449
|
+
"Parameter", ("INFORMATION_DENSITY", f"{info_density:.2G}")
|
|
1450
|
+
)
|
|
1451
|
+
sicd_ew["CollectionInfo"].add(
|
|
1452
|
+
"Parameter", ("PREDICTED_RNIIRS", f"{predicted_rniirs:.1f}")
|
|
1453
|
+
)
|
|
1454
|
+
|
|
1508
1455
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
collection_info_node.append(param_node)
|
|
1456
|
+
@contextlib.contextmanager
|
|
1457
|
+
def uint_tiff():
|
|
1458
|
+
"""Overwrite SAMPLEFORMAT to force TIFFILE not to upcast from complex int16 to complex64
|
|
1513
1459
|
|
|
1514
|
-
|
|
1460
|
+
Per S1-RS-MDA-52-7441 (Sentinel-1 Product Specification) Table 6-13:
|
|
1461
|
+
"Interpretation of pixel format. Set to 5 (complex signed integer, 'int16') for SLC products"
|
|
1462
|
+
"""
|
|
1463
|
+
oldformat = tifffile.SAMPLEFORMAT
|
|
1464
|
+
tifffile.SAMPLEFORMAT = lambda _: oldformat.UINT # treat as UINT
|
|
1465
|
+
try:
|
|
1466
|
+
yield
|
|
1467
|
+
finally:
|
|
1468
|
+
tifffile.SAMPLEFORMAT = oldformat
|
|
1515
1469
|
|
|
1516
1470
|
|
|
1517
1471
|
def main(args=None):
|
|
@@ -1538,14 +1492,14 @@ def main(args=None):
|
|
|
1538
1492
|
|
|
1539
1493
|
manifest_filename = config.safe_product_folder / "manifest.safe"
|
|
1540
1494
|
|
|
1541
|
-
manifest_root =
|
|
1495
|
+
manifest_root = lxml.etree.parse(manifest_filename).getroot()
|
|
1542
1496
|
base_info = _collect_base_info(manifest_root)
|
|
1543
1497
|
files = _get_file_sets(config.safe_product_folder, manifest_root)
|
|
1544
1498
|
|
|
1545
1499
|
used_filenames = set()
|
|
1546
1500
|
for entry in files:
|
|
1547
|
-
product_root_node =
|
|
1548
|
-
swath_info = _collect_swath_info(product_root_node
|
|
1501
|
+
product_root_node = lxml.etree.parse(entry["product"]).getroot()
|
|
1502
|
+
swath_info = _collect_swath_info(product_root_node)
|
|
1549
1503
|
burst_info_list = _collect_burst_info(product_root_node, base_info, swath_info)
|
|
1550
1504
|
if base_info["creation_date_time"].date() >= np.datetime64("2015-11-25"):
|
|
1551
1505
|
[burst_info.update({"radiometric": {}}) for burst_info in burst_info_list]
|
|
@@ -1553,57 +1507,61 @@ def main(args=None):
|
|
|
1553
1507
|
_calc_noise_level_info(entry["noise"], swath_info, burst_info_list)
|
|
1554
1508
|
|
|
1555
1509
|
# Grab the data and write the files
|
|
1556
|
-
|
|
1510
|
+
# Overwrite SAMPLEFORMAT to force TIFFILE not to upcast from complex int16 to complex64
|
|
1511
|
+
# Treat as uint32 and handle the conversion later
|
|
1512
|
+
assert swath_info["pixel_type"] != "RE16I_IM16I", (
|
|
1513
|
+
"pixel handling assumes 'RE16I_IM16I'"
|
|
1514
|
+
)
|
|
1515
|
+
with uint_tiff(), tifffile.TiffFile(entry["data"]) as tif:
|
|
1557
1516
|
image = tif.asarray().T
|
|
1558
1517
|
image_width = tif.pages[0].tags.values()[0].value
|
|
1559
1518
|
begin_col = 0
|
|
1560
1519
|
for burst_info in burst_info_list:
|
|
1561
|
-
|
|
1520
|
+
sicd_xml_obj = _create_sicd_xml(
|
|
1562
1521
|
base_info, swath_info, burst_info, config.classification.upper()
|
|
1563
1522
|
)
|
|
1523
|
+
sicd_ew = sksicd.ElementWrapper(sicd_xml_obj)
|
|
1564
1524
|
# Add SCPCOA node
|
|
1565
|
-
|
|
1566
|
-
sicd.find("./{*}ImageFormation").addnext(scp_coa)
|
|
1567
|
-
xml_helper = sksicd.XmlHelper(et.ElementTree(sicd))
|
|
1525
|
+
sicd_ew["SCPCOA"] = sksicd.compute_scp_coa(sicd_xml_obj.getroottree())
|
|
1568
1526
|
# Update ImageCorners and ValidData
|
|
1569
|
-
_update_geo_data(
|
|
1527
|
+
_update_geo_data(sicd_ew)
|
|
1570
1528
|
|
|
1571
1529
|
# RNIIRS calcs require radiometric info
|
|
1572
1530
|
if "radiometric" in burst_info:
|
|
1573
|
-
_update_rniirs_info(
|
|
1531
|
+
_update_rniirs_info(sicd_ew)
|
|
1574
1532
|
|
|
1575
1533
|
# Check for XML consistency
|
|
1576
|
-
sicd_con = sarkit.verification.SicdConsistency(
|
|
1534
|
+
sicd_con = sarkit.verification.SicdConsistency(sicd_ew.elem)
|
|
1577
1535
|
sicd_con.check()
|
|
1578
1536
|
sicd_con.print_result(fail_detail=True)
|
|
1579
1537
|
|
|
1580
|
-
end_col = begin_col +
|
|
1538
|
+
end_col = begin_col + sicd_ew["ImageData"]["NumCols"]
|
|
1581
1539
|
subset = (slice(0, image_width, 1), slice(begin_col, end_col, 1))
|
|
1582
1540
|
begin_col = end_col
|
|
1583
|
-
image_subset = image[subset]
|
|
1541
|
+
image_subset = np.ascontiguousarray(image[subset])
|
|
1584
1542
|
pixel_type = swath_info["pixel_type"]
|
|
1585
|
-
view_dtype = sksicd.PIXEL_TYPES[pixel_type]["dtype"]
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
complex_data
|
|
1543
|
+
view_dtype = sksicd.PIXEL_TYPES[pixel_type]["dtype"].newbyteorder(
|
|
1544
|
+
image_subset.dtype.byteorder
|
|
1545
|
+
)
|
|
1546
|
+
complex_data = image_subset.view(view_dtype)
|
|
1589
1547
|
|
|
1590
1548
|
metadata = sksicd.NitfMetadata(
|
|
1591
|
-
xmltree=
|
|
1549
|
+
xmltree=sicd_ew.elem.getroottree(),
|
|
1592
1550
|
file_header_part={
|
|
1593
1551
|
"ostaid": "ESA",
|
|
1594
|
-
"ftitle":
|
|
1552
|
+
"ftitle": sicd_ew["CollectionInfo"]["CoreName"],
|
|
1595
1553
|
"security": {
|
|
1596
1554
|
"clas": config.classification[0].upper(),
|
|
1597
1555
|
"clsy": "US",
|
|
1598
1556
|
},
|
|
1599
1557
|
},
|
|
1600
1558
|
im_subheader_part={
|
|
1601
|
-
"iid2":
|
|
1559
|
+
"iid2": sicd_ew["CollectionInfo"]["CoreName"],
|
|
1602
1560
|
"security": {
|
|
1603
1561
|
"clas": config.classification[0].upper(),
|
|
1604
1562
|
"clsy": "US",
|
|
1605
1563
|
},
|
|
1606
|
-
"isorce":
|
|
1564
|
+
"isorce": sicd_ew["CollectionInfo"]["CollectorName"],
|
|
1607
1565
|
},
|
|
1608
1566
|
de_subheader_part={
|
|
1609
1567
|
"security": {
|