Example #1
0
def test_ndrange():
    r = ndrange((1, 2, 3), (3, 5, 6), (1, 2, 2))
    expected = [(1, 2, 3), (1, 2, 5), (1, 4, 3), (1, 4, 5), (2, 2, 3),
                (2, 2, 5), (2, 4, 3), (2, 4, 5)]

    assert len(r) == len(expected)
    assert list(r) == expected
Example #2
0
def test_labelindex(labelmap_setup):
    dvid_server, dvid_repo, _merge_table_path, _mapping_path, _supervoxel_vol = labelmap_setup

    # Need an unlocked node to test these posts
    uuid = post_branch(dvid_server, dvid_repo, 'test_labelindex',
                       'test_labelindex')
    instance_info = (dvid_server, uuid, 'segmentation-scratch')

    # Write some random data
    sv = 99
    vol = sv * np.random.randint(2, size=(128, 128, 128), dtype=np.uint64)
    offset = np.array((64, 64, 64))

    # DVID will generate the index.
    post_labelmap_voxels(*instance_info, offset, vol)

    # Compute labelindex table from scratch
    rows = []
    for block_coord in ndrange(offset, offset + vol.shape, (64, 64, 64)):
        block_coord = np.array(block_coord)
        block_box = np.array((block_coord, block_coord + 64))
        block = extract_subvol(vol, block_box - offset)

        count = (block == sv).sum()
        rows.append([*block_coord, sv, count])

    index_df = pd.DataFrame(rows, columns=['z', 'y', 'x', 'sv', 'count'])

    # Check DVID's generated labelindex table against expected
    labelindex_tuple = fetch_labelindex(*instance_info, sv, format='pandas')
    assert labelindex_tuple.label == sv

    labelindex_tuple.blocks.sort_values(['z', 'y', 'x', 'sv'], inplace=True)
    labelindex_tuple.blocks.reset_index(drop=True, inplace=True)
    assert (labelindex_tuple.blocks == index_df).all().all()

    # Check our protobuf against DVID's
    index_tuple = PandasLabelIndex(index_df, sv, 1,
                                   datetime.datetime.now().isoformat(),
                                   'someuser')
    labelindex = create_labelindex(index_tuple)

    # Since labelindex block entries are not required to be sorted,
    # dvid might return them in a different order.
    # Hence this comparison function which sorts them first.
    def compare_proto_blocks(left, right):
        left_blocks = sorted(left.blocks.items())
        right_blocks = sorted(right.blocks.items())
        return left_blocks == right_blocks

    dvid_labelindex = fetch_labelindex(*instance_info, sv, format='protobuf')
    assert compare_proto_blocks(labelindex, dvid_labelindex)

    # Check post/get roundtrip
    post_labelindex(*instance_info, sv, labelindex)
    dvid_labelindex = fetch_labelindex(*instance_info, sv, format='protobuf')
    assert compare_proto_blocks(labelindex, dvid_labelindex)
 def place_test_object(label, corner):
     corner = np.array(corner)
     label_vol = create_test_object().astype(np.uint64)
     label_vol *= label
     
     corners = np.array(list(ndrange((0,0,0), label_vol.shape, (64,64,64))))
     
     # Drop it away from (0,0,0) to make sure the workflow handles arbitrary locations
     corners += corner
     
     blockwise_vol = view_as_blocks(label_vol, (64,64,64))
     blocks = blockwise_vol.reshape(-1,64,64,64)
     
     # post to dvid
     post_labelarray_blocks(dvid_address, repo_uuid, input_segmentation_name, corners, blocks, downres=True, noindexing=False)
     return np.array([corner, corner + label_vol.shape])
