def roipac_prepifg(base_ifg_paths, params): """ Prepare ROI_PAC interferograms which combines both conversion to geotiff and multilooking/cropping operations. :param list base_ifg_paths: List of unwrapped interferograms :param dict params: Parameters dictionary corresponding to config file """ log.info("Preparing ROI_PAC format interferograms") parallel = params[cf.PARALLEL] if parallel: log.info("Parallel prepifg is not implemented for ROI_PAC") log.info("Running prepifg in serial") xlooks, ylooks, crop = cf.transform_params(params) rsc_file = os.path.join(params[cf.DEM_HEADER_FILE]) if rsc_file is not None: projection = roipac.parse_header(rsc_file)[ifc.PYRATE_DATUM] else: raise roipac.RoipacException('No DEM resource/header file is ' 'provided') dest_base_ifgs = [os.path.join(params[cf.OUT_DIR], os.path.basename(q).split('.')[0] + '_' + os.path.basename(q).split('.')[1] + '.tif') for q in base_ifg_paths] for b, d in zip(base_ifg_paths, dest_base_ifgs): header_file = "%s.%s" % (b, ROI_PAC_HEADER_FILE_EXT) header = roipac.manage_header(header_file, projection) write_geotiff(header, b, d, nodata=params[cf.NO_DATA_VALUE]) prepifg.prepare_ifgs( dest_base_ifgs, crop_opt=crop, xlooks=xlooks, ylooks=ylooks)
def test_multilooked_projection_same_as_geotiff(self): xlooks = ylooks = 1 prepare_ifgs(self.ifg_paths, MAXIMUM_CROP, xlooks, ylooks) mlooked_paths = [ mlooked_path(f, crop_out=MAXIMUM_CROP, looks=xlooks) for f in self.ifg_paths ] self.assert_projection_equal(self.ifg_paths + mlooked_paths)
def test_multilook(self): """Test resampling method using a scaling factor of 4""" scale = 4 # assumes square cells self.ifgs.append(DEM(SML_TEST_DEM_TIF)) self.ifg_paths = [i.data_path for i in self.ifgs] cext = self._custom_extents_tuple() xlooks = ylooks = scale prepare_ifgs(self.ifg_paths, CUSTOM_CROP, xlooks, ylooks, thresh=1.0, user_exts=cext) for n, ipath in enumerate([self.exp_files[3], self.exp_files[7]]): i = Ifg(ipath) i.open() self.assertEqual(i.dataset.RasterXSize, 20 / scale) self.assertEqual(i.dataset.RasterYSize, 28 / scale) # verify resampling path = join(PREP_TEST_TIF, "%s.tif" % n) ds = gdal.Open(path) src_data = ds.GetRasterBand(2).ReadAsArray() exp_resample = multilooking(src_data, scale, scale, thresh=0) self.assertEqual(exp_resample.shape, (7, 5)) assert_array_almost_equal(exp_resample, i.phase_band.ReadAsArray()) ds = None i.close() os.remove(ipath) # verify DEM has been correctly processed # ignore output values as resampling has already been tested for phase exp_dem_path = join(SML_TEST_DEM_DIR, 'roipac_test_trimmed_4rlks_3cr.tif') self.assertTrue(exists(exp_dem_path)) orignal_dem = DEM(SML_TEST_DEM_TIF) orignal_dem.open() dem_dtype = orignal_dem.dataset.GetRasterBand(1).DataType orignal_dem.close() dem = DEM(exp_dem_path) dem.open() # test multilooked dem is of the same datatype as the original dem tif self.assertEqual(dem_dtype, dem.dataset.GetRasterBand(1).DataType) self.assertEqual(dem.dataset.RasterXSize, 20 / scale) self.assertEqual(dem.dataset.RasterYSize, 28 / scale) data = dem.height_band.ReadAsArray() self.assertTrue(data.ptp() != 0) # close ifgs dem.close() for i in self.ifgs: i.close() os.remove(exp_dem_path)
def setUp(self): from tests.common import small_data_setup self.ifgs = small_data_setup() self.ifg_paths = [i.data_path for i in self.ifgs] prepare_ifgs(self.ifg_paths, crop_opt=1, xlooks=1, ylooks=1) looks_paths = [ mlooked_path(d, looks=1, crop_out=1) for d in self.ifg_paths ] self.ifgs_with_nan = [Ifg(i) for i in looks_paths] for ifg in self.ifgs_with_nan: ifg.open()
def test_nodata(self): """Verify NODATA value copied correctly (amplitude band not copied)""" xlooks = ylooks = 1 prepare_ifgs(self.ifg_paths, MINIMUM_CROP, xlooks, ylooks) for ex in [self.exp_files[0], self.exp_files[4]]: ifg = Ifg(ex) ifg.open() # NB: amplitude band doesn't have a NODATA value self.assertTrue( isnan(ifg.dataset.GetRasterBand(1).GetNoDataValue())) ifg.close() for i in self.ifgs: i.close()
def test_already_same_size(self): # should do nothing as layers are same size & no multilooking required ifgs = same_exts_ifgs() ifg_data_paths = [d.data_path for d in ifgs] res_tup = prepare_ifgs(ifg_data_paths, ALREADY_SAME_SIZE, 1, 1) res = [r[1] for r in res_tup] self.assertTrue(all(res))
def test_same_size_multilooking(self): ifgs = same_exts_ifgs() ifg_data_paths = [d.data_path for d in ifgs] xlooks = ylooks = 2 prepare_ifgs(ifg_data_paths, ALREADY_SAME_SIZE, xlooks, ylooks) looks_paths = [ mlooked_path(d, looks=xlooks, crop_out=ALREADY_SAME_SIZE) for d in ifg_data_paths ] mlooked = [Ifg(i) for i in looks_paths] for m in mlooked: m.open() self.assertEqual(len(mlooked), 2) for ifg in mlooked: self.assertAlmostEqual(ifg.x_step, xlooks * self.xs) self.assertAlmostEqual(ifg.x_step, ylooks * self.xs)
def test_nans(self): """Verify NaNs replace 0 in the multilooked phase band""" xlooks = ylooks = 1 prepare_ifgs(self.ifg_paths, MINIMUM_CROP, xlooks, ylooks) for ex in [self.exp_files[0], self.exp_files[4]]: ifg = Ifg(ex) ifg.open() phase = ifg.phase_band.ReadAsArray() self.assertFalse((phase == 0).any()) self.assertTrue((isnan(phase)).any()) ifg.close() self.assertAlmostEqual(nanmax(phase), 4.247, 3) # copied from gdalinfo self.assertAlmostEqual(nanmin(phase), 0.009, 3) # copied from gdalinfo for i in self.ifgs: i.close()
def test_min_extents(self): """Test ifgcropopt=1 crops datasets to min extents.""" xlooks = ylooks = 1 prepare_ifgs(self.ifg_paths, MINIMUM_CROP, xlooks, ylooks) ifg = Ifg(self.exp_files[0]) ifg.open() # output files should have same extents # NB: also verifies gdalwarp correctly copies geotransform across # NB: expected data copied from gdalinfo output gt = ifg.dataset.GetGeoTransform() exp_gt = (150.911666666, 0.000833333, 0, -34.172499999, 0, -0.000833333) for i, j in zip(gt, exp_gt): self.assertAlmostEqual(i, j) self.assert_geotransform_equal([self.exp_files[0], self.exp_files[4]]) ifg.close() for i in self.ifgs: i.close()
def test_open_ifg_from_dataset(self): """ Test showing open() can not be used for Ifg created with gdal.Dataset object as Dataset has already been read in """ paths = [self.ifg.data_path] mlooked_phase_data = prepifg.prepare_ifgs(paths, crop_opt=prepifg.ALREADY_SAME_SIZE, xlooks=2, ylooks=2, write_to_disc=False) mlooked = [Ifg(m[1]) for m in mlooked_phase_data] self.assertRaises(RasterException, mlooked[0].open)
def remove_orbital_error(ifgs, params, preread_ifgs=None): """ Wrapper for orbital error removal functionality. :param ifgs: List of interferograms or interferogram paths :param params: Dict corresponding to config parameters :param preread_ifgs: Dict containing information regarding MPI jobs (optional) :return xxxx """ log.info('Calculating orbital error correction') if not params[cf.ORBITAL_FIT]: log.info('Orbital correction not required') return if preread_ifgs: # don't check except for mpi tests # remove non ifg keys _ = [preread_ifgs.pop(k) for k in ['gt', 'epochlist', 'md', 'wkt']] # perform some general error/sanity checks if mpiops.rank == 0: _check_orbital_ifgs(preread_ifgs) ifg_paths = [i.data_path for i in ifgs] \ if isinstance(ifgs[0], Ifg) else ifgs mlooked = None # mlooking is not necessary for independent correction # can use multiple procesing if write_to_disc=True if params[cf.ORBITAL_FIT_METHOD] == 2: mlooked_dataset = prepifg.prepare_ifgs( ifg_paths, crop_opt=prepifg.ALREADY_SAME_SIZE, xlooks=params[cf.ORBITAL_FIT_LOOKS_X], ylooks=params[cf.ORBITAL_FIT_LOOKS_Y], thresh=params[cf.NO_DATA_AVERAGING_THRESHOLD], write_to_disc=False) mlooked = [Ifg(m[1]) for m in mlooked_dataset] for m in mlooked: m.initialize() m.nodata_value = params[cf.NO_DATA_VALUE] m.convert_to_nans() m.convert_to_mm() orbital_correction(ifgs, params, mlooked=mlooked, preread_ifgs=preread_ifgs)
def test_custom_extents(self): xlooks = ylooks = 1 cext = self._custom_extents_tuple() prepare_ifgs(self.ifg_paths, CUSTOM_CROP, xlooks, ylooks, user_exts=cext) ifg = Ifg(self.exp_files[2]) ifg.open() gt = ifg.dataset.GetGeoTransform() exp_gt = (cext.xfirst, self.xs, 0, cext.yfirst, 0, self.ys) for i, j in zip(gt, exp_gt): self.assertAlmostEqual(i, j) self.assert_geotransform_equal([self.exp_files[2], self.exp_files[6]]) # close ifgs ifg.close() for i in self.ifgs: i.close()
def test_default_max_extents(self): """Test ifgcropopt=2 crops datasets to max bounding box extents.""" xlooks = ylooks = 1 prepare_ifgs(self.ifg_paths, MAXIMUM_CROP, xlooks, ylooks) for f in [self.exp_files[1], self.exp_files[5]]: self.assertTrue(exists(f), msg="Output files not created") # output files should have same extents # NB: also verifies gdalwarp correctly copies geotransform across ifg = Ifg(self.exp_files[1]) ifg.open() gt = ifg.dataset.GetGeoTransform() # copied from gdalinfo output exp_gt = (150.91, 0.000833333, 0, -34.17, 0, -0.000833333) for i, j in zip(gt, exp_gt): self.assertAlmostEqual(i, j) self.assert_geotransform_equal([self.exp_files[1], self.exp_files[5]]) ifg.close() for i in self.ifgs: i.close()
def test_output_datatype(self): """Test resampling method using a scaling factor of 4""" scale = 4 # assumes square cells self.ifgs.append(DEM(SML_TEST_DEM_TIF)) self.ifg_paths = [i.data_path for i in self.ifgs] + [SML_TEST_DEM_TIF] cext = self._custom_extents_tuple() xlooks = ylooks = scale prepare_ifgs(self.ifg_paths, CUSTOM_CROP, xlooks, ylooks, thresh=1.0, user_exts=cext) for i in self.ifg_paths: mlooked_ifg = mlooked_path(i, xlooks, CUSTOM_CROP) ds1 = DEM(mlooked_ifg) ds1.open() ds2 = DEM(i) ds2.open() self.assertEqual( ds1.dataset.GetRasterBand(1).DataType, ds2.dataset.GetRasterBand(1).DataType) ds1 = ds2 = None
def remove_orbital_error(ifgs, params, preread_ifgs=None): """ Wrapper function for PyRate orbital error removal functionality. NB: the ifg data is modified in situ, rather than create intermediate files. The network method assumes the given ifgs have already been reduced to a minimum spanning tree network. :param list ifgs: List of interferograms class objects :param dict params: Dictionary containing configuration parameters :param dict preread_ifgs: Dictionary containing information specifically for MPI jobs (optional) :return: None - interferogram phase data is updated and saved to disk """ ifg_paths = [i.data_path for i in ifgs] \ if isinstance(ifgs[0], Ifg) else ifgs mlooked = None # mlooking is not necessary for independent correction # can use multiple procesing if write_to_disc=True if params[cf.ORBITAL_FIT_METHOD] == NETWORK_METHOD: mlooked_dataset = prepifg.prepare_ifgs( ifg_paths, crop_opt=prepifg.ALREADY_SAME_SIZE, xlooks=params[cf.ORBITAL_FIT_LOOKS_X], ylooks=params[cf.ORBITAL_FIT_LOOKS_Y], thresh=params[cf.NO_DATA_AVERAGING_THRESHOLD], write_to_disc=False) mlooked = [Ifg(m[1]) for m in mlooked_dataset] for m in mlooked: m.initialize() m.nodata_value = params[cf.NO_DATA_VALUE] m.convert_to_nans() m.convert_to_mm() _orbital_correction(ifgs, params, mlooked=mlooked, preread_ifgs=preread_ifgs)