def test_call_with_mock(self, match_data_arrays, check_times, combine_metadata, get_sensors): """Test calling generic compositor.""" from satpy.composites import IncompatibleAreas combine_metadata.return_value = dict() get_sensors.return_value = 'foo' # One dataset, no mode given res = self.comp([self.all_valid]) self.assertEqual(res.shape[0], 1) self.assertEqual(res.attrs['mode'], 'L') match_data_arrays.assert_not_called() # This compositor has been initialized without common masking, so the # masking shouldn't have been called projectables = [ self.all_valid, self.first_invalid, self.second_invalid ] match_data_arrays.return_value = projectables res = self.comp2(projectables) match_data_arrays.assert_called_once() match_data_arrays.reset_mock() # Dataset for alpha given, so shouldn't be masked projectables = [self.all_valid, self.all_valid] match_data_arrays.return_value = projectables res = self.comp(projectables) match_data_arrays.assert_called_once() match_data_arrays.reset_mock() # When areas are incompatible, masking shouldn't happen match_data_arrays.side_effect = IncompatibleAreas() self.assertRaises(IncompatibleAreas, self.comp, [self.all_valid, self.wrong_shape]) match_data_arrays.assert_called_once()
def __call__(self, datasets, optional_datasets=None, **kwargs): """Modify provided data depending on the modifier name and input data.""" if self.attrs['optional_prerequisites']: for opt_dep in self.attrs['optional_prerequisites']: opt_dep_name = opt_dep if isinstance( opt_dep, str) else opt_dep.get('name', '') if 'NOPE' in opt_dep_name or 'fail' in opt_dep_name: continue assert (optional_datasets is not None and len(optional_datasets)) resolution = datasets[0].attrs.get('resolution') mod_name = self.attrs['modifiers'][-1] data = datasets[0].data i = datasets[0].attrs.copy() if mod_name == 'res_change' and resolution is not None: data = self._handle_res_change(datasets, i) elif 'incomp_areas' in mod_name: raise IncompatibleAreas( "Test modifier 'incomp_areas' always raises IncompatibleAreas") self.apply_modifier_info(datasets[0].attrs, i) return DataArray( data, dims=datasets[0].dims, # coords=datasets[0].coords, attrs=i)
def __call__(self, datasets, optional_datasets, **info): if name == 'res_change' and datasets[0].id.resolution is not None: i = datasets[0].info.copy() i['resolution'] *= 5 elif name == 'incomp_areas': raise IncompatibleAreas("Test modifier 'incomp_areas' always raises IncompatibleAreas") else: i = datasets[0].info info = datasets[0].info.copy() self.apply_modifier_info(i, info) return Dataset(data=np.ma.MaskedArray(datasets[0]), **info)
def _combine_area_extents(self, area1, area2): """Combine the area extents of areas 1 and 2.""" if (area1.area_extent[0] == area2.area_extent[0] and area1.area_extent[2] == area2.area_extent[2] and np.isclose(area1.area_extent[1], area2.area_extent[3])): current_extent = list(area1.area_extent) current_extent[1] = area2.area_extent[1] return current_extent else: raise IncompatibleAreas("Can't concatenate area definitions with " "incompatible area extents: " "{} and {}".format(area1, area2))
def _append_area_defs(self, area1, area2): """Append *area2* to *area1* and return the results""" different_items = (set(area1.proj_dict.items()) ^ set(area2.proj_dict.items())) if different_items: raise IncompatibleAreas("Can't concatenate area definitions with " "different projections: " "{} and {}".format(area1, area2)) area_extent = self._combine_area_extents(area1, area2) y_size = area1.y_size + area2.y_size return AreaDefinition(area1.area_id, area1.name, area1.proj_id, area1.proj_dict, area1.x_size, y_size, area_extent)
def __call__(self, datasets, optional_datasets, **info): if self.attrs['optional_prerequisites']: for opt_dep in self.attrs['optional_prerequisites']: if 'NOPE' in opt_dep or 'fail' in opt_dep: continue assert optional_datasets is not None and \ len(optional_datasets) resolution = datasets[0].attrs.get('resolution') if name == 'res_change' and resolution is not None: i = datasets[0].attrs.copy() i['resolution'] *= 5 elif 'incomp_areas' in name: raise IncompatibleAreas( "Test modifier 'incomp_areas' always raises IncompatibleAreas") else: i = datasets[0].attrs info = datasets[0].attrs.copy() self.apply_modifier_info(i, info) return DataArray(np.ma.MaskedArray(datasets[0]), attrs=info)
def _append_area_defs(self, area1, area2): r"""Append *area2* to *area1*. /!\ Warning: This function modifies *area1* /!\ """ different_items = (set(area1.proj_dict.items()) ^ set(area2.proj_dict.items())) if different_items: raise IncompatibleAreas("Can't concatenate area definitions with " "different projections: " "{} and {}".format(area1, area2)) area1.area_extent = self._combine_area_extents(area1, area2) area1.y_size += area2.y_size # workaround for pyresample try: area1.shape = (area1.y_size, area1.x_size) except AttributeError: pass
def __call__(self, datasets, optional_datasets=[], **info): if len(datasets) != 3: raise ValueError("Expected 3 datasets, got %d" % (len(datasets), )) area = None # raise IncompatibleAreas p1, p2, p3 = datasets if optional_datasets: high_res = optional_datasets[0] low_res = datasets[["red", "green", "blue"].index(self.high_resolution_band)] if high_res.info["area"] != low_res.info["area"]: if np.mod(high_res.shape[0], low_res.shape[0]) or \ np.mod(high_res.shape[1], low_res.shape[1]): raise IncompatibleAreas( "High resolution band is not mapped the same area as the low resolution bands" ) else: f0 = high_res.shape[0] / low_res.shape[0] f1 = high_res.shape[1] / low_res.shape[1] if p1.shape != high_res.shape: p1 = np.ma.repeat(np.ma.repeat(p1, f0, axis=0), f1, axis=1) p1.info["area"] = high_res.info["area"] if p2.shape != high_res.shape: p2 = np.ma.repeat(np.ma.repeat(p2, f0, axis=0), f1, axis=1) p2.info["area"] = high_res.info["area"] if p3.shape != high_res.shape: p3 = np.ma.repeat(np.ma.repeat(p3, f0, axis=0), f1, axis=1) p3.info["area"] = high_res.info["area"] area = high_res.info["area"] if self.high_resolution_band == "red": LOG.debug("Sharpening image with high resolution red band") ratio = high_res.data / p1.data r = high_res.data g = p2.data * ratio b = p3.data * ratio elif self.high_resolution_band == "green": LOG.debug("Sharpening image with high resolution green band") ratio = high_res.data / p2.data r = p1.data * ratio g = high_res.data b = p3.data * ratio elif self.high_resolution_band == "blue": LOG.debug("Sharpening image with high resolution blue band") ratio = high_res.data / p3.data r = p1.data * ratio g = p2.data * ratio b = high_res.data else: # no sharpening r = p1.data g = p2.data b = p3.data mask = p1.mask | p2.mask | p3.mask | high_res.mask else: r, g, b = p1.data, p2.data, p3.data mask = p1.mask | p2.mask | p3.mask # Collect information that is the same between the projectables info = combine_info(*datasets) # Update that information with configured information (including name) info.update(self.info) # Force certain pieces of metadata that we *know* to be true info["wavelength"] = None info.setdefault("standard_name", "true_color") info["mode"] = self.info.get("mode", "RGB") if area is not None: info['area'] = area return Projectable(data=np.concatenate(([r], [g], [b]), axis=0), mask=np.array([[mask, mask, mask]]), **info)