def setUp(self): v = peaks(500)[:100,:] utm7 = karta.crs.ProjectedCRS("+proj=utm +zone=7 +north +datum=WGS84", "UTM 7N (WGS 84)") g = karta.RegularGrid([15.0, 15.0, 30.0, 30.0, 0.0, 0.0], v, crs=utm7) fpath = os.path.join(TMPDATA, "test.tif") g.to_gtiff(fpath, compress=None) self.grid = karta.read_gtiff(fpath, in_memory=False)
def setUp(self): v = peaks(500)[:100, :] utm7 = karta.crs.ProjectedCRS("+proj=utm +zone=7 +north +datum=WGS84", "UTM 7N (WGS 84)") g = karta.RegularGrid([15.0, 15.0, 30.0, 30.0, 0.0, 0.0], v, crs=utm7) fpath = os.path.join(TMPDATA, "test.tif") g.to_gtiff(fpath, compress=None) self.grid = karta.read_gtiff(fpath, in_memory=False)
def test_io(self): # try writing a file, then read it back in and verify that it matches v = karta.raster.peaks(500)[:100,:] utm7 = karta.crs.Proj4CRS("+proj=utm +zone=7 +north", "+ellps=WGS84") g = karta.RegularGrid([15.0, 15.0, 30.0, 30.0, 0.0, 0.0], v, crs=utm7) fpath = os.path.join(TESTDATA, "test.tif") g.gtiffwrite(fpath) gnew = karta.read_gtiff(fpath) self.assertTrue("+proj=utm" in gnew.crs.project.srs) self.assertTrue("+zone=7" in gnew.crs.project.srs) self.assertEqual(g.transform, gnew.transform) self.assertEqual(g.values.dtype, gnew.values.dtype) self.assertTrue(np.all(g.values == gnew.values)) return
def test_io(self): # try writing a file, then read it back in and verify that it matches v = karta.raster.peaks(500)[:100, :] utm7 = karta.crs.Proj4CRS("+proj=utm +zone=7 +north", "+ellps=WGS84") g = karta.RegularGrid([15.0, 15.0, 30.0, 30.0, 0.0, 0.0], v, crs=utm7) fpath = os.path.join(TESTDATA, "test.tif") g.gtiffwrite(fpath) gnew = karta.read_gtiff(fpath) self.assertTrue("+proj=utm" in gnew.crs.project.srs) self.assertTrue("+zone=7" in gnew.crs.project.srs) self.assertEqual(g.transform, gnew.transform) self.assertEqual(g.values.dtype, gnew.values.dtype) self.assertTrue(np.all(g.values == gnew.values)) return
def test_io(self): # try writing a file, then read it back in and verify that it matches v = peaks(500)[:100, :] utm7 = karta.crs.ProjectedCRS("+proj=utm +zone=7 +north +datum=WGS84", "UTM 7N (WGS 84)") g = karta.RegularGrid([15.0, 15.0, 30.0, 30.0, 0.0, 0.0], v, crs=utm7) fpath = os.path.join(TMPDATA, "test.tif") g.to_gtiff(fpath, compress=None) gnew = karta.read_gtiff(fpath) self.assertTrue("+proj=utm" in gnew.crs.get_proj4()) self.assertTrue("+zone=7" in gnew.crs.get_proj4()) self.assertEqual(g.transform, gnew.transform) self.assertEqual(g.values.dtype, gnew.values.dtype) self.assertTrue(np.all(g.values == gnew.values)) return
def test_io(self): # try writing a file, then read it back in and verify that it matches v = peaks(500)[:100,:] utm7 = karta.crs.ProjectedCRS("+proj=utm +zone=7 +north +datum=WGS84", "UTM 7N (WGS 84)") g = karta.RegularGrid([15.0, 15.0, 30.0, 30.0, 0.0, 0.0], v, crs=utm7) fpath = os.path.join(TMPDATA, "test.tif") g.to_gtiff(fpath, compress=None) gnew = karta.read_gtiff(fpath) self.assertTrue("+proj=utm" in gnew.crs.get_proj4()) self.assertTrue("+zone=7" in gnew.crs.get_proj4()) self.assertEqual(g.transform, gnew.transform) self.assertEqual(g.values.dtype, gnew.values.dtype) self.assertTrue(np.all(g[:,:] == gnew[:,:])) return
def test_io_virtual(self): # try writing a file, then open it without loading into memory and verify v = peaks(500)[:100,:] utm7 = karta.crs.ProjectedCRS("+proj=utm +zone=7 +north +datum=WGS84", "UTM 7N (WGS 84)") g = karta.RegularGrid([15.0, 15.0, 30.0, 30.0, 0.0, 0.0], v, crs=utm7) fpath = os.path.join(TMPDATA, "test.tif") g.to_gtiff(fpath, compress=None) gnew = karta.read_gtiff(fpath, in_memory=False) self.assertEqual(g.transform, gnew.transform) self.assertEqual(g.values.dtype, gnew.values.dtype) self.assertEqual(g.size, gnew.size) self.assertTrue(np.all(g[10:50:3, 15:45:2] == gnew[10:50:3, 15:45:2])) self.assertTrue(np.all(g[10:50:3, 45:15:-2] == gnew[10:50:3, 45:15:-2])) self.assertTrue(np.all(g[:,:] == gnew[:,:])) return
def compute_vertical_corrections(grids, min_pixel_overlap=100, weighting_func=None, polymasks=()): """ Perform pairwaise comparisons of a list of DEMs and return a dictionary of {index -> vertical correction} that minimizes the misfit between overlapping DEMs, subject to weights from *weighting_func(fnm1, fnm2)*. Parameters ---------- grids : list of filenames of RegularGrid-like instances Grids to compute corrections for. Grids must have the same extent and resolution. min_pixel_overlap : int, optional Minimum number of overlapping data pixels for computing grid relationships (default 100) weighting_func : callable Function that takes two of the input grids (either filenames or RegularGrid instances) and returns a weight. (default, uniforma weighting). polymasks : list or tuple of Polygon instances Polygons that define the data region to use for comparisons, for example to restrict grid correction to comparisons between stable bedrock polygons. If empty (default), all data pixels are considered valid for comparison. """ if isinstance(grids[0], str): gridnames = True else: gridnames = False if weighting_func is None: weighting_func = lambda a,b: 1.0 c, C = _comparison_matrix(len(grids)) # Piecewise comparison (computes the matrix-vector product CD) CD = [] for i, j in c: if gridnames: dem0 = karta.read_gtiff(grids[i], bandclass=SimpleBand) dem1 = karta.read_gtiff(grids[j], bandclass=SimpleBand) dem0.values[dem0.values<-1000000] = np.nan dem1.values[dem1.values<-1000000] = np.nan else: dem0 = grids[i] dem1 = grids[j] # If bedrock regions are provided, limit the overlapping pixel counts # the regions inside the bedrock masking polygons. # Iterate through all polygons, keeping track of pixels that are in at # least one polygon in the *mask_count* array variables. # Then, set all DEM pixel where *mask_count* is zero to NODATA if polymasks is not None and len(polymasks)!=0: mask_count0 = np.zeros(dem0.size, dtype=np.int16) mask_count1 = np.zeros(dem1.size, dtype=np.int16) for poly in polymasks: x = [a[0] for a in poly.get_vertices(dem0.crs)] y = [a[1] for a in poly.get_vertices(dem0.crs)] ny, nx = dem0.size msk0 = karta.raster.grid.mask_poly(x, y, nx, ny, dem0.transform) ny, nx = dem1.size msk1 = karta.raster.grid.mask_poly(x, y, nx, ny, dem1.transform) mask_count0[msk0] += 1 mask_count1[msk1] += 1 dem0.values[mask_count0==0] = dem0.nodata dem1.values[mask_count1==0] = dem1.nodata msk = dem0.data_mask & dem1.data_mask if msk.sum() >= min_pixel_overlap: CD.append(np.mean(dem0[msk] - dem1[msk])) else: CD.append(np.nan) del dem0, dem1, msk # Augment C by removing rows where there is no appreciable overlap Ca = C[~np.isnan(CD),:] # Drop non-ovelapping relations CaD = np.array(CD)[~np.isnan(CD)] corrected_grids = [i for tf, i in zip(~np.all(Ca==0, axis=0), range(len(grids))) if tf] Ca = Ca[:,~np.all(Ca==0, axis=0)] # Drop DEMs not involved in remaining relations # Compute weights Wdiag = np.zeros(len(Ca)) for i,row in enumerate(Ca): grid1 = grids[corrected_grids[np.argmin(row)]] grid2 = grids[corrected_grids[np.argmax(row)]] Wdiag[i] = weighting_func(grid1, grid2) W = np.diag(Wdiag) Winv = np.linalg.inv(W) # Solve the weighted least-squares problem: C^T W^-1 C dz = -C^T W^-1 C D #dz = np.linalg.solve(np.dot(np.dot(Ca.T, Winv), Ca), # np.dot(np.dot(Ca.T, Winv), -CaD)) A = np.dot(np.dot(Ca.T, Winv), Ca) RHS = np.dot(np.dot(Ca.T, Winv), -CaD) # Append a constraint to ensure that the mean of dz is zero n = A.shape[0] A = np.r_[np.c_[A, np.zeros(n)], np.ones([1,n+1])] RHS = np.r_[RHS, 0.0] # A^T.A may be singular, so solve system with the pseudoinverse dz = np.dot(np.linalg.pinv(A), RHS)[:-1] return {i: _dz for i, _dz in zip(corrected_grids, dz)}