-
Notifications
You must be signed in to change notification settings - Fork 320
Refactor _resampled_scene() and _reduce_data() methods of the Scene class
#3178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -867,45 +867,68 @@ | |
|
|
||
| If data reduction is enabled, some local caching is perfomed in order to | ||
| avoid recomputation of area intersections. | ||
| """ | ||
| from satpy.resample.base import resample_dataset | ||
|
|
||
| new_datasets = {} | ||
| datasets = list(new_scn._datasets.values()) | ||
| destination_area = self._get_finalized_destination_area(destination_area, new_scn) | ||
|
|
||
| resamplers = {} | ||
| reductions = {} | ||
| for dataset, parent_dataset in dataset_walker(datasets): | ||
| ds_id = DataID.from_dataarray(dataset) | ||
| pres = None | ||
| if parent_dataset is not None: | ||
| pres = new_datasets[DataID.from_dataarray(parent_dataset)] | ||
| if ds_id in new_datasets: | ||
| replace_anc(new_datasets[ds_id], pres) | ||
| if ds_id in new_scn._datasets: | ||
| new_scn._datasets[ds_id] = new_datasets[ds_id] | ||
| pres = self._get_new_datasets_from_parent(new_datasets, parent_dataset) | ||
| if self._replace_anc_for_new_datasets(new_datasets, ds_id, pres, new_scn): | ||
| continue | ||
| if dataset.attrs.get("area") is None: | ||
| if parent_dataset is None: | ||
| new_scn._datasets[ds_id] = dataset | ||
| else: | ||
| replace_anc(dataset, pres) | ||
| if self._update_area(dataset, parent_dataset, new_scn, ds_id, pres): | ||
| continue | ||
| LOG.debug("Resampling %s", ds_id) | ||
| source_area = dataset.attrs["area"] | ||
| dataset, source_area = self._reduce_data(dataset, source_area, destination_area, | ||
|
|
||
| dataset, source_area = self._reduce_data(dataset, destination_area, | ||
| reduce_data, reductions, resample_kwargs) | ||
| self._prepare_resampler(source_area, destination_area, resamplers, resample_kwargs) | ||
| kwargs = resample_kwargs.copy() | ||
| kwargs["resampler"] = resamplers[source_area] | ||
| res = resample_dataset(dataset, destination_area, **kwargs) | ||
|
|
||
| LOG.debug("Resampling %s", ds_id) | ||
| res = self._resample_dataset(source_area, destination_area, dataset, resamplers, resample_kwargs) | ||
|
|
||
|
Check notice on line 890 in satpy/scene.py
|
||
| new_datasets[ds_id] = res | ||
| if ds_id in new_scn._datasets: | ||
| new_scn._datasets[ds_id] = res | ||
| if parent_dataset is not None: | ||
| replace_anc(res, pres) | ||
|
|
||
| @classmethod | ||
| def _get_new_datasets_from_parent(self, new_datasets, parent_dataset): | ||
| if parent_dataset is not None: | ||
| return new_datasets[DataID.from_dataarray(parent_dataset)] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In addition to renaming, it seems that for ds_id, dataset, resampled_parent in resampled_dataset_walker(datasets, new_datasets):Or something like that. ...and if that is done, then there might be an argument for putting I'll admit the code was ugly and the logic of
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for all the comments and no regular review. I just keep brainstorming. One other idea, what if only |
||
| return None | ||
|
|
||
| @classmethod | ||
| def _replace_anc_for_new_datasets(self, new_datasets, ds_id, pres, new_scn): | ||
| if ds_id in new_datasets: | ||
| replace_anc(new_datasets[ds_id], pres) | ||
| if ds_id in new_scn._datasets: | ||
| new_scn._datasets[ds_id] = new_datasets[ds_id] | ||
| return True | ||
| return False | ||
|
|
||
| @classmethod | ||
| def _update_area(self, dataset, parent_dataset, new_scn, ds_id, pres): | ||
| if dataset.attrs.get("area") is None: | ||
| if parent_dataset is None: | ||
| new_scn._datasets[ds_id] = dataset | ||
| else: | ||
| replace_anc(dataset, pres) | ||
| return True | ||
| return False | ||
|
|
||
| def _resample_dataset(self, source_area, destination_area, dataset, resamplers, resample_kwargs): | ||
| from satpy.resample.base import resample_dataset | ||
|
|
||
| self._prepare_resampler(source_area, destination_area, resamplers, resample_kwargs) | ||
| kwargs = resample_kwargs.copy() | ||
| kwargs["resampler"] = resamplers[source_area] | ||
| res = resample_dataset(dataset, destination_area, **kwargs) | ||
|
|
||
| return res | ||
|
|
||
| def _get_finalized_destination_area(self, destination_area, new_scn): | ||
| if isinstance(destination_area, str): | ||
| destination_area = get_area_def(destination_area) | ||
|
|
@@ -927,32 +950,39 @@ | |
| resamplers[source_area] = resampler | ||
| self._resamplers[key] = resampler | ||
|
|
||
| def _reduce_data(self, dataset, source_area, destination_area, reduce_data, reductions, resample_kwargs): | ||
| def _reduce_data(self, dataset, destination_area, reduce_data, reductions, resample_kwargs): | ||
| source_area = dataset.attrs["area"] | ||
| if not reduce_data: | ||
| LOG.debug("Data reduction disabled by the user") | ||
| return dataset, source_area | ||
|
|
||
| try: | ||
| if reduce_data: | ||
| key = source_area | ||
| try: | ||
| (slice_x, slice_y), source_area = reductions[key] | ||
| except KeyError: | ||
| if resample_kwargs.get("resampler") == "gradient_search": | ||
| factor = resample_kwargs.get("shape_divisible_by", 2) | ||
| else: | ||
| factor = None | ||
| try: | ||
| slice_x, slice_y = source_area.get_area_slices( | ||
| destination_area, shape_divisible_by=factor) | ||
| except TypeError: | ||
| slice_x, slice_y = source_area.get_area_slices( | ||
| destination_area) | ||
| source_area = source_area[slice_y, slice_x] | ||
| reductions[key] = (slice_x, slice_y), source_area | ||
| dataset = self._slice_data(source_area, (slice_x, slice_y), dataset) | ||
| else: | ||
| LOG.debug("Data reduction disabled by the user") | ||
| slice_x, slice_y = self._get_source_dest_slices(source_area, destination_area, reductions, resample_kwargs) | ||
| source_area = source_area[slice_y, slice_x] | ||
| reductions[source_area] = (slice_x, slice_y), source_area | ||
| dataset = self._slice_data(source_area, (slice_x, slice_y), dataset) | ||
|
Comment on lines
959
to
+963
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious if the |
||
| except NotImplementedError: | ||
| LOG.info("Not reducing data before resampling.") | ||
|
|
||
|
Check notice on line 966 in satpy/scene.py
|
||
| return dataset, source_area | ||
|
|
||
| @classmethod | ||
| def _get_source_dest_slices(self, source_area, destination_area, reductions, resample_kwargs): | ||
| try: | ||
| (slice_x, slice_y), source_area = reductions[source_area] | ||
| except KeyError: | ||
| if resample_kwargs.get("resampler") == "gradient_search": | ||
| factor = resample_kwargs.get("shape_divisible_by", 2) | ||
| else: | ||
| factor = None | ||
| try: | ||
| slice_x, slice_y = source_area.get_area_slices( | ||
| destination_area, shape_divisible_by=factor) | ||
| except TypeError: | ||
| slice_x, slice_y = source_area.get_area_slices( | ||
| destination_area) | ||
| return slice_x, slice_y | ||
|
|
||
| def resample( | ||
| self, | ||
| destination: AreaDefinition | CoordinateDefinition | None = None, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
selfshould beclssince these are classmethods now, but given that they are classmethods or could be staticmethods, how about we move these to outside of the Scene? And could they (or should they) be moved to thesatpy.resamplesubpackage?