Example #4
0
def test_is_box_coverage_complete():
    full_box = [[0, 50, 100], [100, 150, 200]]
    assert is_box_coverage_complete([full_box], full_box)
    full_box = np.array(full_box)

    boxes = [[[0, 50, 100], [50, 150, 200]], [[50, 50, 100], [100, 150, 200]]]
    assert is_box_coverage_complete(boxes, full_box)

    boxes = [[[0, 50, 100], [50, 150, 200]], [[50, 50, 100], [75, 150, 200]]]
    assert not is_box_coverage_complete(boxes, full_box)

    box_shape = np.array((50, 50, 50))
    boxes = [(box, box + box_shape)
             for box in ndrange(full_box[0], full_box[1], box_shape)]
    assert is_box_coverage_complete(boxes, full_box)
    assert not is_box_coverage_complete(boxes[:-1], full_box)
    assert not is_box_coverage_complete(boxes[1:], full_box)

    # Try boxes that exceed the bounds of full_box
    boxes = [[[0, 0, 100], [50, 150, 200]], [[50, 50, 100], [100, 150, 300]]]
    assert is_box_coverage_complete(boxes, full_box)

    boxes = [[[0, 0, 100], [50, 150, 200]], [[50, 50, 100], [75, 150, 300]]]
    assert not is_box_coverage_complete(boxes, full_box)
def setup_dvid_segmentation_input(setup_dvid_repo):
    dvid_address, repo_uuid = setup_dvid_repo
    input_segmentation_name = 'segmentation-sparsemeshes-input'

    create_labelmap_instance(dvid_address,
                             repo_uuid,
                             input_segmentation_name,
                             max_scale=3)

    label_vol = create_test_object().astype(np.uint64)
    label_vol *= 100

    corners = np.array(list(ndrange((0, 0, 0), label_vol.shape, (64, 64, 64))))

    # Drop it away from (0,0,0) to make sure the workflow handles arbitrary locations
    corners += 256

    blockwise_vol = view_as_blocks(label_vol, (64, 64, 64))
    blocks = blockwise_vol.reshape(-1, 64, 64, 64)

    # post to dvid
    post_labelarray_blocks(dvid_address,
                           repo_uuid,
                           input_segmentation_name,
                           corners,
                           blocks,
                           downres=True,
                           noindexing=False)

    template_dir = tempfile.mkdtemp(suffix="sparsemeshes-template")

    config_text = textwrap.dedent(f"""\
        workflow-name: sparsemeshes
        cluster-type: {CLUSTER_TYPE}

        input:
          dvid:
            server: {dvid_address}
            uuid: {repo_uuid}
            segmentation-name: {input_segmentation_name}
           
          geometry:
            bounding-box: [[0,0,0], [128,128,128]]
            block-width: 64
            available-scales: [0,1,2,3]
 
        sparsemeshes:
          min-scale: 0
          max-analysis-volume: 1e6 # Too small for scale 0, will use scale 1
          bodies: [100, 200] # 200 doesn't exist, will fail (see below)
          smoothing-iterations: 3
          decimation-fraction: 0.1
          format: obj
          output-directory: meshes
    """)

    with open(f"{template_dir}/workflow.yaml", 'w') as f:
        f.write(config_text)

    yaml = YAML()
    with StringIO(config_text) as f:
        config = yaml.load(f)

    return template_dir, config, dvid_address, repo_uuid
def test_connectedcomponents(setup_connectedcomponents_hdf5_zarr,
                             disable_auto_retry):
    template_dir, _config, input_vol = setup_connectedcomponents_hdf5_zarr

    execution_dir, workflow = launch_flow(template_dir, 1)
    final_config = workflow.config

    output_path = final_config["output"]["zarr"]["path"]
    dset_name = final_config["output"]["zarr"]["dataset"]

    store = zarr.NestedDirectoryStore(output_path)
    f = zarr.open(store=store, mode='r')
    output_vol = f[dset_name][:]
    assert output_vol.shape == input_vol.shape

    final_labels = pd.unique(output_vol.reshape(-1))

    # Never change label 0
    assert 0 in final_labels
    assert ((input_vol == 0) == (output_vol == 0)).all()

    # Single-component objects
    assert 2 in final_labels
    assert 4 in final_labels

    assert ((input_vol == 2) == (output_vol == 2)).all()
    assert ((input_vol == 4) == (output_vol == 4)).all()

    # Split objects
    assert 1 not in final_labels
    assert 3 not in final_labels

    for corner in map(np.array, ndrange((0, 0, 0), (1, 8, 8), (1, 4, 4))):
        box = (corner, corner + (1, 4, 4))
        input_block = extract_subvol(input_vol, box)
        output_block = extract_subvol(output_vol, box)

        for orig_label in [1, 3]:
            if orig_label in input_block:
                positions = (input_block == orig_label)

                assert (input_block[positions] != output_block[positions]).all(), \
                    f"original label {orig_label} was not split!"

                assert (output_block[positions] > input_vol.max()).all(), \
                    f"original label {orig_label} was not split!"

                # This block-based assertion is not generally true for all possible input,
                # but our test data blocks are set up so that this is a valid check.
                # (No block happens to contain more than one final CC that came from the same original label.)
                assert (output_block[positions] == output_block[positions][0]).all(), \
                    f"original label {orig_label} ended up over-segmentated"

    # Check CSV output
    df = pd.read_csv(f'{execution_dir}/relabeled-objects.csv')

    assert len(df.query('orig_label == 0')) == 0
    assert len(df.query('orig_label == 1')) == 3
    assert len(df.query('orig_label == 2')) == 0
    assert len(df.query('orig_label == 3')) == 2
    assert len(df.query('orig_label == 4')) == 0

    assert not df['final_label'].duplicated().any()
    assert (df['final_label'] > input_vol.max()).all()
