You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Some of the S1 velocity granules produced for the ITS_LIVE project have incorrect M11/M12 variables (nasa-jpl/its_live_production#18), which either need to be reprocessed or corrected.
Ideally, instead of reprocessing the granules, we'd be able to use the S1 correction workflow to derive M11/M12 using the script below since M11/M12 only depends on the output Geogrid GeoTIFFs.
and notably, if I run the M11/M12 script below on the Geogrid GeoTIFFs produced when reprocessing the velocity granule, I get the same M11/M12 variables out.
However, if I run the correction workflow using HyP3 AutoRIFT:
I get M11/M12 variables that generally look the same:
(conference internet isn't letting me upload the image; will try again at the hotel room tonight)
where the velocity directory contains GeoGrid GeoTIFFs from the full S1 velocity pair workflow, and the correction directory contains GeoGrid GeoTIFFs from the S1 correction workflow.
The full script is:
fromdatetimeimportdatetimeimportnumpyasnpfromautoRIFTimport__version__asversionfromnetCDF4importDatasetfromhyp3_autoriftimportutilsfromhyp3_autorift.processimportDEFAULT_PARAMETER_FILEscene='S1A_IW_SLC__1SDV_20170203T162106_20170203T162132_015121_018B9A_1380'epsg: int=32635grid_location_path: str='window_location.tif'search_range_path: str='window_search_range.tif'offset2vx_path: str='window_rdr_off2vel_x_vec.tif'offset2vy_path: str='window_rdr_off2vel_y_vec.tif'scale_factor_path: str='window_scale_factor.tif'parameter_file: str=DEFAULT_PARAMETER_FILExGrid, tran, _, srs, nodata=utils.load_geospatial(grid_location_path, band=1)
offset2vy_1, _, _, _, _=utils.load_geospatial(offset2vy_path, band=1)
offset2vy_1[offset2vy_1==nodata] =np.nanoffset2vy_2, _, _, _, _=utils.load_geospatial(offset2vy_path, band=2)
offset2vy_2[offset2vy_2==nodata] =np.nanoffset2vx_1, _, _, _, _=utils.load_geospatial(offset2vx_path, band=1)
offset2vx_1[offset2vx_1==nodata] =np.nanoffset2vx_2, _, _, _, _=utils.load_geospatial(offset2vx_path, band=2)
offset2vx_2[offset2vx_2==nodata] =np.nanoffset2vr, _, _, _, _=utils.load_geospatial(offset2vx_path, band=3)
offset2vr[offset2vr==nodata] =np.nanscale_factor_1, _, _, _, _=utils.load_geospatial(scale_factor_path, band=1)
scale_factor_1[scale_factor_1==nodata] =np.nandimidY, dimidX=xGrid.shapenoDataMask=xGrid==nodatay=np.arange(tran[3], tran[3] +tran[5] *dimidY, tran[5])
x=np.arange(tran[0], tran[0] +tran[1] *dimidX, tran[1])
dr_2_vr_factor=np.median(offset2vr[np.logical_not(np.isnan(offset2vr))])
chunk_lines=np.min([np.ceil(8192/dimidY) *128, dimidY])
ChunkSize= [chunk_lines, dimidX]
nc_outfile=Dataset(f'{scene}_conversion_matrices.nc', 'w', clobber=True, format='NETCDF4')
nc_outfile.setncattr('GDAL_AREA_OR_POINT', 'Area')
nc_outfile.setncattr('Conventions', 'CF-1.8')
nc_outfile.setncattr('date_created', datetime.now().strftime("%d-%b-%Y %H:%M:%S"))
nc_outfile.setncattr('title', 'autoRIFT S1 Corrections')
nc_outfile.setncattr('autoRIFT_software_version', version)
nc_outfile.setncattr('autoRIFT_parameter_file', parameter_file)
nc_outfile.createDimension('x', len(x))
nc_outfile.createDimension('y', len(y))
var=nc_outfile.createVariable('x', np.dtype('float64'), 'x', fill_value=None)
var.setncattr('standard_name', 'projection_x_coordinate')
var.setncattr('description', 'x coordinate of projection')
var.setncattr('units', 'm')
var[:] =xvar=nc_outfile.createVariable('y', np.dtype('float64'), 'y', fill_value=None)
var.setncattr('standard_name', 'projection_y_coordinate')
var.setncattr('description', 'y coordinate of projection')
var.setncattr('units', 'm')
var[:] =ymapping_var_name='mapping'var=nc_outfile.createVariable(mapping_var_name, 'U1', (), fill_value=None)
ifsrs.GetAttrValue('PROJECTION') =='Polar_Stereographic':
var.setncattr('grid_mapping_name', 'polar_stereographic')
var.setncattr('straight_vertical_longitude_from_pole', srs.GetProjParm('central_meridian'))
var.setncattr('false_easting', srs.GetProjParm('false_easting'))
var.setncattr('false_northing', srs.GetProjParm('false_northing'))
var.setncattr('latitude_of_projection_origin', np.sign(srs.GetProjParm('latitude_of_origin')) *90.0)
var.setncattr('latitude_of_origin', srs.GetProjParm('latitude_of_origin'))
var.setncattr('semi_major_axis', float(srs.GetAttrValue('GEOGCS|SPHEROID', 1)))
var.setncattr('scale_factor_at_projection_origin', 1)
var.setncattr('inverse_flattening', float(srs.GetAttrValue('GEOGCS|SPHEROID', 2)))
var.setncattr('spatial_ref', srs.ExportToWkt())
var.setncattr('crs_wkt', srs.ExportToWkt())
var.setncattr('proj4text', srs.ExportToProj4())
var.setncattr('spatial_epsg', epsg)
var.setncattr('GeoTransform', ' '.join(str(x) forxintran))
elifsrs.GetAttrValue('PROJECTION') =='Transverse_Mercator':
var.setncattr('grid_mapping_name', 'universal_transverse_mercator')
zone=epsg-np.floor(epsg/100) *100var.setncattr('utm_zone_number', zone)
var.setncattr('longitude_of_central_meridian', srs.GetProjParm('central_meridian'))
var.setncattr('false_easting', srs.GetProjParm('false_easting'))
var.setncattr('false_northing', srs.GetProjParm('false_northing'))
var.setncattr('latitude_of_projection_origin', srs.GetProjParm('latitude_of_origin'))
var.setncattr('semi_major_axis', float(srs.GetAttrValue('GEOGCS|SPHEROID', 1)))
var.setncattr('scale_factor_at_central_meridian', srs.GetProjParm('scale_factor'))
var.setncattr('inverse_flattening', float(srs.GetAttrValue('GEOGCS|SPHEROID', 2)))
var.setncattr('spatial_ref', srs.ExportToWkt())
var.setncattr('crs_wkt', srs.ExportToWkt())
var.setncattr('proj4text', srs.ExportToProj4())
var.setncattr('spatial_epsg', epsg)
var.setncattr('GeoTransform', ' '.join(str(x) forxintran))
else:
raiseException(f'Projection {srs.GetAttrValue("PROJECTION")} not recognized for this program')
NoDataValue=-32767var=nc_outfile.createVariable('M11', np.dtype('int16'), ('y', 'x'), fill_value=NoDataValue,
zlib=True, complevel=2, shuffle=True, chunksizes=ChunkSize)
var.setncattr('standard_name', 'conversion_matrix_element_11')
var.setncattr(
'description',
'conversion matrix element (1st row, 1st column) that can be multiplied with vx to give range pixel ''displacement dr (see Eq. A18 in https://www.mdpi.com/2072-4292/13/4/749)'
)
var.setncattr('units', 'pixel/(meter/year)')
var.setncattr('grid_mapping', mapping_var_name)
var.setncattr('dr_to_vr_factor', dr_2_vr_factor)
var.setncattr('dr_to_vr_factor_description', 'multiplicative factor that converts slant range ''pixel displacement dr to slant range velocity vr')
M11=offset2vy_2/ (offset2vx_1*offset2vy_2-offset2vx_2*offset2vy_1) /scale_factor_1x1=np.nanmin(M11[:])
x2=np.nanmax(M11[:])
y1=-50y2=50C= [(y2-y1) / (x2-x1), y1-x1* (y2-y1) / (x2-x1)]
var.setncattr('scale_factor', np.float32(1/C[0]))
var.setncattr('add_offset', np.float32(-C[1] /C[0]))
M11[noDataMask] =NoDataValue*np.float32(1/C[0]) +np.float32(-C[1] /C[0])
var[:] =M11var=nc_outfile.createVariable('M12', np.dtype('int16'), ('y', 'x'), fill_value=NoDataValue,
zlib=True, complevel=2, shuffle=True, chunksizes=ChunkSize)
var.setncattr('standard_name', 'conversion_matrix_element_12')
var.setncattr(
'description',
'conversion matrix element (1st row, 2nd column) that can be multiplied with vy to give range pixel ''displacement dr (see Eq. A18 in https://www.mdpi.com/2072-4292/13/4/749)'
)
var.setncattr('units', 'pixel/(meter/year)')
var.setncattr('grid_mapping', mapping_var_name)
var.setncattr('dr_to_vr_factor', dr_2_vr_factor)
var.setncattr('dr_to_vr_factor_description',
'multiplicative factor that converts slant range pixel displacement dr to slant range velocity vr')
M12=-offset2vx_2/ (offset2vx_1*offset2vy_2-offset2vx_2*offset2vy_1) /scale_factor_1x1=np.nanmin(M12[:])
x2=np.nanmax(M12[:])
y1=-50y2=50C= [(y2-y1) / (x2-x1), y1-x1* (y2-y1) / (x2-x1)]
var.setncattr('scale_factor', np.float32(1/C[0]))
var.setncattr('add_offset', np.float32(-C[1] /C[0]))
M12[noDataMask] =NoDataValue*np.float32(1/C[0]) +np.float32(-C[1] /C[0])
var[:] =M12
The text was updated successfully, but these errors were encountered:
To correct the M11/M12 variables in an S1 velocity granule, the values computed for M11/M12 and the dr_to_vr_factor via the correction workflow must be divided by the pair separation (in days).
Some of the S1 velocity granules produced for the ITS_LIVE project have incorrect M11/M12 variables (nasa-jpl/its_live_production#18), which either need to be reprocessed or corrected.
Ideally, instead of reprocessing the granules, we'd be able to use the S1 correction workflow to derive M11/M12 using the script below since M11/M12 only depends on the output Geogrid GeoTIFFs.
If I re-process this pair using HyP3 AutoRIFT:
I get M11/M12 variables with these attributes (Note: only showing ones of interest):
and notably, if I run the M11/M12 script below on the Geogrid GeoTIFFs produced when reprocessing the velocity granule, I get the same M11/M12 variables out.
However, if I run the correction workflow using HyP3 AutoRIFT:
I get M11/M12 variables that generally look the same:
(conference internet isn't letting me upload the image; will try again at the hotel room tonight)
but are ~1 order of magnitude different:
Comparing the GeoTIFFs produced, we see that only the
window_rdr_off2vel_*_vec.tif
tiffs differ (Golden = Velocity; New = Correction):but also visually look the same (when the colorscale is stretched to +/- 2 sdv for each band).
Script to produce M11/M12 NetCDF file from the S1 Correction workflow output GeoTIFFs:
I've uploaded the script to produce a netCDF File containing the M11/M12 variables derived from output GeoGrid GeoTIFFs to:
The files under that prefix are:
where the
velocity
directory contains GeoGrid GeoTIFFs from the full S1 velocity pair workflow, and thecorrection
directory contains GeoGrid GeoTIFFs from the S1 correction workflow.The full script is:
The text was updated successfully, but these errors were encountered: