def test_copysegmentation_dvid_to_zarr(setup_dvid_to_zarr):
    template_dir, config, volume, dvid_address, repo_uuid, output_file = setup_dvid_to_zarr

    # Modify the config from above to compute pyramid scales,
    # and choose a bounding box that is aligned with the bricks even at scale 2
    # (just for easier testing).
    box_zyx = [[0, 0, 0], [256, 256, 256]]
    config["input"]["geometry"]["bounding-box"] = box_zyx
    config["copysegmentation"]["pyramid-depth"] = 2

    yaml = YAML()
    yaml.default_flow_style = False
    with open(f"{template_dir}/workflow.yaml", 'w') as f:
        yaml.dump(config, f)

    execution_dir, _workflow = launch_flow(template_dir, 1)

    box_zyx = np.array(box_zyx)

    scale_0_vol = volume[box_to_slicing(*box_zyx)]
    scale_1_vol = downsample_labels(scale_0_vol, 2, True)
    scale_2_vol = downsample_labels(scale_1_vol, 2, True)

    store = zarr.NestedDirectoryStore(f"{execution_dir}/{output_file}")
    f = zarr.open(store, 'r')
    output_0_vol = f['s0'][box_to_slicing(*(box_zyx // 1))]
    output_1_vol = f['s1'][box_to_slicing(*(box_zyx // 2))]
    output_2_vol = f['s2'][box_to_slicing(*(box_zyx // 4))]

    assert (output_0_vol == scale_0_vol).all(), \
        "Scale 0: Written vol does not match expected"
    assert (output_1_vol == scale_1_vol).all(), \
        "Scale 1: Written vol does not match expected"
    assert (output_2_vol == scale_2_vol).all(), \
        "Scale 2: Written vol does not match expected"
def test_copygrayscale_from_hdf5_to_dvid_multiscale(setup_hdf5_grayscale_input,
                                                    disable_auto_retry):
    _template_dir, config, _volume, dvid_address, repo_uuid, output_grayscale_name = setup_hdf5_grayscale_input

    # Modify the config from above to compute pyramid scales,
    # and choose a bounding box that is aligned with the bricks even at scale 2
    # (just for easier testing).
    config["input"]["geometry"]["bounding-box"] = [[0, 0, 0], [128, 256, 128]]
    config["copygrayscale"]["min-pyramid-scale"] = 1
    config["copygrayscale"]["max-pyramid-scale"] = 2
    config["copygrayscale"][
        "downsample-method"] = "label"  # This test is easier to write if we use this downsampling method

    box_zyx, scale_0_vol = _run_to_dvid(setup_hdf5_grayscale_input,
                                        check_scale_0=False)

    scale_1_vol = downsample_labels(scale_0_vol, 2, True)
    scale_2_vol = downsample_labels(scale_1_vol, 2, True)

    # Check the other scales -- be careful to extract exactly one brick.
    output_vol = fetch_raw(dvid_address, repo_uuid,
                           output_grayscale_name + '_1', box_zyx // 2)
    assert (output_vol == scale_1_vol).all(), \
        "Scale 1: Written vol does not match expected"

    # Check the other scales -- be careful to extract exactly one brick.
    output_vol = fetch_raw(dvid_address, repo_uuid,
                           output_grayscale_name + '_2', box_zyx // 4)
    assert (output_vol == scale_2_vol).all(), \
        "Scale 2: Written vol does not match expected"
Example #3
0
def downsample(volume, factor, method):
    assert method in DOWNSAMPLE_METHODS
    assert (np.array(volume.shape) % factor == 0).all(), \
        "Volume dimensions must be a multiple of the downsample factor."

    if method == 'subsample':
        sl = slice(None, None, factor)
        return volume[(sl, ) * volume.ndim].copy('C')

    if method == 'block-mean':
        return block_downsample(volume, factor)

    if method in ('zoom', 'grayscale'):  # synonyms
        # vigra is 2.7x faster than scipy, but it complains for small images:
        #
        #  Precondition violation!
        #  resizeImage(): Each output axis must have length > 1.)
        #
        # Furthermore, it seems to be somewhat unstable even for small
        # images that satisfy the above condition.
        # Therefore, use vigra for non-tiny images,
        # and use scipy for the tiny stuff.
        newshape = np.array(volume.shape) // factor
        if (newshape >= 10).all():
            return vigra_sampling_resize(volume, newshape)
        else:
            return scipy.ndimage.zoom(volume, 1 / factor)

    if method == 'mode':
        return downsample_labels(volume, factor, False)
    if method in ('labels', 'label'):  # synonyms
        return downsample_labels(volume, factor, True)
    if method == 'labels-numba':
        reduced_output, _reduced_box = downsample_labels_3d_suppress_zero(
            volume, factor)
        return reduced_output

    raise AssertionError("Shouldn't get here.")
 def downsample_brick(brick):
     assert (brick.physical_box % factor == 0).all()
     assert (brick.logical_box % factor == 0).all()
 
     if method == 'grayscale':
         downsampled_volume = scipy.ndimage.interpolation.zoom(brick.volume, 1/factor, mode='reflect')
     elif method == 'label':
         # Old: Python downsampling
         # downsample_3Dlabels(brick.volume)
     
         # Newer: Numba downsampling
         #downsampled_volume, _ = downsample_labels_3d_suppress_zero(brick.volume, (2,2,2), brick.physical_box)
     
         # Even Newer: C++ downsampling (note: only works on aligned data.)
         # For consistency with DVID's on-demand downsampling, we suppress 0 pixels.
         downsampled_volume = downsample_labels(brick.volume, factor, suppress_zero=True)
     else:
         assert False
 
     downsampled_logical_box = brick.logical_box // factor
     downsampled_physical_box = brick.physical_box // factor
     
     return Brick(downsampled_logical_box, downsampled_physical_box, downsampled_volume)
def test_copysegmentation_from_hdf5_to_dvid_multiscale(
        setup_hdf5_segmentation_input, disable_auto_retry):
    template_dir, config, volume, dvid_address, repo_uuid, _ = setup_hdf5_segmentation_input

    # Modify the config from above to compute pyramid scales,
    # and choose a bounding box that is aligned with the bricks even at scale 2
    # (just for easier testing).
    box_zyx = [[0, 0, 0], [256, 256, 256]]
    config["input"]["geometry"]["bounding-box"] = box_zyx
    config["copysegmentation"]["pyramid-depth"] = 2

    # Change the segmentation name so it doesn't conflict with earlier tests
    output_segmentation_name = 'segmentation-output-from-hdf5-multiscale'
    config["output"]["dvid"]["segmentation-name"] = output_segmentation_name

    yaml = YAML()
    yaml.default_flow_style = False
    with open(f"{template_dir}/workflow.yaml", 'w') as f:
        yaml.dump(config, f)

    _execution_dir, _workflow = launch_flow(template_dir, 1)

    box_zyx = np.array(box_zyx)

    scale_0_vol = volume[box_to_slicing(*box_zyx)]
    scale_1_vol = downsample_labels(scale_0_vol, 2, True)
    scale_2_vol = downsample_labels(scale_1_vol, 2, True)

    output_0_vol = fetch_labelmap_voxels(dvid_address,
                                         repo_uuid,
                                         output_segmentation_name,
                                         box_zyx // 1,
                                         scale=0)
    output_1_vol = fetch_labelmap_voxels(dvid_address,
                                         repo_uuid,
                                         output_segmentation_name,
                                         box_zyx // 2,
                                         scale=1)
    output_2_vol = fetch_labelmap_voxels(dvid_address,
                                         repo_uuid,
                                         output_segmentation_name,
                                         box_zyx // 4,
                                         scale=2)

    #     np.save('/tmp/expected-0.npy', scale_0_vol)
    #     np.save('/tmp/expected-1.npy', scale_1_vol)
    #     np.save('/tmp/expected-2.npy', scale_2_vol)
    #
    #     np.save('/tmp/output-0.npy', output_0_vol)
    #     np.save('/tmp/output-1.npy', output_1_vol)
    #     np.save('/tmp/output-2.npy', output_2_vol)
    #
    #     np.save('/tmp/diff-0.npy', (output_0_vol != scale_0_vol))
    #     np.save('/tmp/diff-1.npy', (output_1_vol != scale_1_vol))
    #     np.save('/tmp/diff-2.npy', (output_2_vol != scale_2_vol))

    assert (output_0_vol == scale_0_vol).all(), \
        "Scale 0: Written vol does not match expected"
    assert (output_1_vol == scale_1_vol).all(), \
        "Scale 1: Written vol does not match expected"
    assert (output_2_vol == scale_2_vol).all(), \
        "Scale 2: Written vol does not match expected"