def test_stack(self): scenes = ( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", "landsat:LC08:PRE:TOAR:meta_LC80260322016197_v1", ) scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[1].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds="update", resolution=600) scenes = SceneCollection(scenes) stack, metas = scenes.stack("nir", ctx, raster_info=True) assert stack.shape == (2, 1, 122, 120) assert (stack.mask[:, 0, 2, 2]).all() assert len(metas) == 2 assert all(len(m["geoTransform"]) == 6 for m in metas) img_stack = scenes.stack("nir red", ctx, bands_axis=-1) assert img_stack.shape == (2, 122, 120, 2) # no_alpha = scenes.stack("nir", mask_alpha=False) # # assert raster not called with alpha once mocks exist no_mask = scenes.stack("nir", ctx, mask_alpha=False, mask_nodata=False) assert not hasattr(no_mask, "mask") assert no_mask.shape == (2, 1, 122, 120) with pytest.raises(NotImplementedError): scenes.stack("nir red", ctx, bands_axis=0) stack_axis_1 = scenes.stack("nir red", ctx, bands_axis=1) assert stack_axis_1.shape == (2, 2, 122, 120)
def test_stack(self): scenes = ("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", "landsat:LC08:PRE:TOAR:meta_LC80260322016197_v1") scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[1].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds=overlap.bounds, resolution=600) scenes = SceneCollection(scenes) stack, metas = scenes.stack("nir", ctx, raster_info=True) self.assertEqual(stack.shape, (2, 1, 123, 121)) self.assertTrue((stack.mask[:, 0, 2, 2]).all()) self.assertEqual(len(metas), 2) self.assertTrue(all(len(m["geoTransform"]) == 6 for m in metas)) img_stack = scenes.stack("nir red", ctx, bands_axis=-1) self.assertEqual(img_stack.shape, (2, 123, 121, 2)) # no_alpha = scenes.stack("nir", mask_alpha=False) # # assert raster not called with alpha once mocks exist no_mask = scenes.stack("nir", ctx, mask_alpha=False, mask_nodata=False) self.assertFalse(hasattr(no_mask, "mask")) self.assertEqual(no_mask.shape, (2, 1, 123, 121)) with self.assertRaises(NotImplementedError): scenes.stack("nir red", ctx, bands_axis=0) stack_axis_1 = scenes.stack("nir red", ctx, bands_axis=1) self.assertEqual(stack_axis_1.shape, (2, 2, 123, 121))
def test_mosaic(self): scenes = ("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", "landsat:LC08:PRE:TOAR:meta_LC80260322016197_v1") scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[1].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds="update", resolution=600) scenes = SceneCollection(scenes) mosaic, meta = scenes.mosaic("nir", ctx, raster_info=True) self.assertEqual(mosaic.shape, (1, 122, 120)) self.assertTrue((mosaic.mask[:, 2, 2]).all()) self.assertEqual(len(meta["geoTransform"]), 6) img_mosaic = scenes.mosaic("nir red", ctx, bands_axis=-1) self.assertEqual(img_mosaic.shape, (122, 120, 2)) mosaic_with_alpha = scenes.mosaic(["red", "alpha"], ctx) self.assertEqual(mosaic_with_alpha.shape, (2, 122, 120)) mosaic_only_alpha = scenes.mosaic("alpha", ctx) self.assertEqual(mosaic_only_alpha.shape, (1, 122, 120)) self.assertTrue(((mosaic_only_alpha.data == 0) == mosaic_only_alpha.mask).all()) # no_alpha = scenes.mosaic("nir", mask_alpha=False) # # assert raster not called with alpha once mocks exist no_mask = scenes.mosaic("nir", ctx, mask_alpha=False, mask_nodata=False) self.assertFalse(hasattr(no_mask, "mask")) self.assertEqual(no_mask.shape, (1, 122, 120)) with self.assertRaises(ValueError): scenes.mosaic("alpha red", ctx) with self.assertRaises(TypeError): scenes.mosaic("red", ctx, invalid_argument=True)
def test_stack_flatten(self): scenes = ( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", # note: just duplicated "landsat:LC08:PRE:TOAR:meta_LC80260322016197_v1", ) scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[2].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds="update", resolution=600) scenes = SceneCollection(scenes) unflattened = scenes.stack("nir", ctx) flattened, metas = scenes.stack("nir", ctx, flatten="properties.id", raster_info=True) assert len(flattened) == 2 assert len(metas) == 2 mosaic = scenes.mosaic("nir", ctx) allflat = scenes.stack("nir", ctx, flatten="properties.product") assert (mosaic == allflat).all() for i, scene in enumerate(scenes): scene.properties.foo = i noflat = scenes.stack("nir", ctx, flatten="properties.foo") assert len(noflat) == len(scenes) assert (noflat == unflattened).all()
def test_load_multiband(self): scene, ctx = Scene.from_id("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") arr = scene.ndarray("red green blue", ctx.assign(resolution=1000)) self.assertEqual(arr.shape, (3, 239, 235)) self.assertTrue((arr.mask[:, 2, 2]).all()) self.assertFalse((arr.mask[:, 115, 116]).all())
def test_mosaic_no_alpha(self): scenes = ( "modis:mod11a2:006:meta_MOD11A2.A2017305.h09v05.006.2017314042814_v1", "modis:mod11a2:006:meta_MOD11A2.A2000049.h08v05.006.2015058135046_v1", ) scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[1].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds="update", resolution=600) sc = SceneCollection(scenes) no_mask = sc.mosaic(["Clear_sky_days", "Clear_sky_nights"], ctx, mask_nodata=False) assert not hasattr(no_mask, "mask") masked_alt_alpha_band = sc.mosaic( ["Clear_sky_days", "Clear_sky_nights"], ctx, mask_alpha="Clear_sky_nights") assert hasattr(masked_alt_alpha_band, "mask") # errors when alternate alpha band is provided but not available in the scene with pytest.raises(ValueError): sc.mosaic(["Clear_sky_days", "Clear_sky_nights"], ctx, mask_alpha="alt-alpha")
def test_from_id(self): scene_id = "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1" scene, ctx = Scene.from_id(scene_id) self.assertEqual(scene.properties.id, scene_id) self.assertIsInstance(scene.geometry, shapely.geometry.Polygon) self.assertIsInstance(ctx, geocontext.AOI)
def test_different_band_dtypes(self): scene, ctx = Scene.from_id( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") scene.properties.bands["green"]["dtype"] = "Int16" arr, info = scene.ndarray("red green", ctx.assign(resolution=600), mask_alpha=False) assert arr.dtype.type == np.int32
def test_auto_mask_alpha_true(self): scene, ctx = Scene.from_id( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") arr = scene.ndarray(["red", "green", "blue"], ctx.assign(resolution=1000), mask_nodata=False) self.assertTrue(hasattr(arr, "mask")) self.assertEqual(arr.shape, (3, 239, 235))
def test_load_nomask(self): scene, ctx = Scene.from_id( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") arr = scene.ndarray(["red", "nir"], ctx.assign(resolution=1000), mask_nodata=False, mask_alpha=False) self.assertFalse(hasattr(arr, "mask")) self.assertEqual(arr.shape, (2, 230, 231))
def test_auto_mask_alpha_false(self): scene, ctx = Scene.from_id( "modis:mod11a2:006:meta_MOD11A2.A2017305.h09v05.006.2017314042814_v1" ) arr = scene.ndarray(['Clear_sky_days', 'Clear_sky_nights'], ctx.assign(resolution=1000), mask_nodata=False) self.assertFalse(hasattr(arr, "mask")) self.assertEqual(arr.shape, (2, 688, 473))
def test_from_id(self): scene_id = "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1" scene, ctx = Scene.from_id(scene_id) self.assertEqual(scene.properties.id, scene_id) self.assertIsInstance(ctx, geocontext.AOI) self.assertEqual(ctx.resolution, 15) self.assertEqual(ctx.crs, "EPSG:32615") self.assertEqual(ctx.bounds, scene.geometry.bounds) self.assertEqual(ctx.geometry, None)
def test_stack_serial(self): scenes = ("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", "landsat:LC08:PRE:TOAR:meta_LC80260322016197_v1") scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[1].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds="update", resolution=600) scenes = SceneCollection(scenes) stack, metas = scenes.stack("nir", ctx, raster_info=True) self.assertEqual(stack.shape, (2, 1, 122, 120))
def test_mask_missing_band(self): scene, ctx = Scene.from_id( "modis:mod11a2:006:meta_MOD11A2.A2017305.h09v05.006.2017314042814_v1" ) with pytest.raises(ValueError): scene.ndarray( ["Clear_sky_days", "Clear_sky_nights"], ctx.assign(resolution=1000), mask_alpha="missing_band", mask_nodata=False, )
def test_load_one_band(self): scene, ctx = Scene.from_id("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") arr, info = scene.ndarray("red", ctx.assign(resolution=1000), raster_info=True) self.assertEqual(arr.shape, (1, 239, 235)) self.assertTrue(arr.mask[0, 2, 2]) self.assertFalse(arr.mask[0, 115, 116]) self.assertEqual(len(info["geoTransform"]), 6) with self.assertRaises(TypeError): scene.ndarray("blue", ctx, invalid_argument=True)
def test_different_band_dtypes_fails(self): scene, ctx = Scene.from_id("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") scene.properties.bands = { "red": { "dtype": "UInt16" }, "green": { "dtype": "Int16" } } with self.assertRaises(ValueError): scene.ndarray("red green", ctx)
def test_load_multiband_axis_last(self): scene, ctx = Scene.from_id("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") arr = scene.ndarray("red green blue", ctx.assign(resolution=1000), bands_axis=-1) self.assertEqual(arr.shape, (239, 235, 3)) self.assertTrue((arr.mask[2, 2, :]).all()) self.assertFalse((arr.mask[115, 116, :]).all()) with self.assertRaises(ValueError): arr = scene.ndarray("red green blue", ctx.assign(resolution=1000), bands_axis=3) with self.assertRaises(ValueError): arr = scene.ndarray("red green blue", ctx.assign(resolution=1000), bands_axis=-3)
def test_auto_mask_alpha_false(self): scene, ctx = Scene.from_id( "modis:mod11a2:006:meta_MOD11A2.A2017305.h09v05.006.2017314042814_v1" ) arr = scene.ndarray( ["Clear_sky_days", "Clear_sky_nights"], ctx.assign(resolution=1000), mask_nodata=False, ) assert not hasattr(arr, "mask") assert arr.shape == (2, 688, 473)
def with_alpha(self): scene, ctx = Scene.from_id("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") arr = scene.ndarray(["red", "alpha"], ctx.assign(resolution=1000)) self.assertEqual(arr.shape, (2, 239, 235)) self.assertTrue((arr.mask == (arr.data[1] == 0)).all()) arr = scene.ndarray(["alpha"], ctx.assign(resolution=1000), mask_nodata=False) self.assertEqual(arr.shape, (1, 239, 235)) self.assertTrue((arr.mask == (arr.data == 0)).all()) with self.assertRaises(ValueError): arr = scene.ndarray("alpha red", ctx.assign(resolution=1000))
def test_fails_with_different_dtypes(self): scenes = ("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", "landsat:LC08:PRE:TOAR:meta_LC80260322016197_v1") scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[1].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds="update", resolution=600) scenes = SceneCollection(scenes) scenes[0].properties.bands.nir.dtype = "Byte" with self.assertRaises(ValueError): mosaic, meta = scenes.mosaic("nir", ctx) with self.assertRaises(ValueError): stack, meta = scenes.stack("nir", ctx)
def test_load_one_band(self): scene, ctx = Scene.from_id( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") arr, info = scene.ndarray("red", ctx.assign(resolution=1000), raster_info=True) assert arr.shape == (1, 239, 235) assert arr.mask[0, 2, 2] assert not arr.mask[0, 115, 116] assert len(info["geoTransform"]) == 6 with pytest.raises(TypeError): scene.ndarray("blue", ctx, invalid_argument=True)
def test_incompatible_dtypes(self): scenes = ( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", "landsat:LC08:PRE:TOAR:meta_LC80260322016197_v1", ) scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[1].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds="update", resolution=600) scenes = SceneCollection(scenes) scenes[0].properties.bands.nir.dtype = "Int16" mosaic = scenes.mosaic("nir", ctx) assert mosaic.dtype.type == np.int32 stack, meta = scenes.stack("nir", ctx) assert stack.dtype.type == np.int32
def test_load_multiband_axis_last(self): scene, ctx = Scene.from_id( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") arr = scene.ndarray("red green blue", ctx.assign(resolution=1000), bands_axis=-1) assert arr.shape == (239, 235, 3) assert (arr.mask[2, 2, :]).all() assert not (arr.mask[115, 116, :]).all() with pytest.raises(ValueError): arr = scene.ndarray("red green blue", ctx.assign(resolution=1000), bands_axis=3) with pytest.raises(ValueError): arr = scene.ndarray("red green blue", ctx.assign(resolution=1000), bands_axis=-3)
def test_mosaic_scaling(self): scenes = ( "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1", "landsat:LC08:PRE:TOAR:meta_LC80260322016197_v1", ) scenes, ctxs = zip(*[Scene.from_id(scene) for scene in scenes]) overlap = scenes[0].geometry.intersection(scenes[1].geometry) ctx = ctxs[0].assign(geometry=overlap, bounds="update", resolution=600) scenes = SceneCollection(scenes) mosaic = scenes.mosaic("nir alpha", ctx, scaling="raw") assert mosaic.shape == (2, 122, 120) assert mosaic.dtype == np.uint16 mosaic = scenes.mosaic("nir", ctx, scaling="raw") assert mosaic.shape == (1, 122, 120) assert mosaic.dtype == np.uint16 mosaic = scenes.mosaic("nir", ctx, scaling=[None]) assert mosaic.shape == (1, 122, 120) assert mosaic.dtype == np.uint16
def test_from_id_no_shapely(self): scene_id = "landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1" scene, ctx = Scene.from_id(scene_id) self.assertEqual(ctx.bounds, (-95.8364984, 40.703737, -93.1167728, 42.7999878))
def test_nonexistent_band_fails(self): scene, ctx = Scene.from_id("landsat:LC08:PRE:TOAR:meta_LC80270312016188_v1") with self.assertRaises(ValueError): scene.ndarray("blue yellow", ctx)