def test_connectedcomponents_dvid_subset_labels(setup_connectedcomponents_dvid,
                                                disable_auto_retry):
    template_dir, _config, input_vol, dvid_address, repo_uuid, output_segmentation_name = setup_connectedcomponents_dvid

    execution_dir, workflow = launch_flow(template_dir, 1)
    _final_config = workflow.config

    output_vol = fetch_labelmap_voxels(dvid_address,
                                       repo_uuid,
                                       output_segmentation_name,
                                       [(0, 0, 0), input_vol.shape],
                                       supervoxels=True)
    assert output_vol.shape == input_vol.shape

    final_labels = pd.unique(output_vol.reshape(-1))

    # Never change label 0
    assert 0 in final_labels
    assert ((input_vol == 0) == (output_vol == 0)).all()

    # Single-component objects
    assert 2 in final_labels
    assert 4 in final_labels

    assert ((input_vol == 2) == (output_vol == 2)).all()
    assert ((input_vol == 4) == (output_vol == 4)).all()

    # Omitted from analysis; left unsplit
    assert 3 in final_labels
    assert ((input_vol == 3) == (output_vol == 3)).all()

    # Split objects
    assert 1 not in final_labels

    for corner in map(np.array, ndrange((0, 0, 0), (1, 8, 8), (1, 4, 4))):
        box = (corner, corner + 4)
        input_block = extract_subvol(input_vol, box)
        output_block = extract_subvol(output_vol, box)

        for orig_label in [1]:
            if orig_label in input_block:
                positions = (input_block == orig_label)

                assert (input_block[positions] != output_block[positions]).all(), \
                    f"original label {orig_label} was not split!"

                assert (output_block[positions] > input_vol.max()).all(), \
                    f"original label {orig_label} was not split!"

                # This block-based assertion is not generally true for all possible input,
                # but our test data blocks are set up so that this is a valid check.
                # (No block happens to contain more than one final CC that came from the same original label.)
                assert (output_block[positions] == output_block[positions][0]).all(), \
                    f"original label {orig_label} ended up over-segmentated"

    #
    # Check CSV output
    #
    df = pd.read_csv(f'{execution_dir}/relabeled-objects.csv')

    assert len(df.query('orig_label == 0')) == 0
    assert len(df.query('orig_label == 1')) == 3
    assert len(df.query('orig_label == 2')) == 0
    assert len(df.query('orig_label == 3')) == 0  # 3 was not touched.
    assert len(df.query('orig_label == 4')) == 0

    assert not df['final_label'].duplicated().any()
    assert (df['final_label'] > input_vol.max()).all()

    #
    # Check block stats
    #
    with h5py.File(f'{execution_dir}/block-statistics.h5', 'r') as f:
        stats_df = pd.DataFrame(f['stats'][:])

    for row in stats_df.itertuples():
        corner = np.array((row.z, row.y, row.x))
        block_box = np.array([corner, corner + 64])
        block = extract_subvol(output_vol, block_box)
        assert (block == row.segment_id).sum() == row.count