diff --git a/satpy/scene.py b/satpy/scene.py index 8f06d9d81a..ab1759b581 100644 --- a/satpy/scene.py +++ b/satpy/scene.py @@ -900,7 +900,19 @@ def load(self, wishlist, calibration=None, resolution=None, if unload: self.unload(keepables=keepables) - def _resampled_scene(self, new_scn, destination_area, **resample_kwargs): + def _reduce_data(self, source_area, destination_area, dataset): + """Reduce data by slicing it.""" + slice_x, slice_y = source_area.get_area_slices(destination_area) + source_area = source_area[slice_y, slice_x] + dataset = dataset.isel(x=slice_x, y=slice_y) + assert ('x', source_area.x_size) in dataset.sizes.items() + assert ('y', source_area.y_size) in dataset.sizes.items() + dataset.attrs['area'] = source_area + + return dataset + + def _resampled_scene(self, new_scn, destination_area, reduce_data=True, + **resample_kwargs): """Resample `datasets` to the `destination` area.""" new_datasets = {} datasets = list(new_scn.datasets.values()) @@ -933,13 +945,11 @@ def _resampled_scene(self, new_scn, destination_area, **resample_kwargs): LOG.debug("Resampling %s", ds_id) source_area = dataset.attrs['area'] try: - slice_x, slice_y = source_area.get_area_slices( - destination_area) - source_area = source_area[slice_y, slice_x] - dataset = dataset.isel(x=slice_x, y=slice_y) - assert ('x', source_area.x_size) in dataset.sizes.items() - assert ('y', source_area.y_size) in dataset.sizes.items() - dataset.attrs['area'] = source_area + if reduce_data: + dataset = self._reduce_data(source_area, destination_area, + dataset) + else: + LOG.debug("Data reduction disabled by the user") except NotImplementedError: LOG.info("Not reducing data before resampling.") if source_area not in resamplers: @@ -958,7 +968,8 @@ def _resampled_scene(self, new_scn, destination_area, **resample_kwargs): replace_anc(res, pres) def resample(self, destination=None, datasets=None, generate=True, - unload=True, resampler=None, **resample_kwargs): + unload=True, resampler=None, reduce_data=True, + **resample_kwargs): """Resample datasets and return a new scene. Args: @@ -977,6 +988,8 @@ def resample(self, destination=None, datasets=None, generate=True, ('nearest'). Other possible values include 'native', 'ewa', etc. See the :mod:`~satpy.resample` documentation for more information. + reduce_data (bool): Reduce data by matching the input and output + areas and slicing the data arrays (default: True) resample_kwargs: Remaining keyword arguments to pass to individual resampler classes. See the individual resampler class documentation :mod:`here ` for available @@ -992,7 +1005,7 @@ def resample(self, destination=None, datasets=None, generate=True, # we may have some datasets we asked for but don't exist yet new_scn.wishlist = self.wishlist.copy() self._resampled_scene(new_scn, destination, resampler=resampler, - **resample_kwargs) + reduce_data=reduce_data, **resample_kwargs) # regenerate anything from the wishlist that needs it (combining # multiple resolutions, etc.) diff --git a/satpy/tests/test_scene.py b/satpy/tests/test_scene.py index 2532e2628d..08c813813e 100644 --- a/satpy/tests/test_scene.py +++ b/satpy/tests/test_scene.py @@ -1483,10 +1483,11 @@ def _fake_resample_dataset(self, dataset, dest_area, **kwargs): """Return copy of dataset pretending it was resampled.""" return dataset.copy() + @mock.patch('satpy.scene.Scene._reduce_data') @mock.patch('satpy.scene.resample_dataset') @mock.patch('satpy.composites.CompositorLoader.load_compositors') @mock.patch('satpy.scene.Scene.create_reader_instances') - def test_resample_scene_copy(self, cri, cl, rs): + def test_resample_scene_copy(self, cri, cl, rs, reduce_data): """Test that the Scene is properly copied during resampled. The Scene that is created as a copy of the original Scene should not @@ -1550,6 +1551,20 @@ def test_resample_scene_copy(self, cri, cl, rs): self.assertTupleEqual( tuple(loaded_ids[1]), tuple(DatasetID(name='new_ds'))) + # Test that data reduction can be disabled + scene = satpy.scene.Scene(filenames=['bla'], + base_dir='bli', + reader='fake_reader') + + scene.load(['comp19']) + scene['comp19'].attrs['area'] = area_def + new_scene = scene.resample(area_def, reduce_data=False) + self.assertFalse(reduce_data.called) + new_scene = scene.resample(area_def) + self.assertTrue(reduce_data.called_once) + new_scene = scene.resample(area_def, reduce_data=True) + self.assertEqual(reduce_data.call_count, 2) + @mock.patch('satpy.scene.resample_dataset') @mock.patch('satpy.composites.CompositorLoader.load_compositors') @mock.patch('satpy.scene.Scene.create_reader_instances')