def downsample_unpadded_data( buffer: np.ndarray, target_mag: Mag, interpolation_mode: InterpolationModes ) -> np.ndarray: target_mag_np = np.array(target_mag.to_list()) current_dimension_size = np.array(buffer.shape[1:]) padding_size_for_downsampling = ( target_mag_np - (current_dimension_size % target_mag_np) % target_mag_np ) padding_size_for_downsampling = list(zip([0, 0, 0], padding_size_for_downsampling)) buffer = np.pad( buffer, pad_width=[(0, 0)] + padding_size_for_downsampling, mode="constant" ) dimension_decrease = np.array([1] + target_mag.to_list()) downsampled_buffer_shape = np.array(buffer.shape) // dimension_decrease downsampled_buffer = np.empty(dtype=buffer.dtype, shape=downsampled_buffer_shape) for channel in range(buffer.shape[0]): downsampled_buffer[channel] = downsample_cube( buffer[channel], target_mag.to_list(), interpolation_mode ) return downsampled_buffer
def test_mag_constructor() -> None: mag = Mag(16) assert mag.to_list() == [16, 16, 16] mag = Mag("256") assert mag.to_list() == [256, 256, 256] mag = Mag("16-2-4") assert mag.to_list() == [16, 2, 4] mag1 = Mag("16-2-4") mag2 = Mag("8-2-4") assert mag1 > mag2 assert mag1.to_layer_name() == "16-2-4" assert np.all(mag1.to_np() == np.array([16, 2, 4])) assert mag1 == Mag(mag1) assert mag1 == Mag(mag1.to_np())
def mag_unstructure(mag: Mag) -> List[int]: return mag.to_list()
def upsample( self, from_mag: Mag, finest_mag: Mag = Mag(1), compress: bool = False, sampling_mode: Union[str, SamplingModes] = SamplingModes.ANISOTROPIC, align_with_other_layers: Union[bool, "Dataset"] = True, buffer_shape: Optional[Vec3Int] = None, buffer_edge_len: Optional[int] = None, args: Optional[Namespace] = None, *, min_mag: Optional[Mag] = None, ) -> None: """ Upsamples the data starting from `from_mag` as long as the magnification is `>= finest_mag`. There are three different `sampling_modes`: - 'anisotropic' - The next magnification is chosen so that the width, height and depth of a downsampled voxel assimilate. For example, if the z resolution is worse than the x/y resolution, z won't be downsampled in the first downsampling step(s). As a basis for this method, the voxel_size from the datasource-properties.json is used. - 'isotropic' - Each dimension is downsampled equally. - 'constant_z' - The x and y dimensions are downsampled equally, but the z dimension remains the same. `min_mag` is deprecated, please use `finest_mag` instead. """ assert ( from_mag in self.mags.keys() ), f"Failed to upsample data. The from_mag ({from_mag.to_layer_name()}) does not exist." if min_mag is not None: warn_deprecated("upsample(min_mag=…)", "upsample(finest_mag=…)") assert finest_mag == Mag( 1 ), "Cannot set both min_mag and finest_mag, please only use finest_mag." finest_mag = min_mag sampling_mode = SamplingModes.parse(sampling_mode) voxel_size: Optional[Tuple[float, float, float]] = None if sampling_mode == SamplingModes.ANISOTROPIC: voxel_size = self.dataset.voxel_size elif sampling_mode == SamplingModes.ISOTROPIC: voxel_size = None elif sampling_mode == SamplingModes.CONSTANT_Z: finest_mag_with_fixed_z = finest_mag.to_list() finest_mag_with_fixed_z[2] = from_mag.to_list()[2] finest_mag = Mag(finest_mag_with_fixed_z) voxel_size = None else: raise AttributeError( f"Upsampling failed: {sampling_mode} is not a valid UpsamplingMode ({SamplingModes.ANISOTROPIC}, {SamplingModes.ISOTROPIC}, {SamplingModes.CONSTANT_Z})" ) if buffer_shape is None and buffer_edge_len is not None: buffer_shape = Vec3Int.full(buffer_edge_len) dataset_to_align_with = self._get_dataset_from_align_with_other_layers( align_with_other_layers) mags_to_upsample = calculate_mags_to_upsample(from_mag, finest_mag, dataset_to_align_with, voxel_size) for prev_mag, target_mag in zip([from_mag] + mags_to_upsample[:-1], mags_to_upsample): assert prev_mag > target_mag assert target_mag not in self.mags prev_mag_view = self.mags[prev_mag] mag_factors = [ t / s for (t, s) in zip(target_mag.to_list(), prev_mag.to_list()) ] # initialize the new mag target_mag_view = self._initialize_mag_from_other_mag( target_mag, prev_mag_view, compress) # Get target view target_view = target_mag_view.get_view() # perform upsampling with get_executor_for_args(args) as executor: if buffer_shape is None: buffer_shape = determine_buffer_shape(prev_mag_view.info) func = named_partial( upsample_cube_job, mag_factors=mag_factors, buffer_shape=buffer_shape, ) prev_mag_view.get_view().for_zipped_chunks( # this view is restricted to the bounding box specified in the properties func, target_view=target_view, executor=executor, progress_desc= f"Upsampling from Mag {prev_mag} to Mag {target_mag}", )