def run_inference(input_file, input_key, output_file, output_key, checkpoint,
                  n_gpus):

    out_blocks = (65, 675, 675)
    chunks = (1, ) + out_blocks

    with h5py.File(input_file) as f:
        shape = f[input_key].shape
    aff_shape = (3, ) + shape

    f = z5py.N5File(output_file)
    f.require_dataset(output_key,
                      shape=aff_shape,
                      chunks=chunks,
                      compression='gzip',
                      dtype='uint8')

    get_offset_lists(shape,
                     list(range(n_gpus)),
                     './offsets',
                     output_shape=out_blocks)

    with futures.ProcessPoolExecutor(n_gpus) as pp:
        tasks = [
            pp.submit(single_inference, input_file, input_key, output_file,
                      output_key, checkpoint, gpu_id)
            for gpu_id in range(n_gpus)
        ]
        [t.result() for t in tasks]

    evaluate_bench()
def solve_subproblems(job_id, config_path):

    fu.log("start processing job %i" % job_id)
    fu.log("reading config from %s" % config_path)

    # get the config
    with open(config_path) as f:
        config = json.load(f)
    # input configs
    problem_path = config['problem_path']
    scale = config['scale']
    block_shape = config['block_shape']
    block_list = config['block_list']
    n_threads = config['threads_per_job']
    agglomerator_key = config['agglomerator']
    time_limit = config.get('time_limit_solver', None)

    fu.log("reading problem from %s" % problem_path)
    problem = z5py.N5File(problem_path)
    shape = problem.attrs['shape']

    # load the costs
    costs_key = 's%i/costs' % scale
    fu.log("reading costs from path in problem: %s" % costs_key)
    ds = problem[costs_key]
    ds.n_threads = n_threads
    costs = ds[:]

    # load the graph
    graph_key = 's%i/graph' % scale
    fu.log("reading graph from path in problem: %s" % graph_key)
    graph = ndist.Graph(os.path.join(problem_path, graph_key),
                        numberOfThreads=n_threads)
    uv_ids = graph.uvIds()
    # check if the problem has an ignore-label
    ignore_label = problem[graph_key].attrs['ignoreLabel']
    fu.log("ignore label is %s" % ('true' if ignore_label else 'false'))

    fu.log("using agglomerator %s" % agglomerator_key)
    agglomerator = su.key_to_agglomerator(agglomerator_key)

    # the output group
    out = problem['s%i/sub_results' % scale]

    # TODO this should be a n5 varlen dataset as well and
    # then this is just another dataset in problem path
    block_prefix = os.path.join(problem_path, 's%i' % scale, 'sub_graphs',
                                'block_')
    blocking = nt.blocking([0, 0, 0], shape, list(block_shape))

    with futures.ThreadPoolExecutor(n_threads) as tp:
        tasks = [
            tp.submit(_solve_block_problem, block_id, graph, uv_ids,
                      block_prefix, costs, agglomerator, ignore_label,
                      blocking, out, time_limit) for block_id in block_list
        ]
        [t.result() for t in tasks]

    fu.log_job_success(job_id)
Exemplo n.º 3
0
def sub_solutions(job_id, config_path):

    fu.log("start processing job %i" % job_id)
    fu.log("reading config from %s" % config_path)

    # get the config
    with open(config_path) as f:
        config = json.load(f)
    # input configs
    problem_path = config['problem_path']
    scale = config['scale']
    block_shape = config['block_shape']
    block_list = config['block_list']
    n_threads = config['threads_per_job']
    output_path = config['output_path']
    output_key = config['output_key']
    ws_path = config['ws_path']
    ws_key = config['ws_key']

    sub_result_identifer = config.get('sub_result_identifier', 'sub_results')
    sub_graph_identifer = config.get('sub_graph_identifier', 'sub_graphs')

    fu.log("reading problem from %s" % problem_path)
    problem = z5py.N5File(problem_path)
    shape = problem.attrs['shape']

    blocking = nt.blocking([0, 0, 0], list(shape), list(block_shape))

    # we need to project the ws labels back to the original labeling
    # for this, we first need to load the initial node labeling
    if scale > 1:
        node_label_key = 's%i/node_labeling' % scale
        fu.log("scale %i > 1; reading node labeling from %s" % (scale, node_label_key))
        ds_node_labeling = problem[node_label_key]
        ds_node_labeling.n_threads = n_threasd
        initial_node_labeling = ds_node_labeling[:]
    else:
        initial_node_labeling = None

    # read the sub results
    ds_results = problem['s%i/%s/node_result' % (scale, sub_result_identifier)]
    # TODO should be varlen dataset
    fu.log("reading subresults")
    block_node_prefix = os.path.join(problem_path, 's%i' % scale, sub_graph_identifier, 'block_')
    block_list, block_results = _read_subresults(ds_results, block_node_prefix, blocking,
                                                 block_list, n_threads, initial_node_labeling)

    fu.log("writing subresults")
    # write the resulting segmentation
    with vu.file_reader(output_path) as f_out, vu.file_reader(ws_path, 'r') as f_in:
        ds_in = f_in[ws_key]
        ds_out = f_out[output_key]
        with futures.ThreadPoolExecutor(n_threads) as tp:
            tasks = [tp.submit(_write_block_res, ds_in, ds_out,
                               block_id, blocking, block_res)
                     for block_id, block_res in zip(block_list, block_results)]
            [t.result() for t in tasks]
    fu.log_job_success(job_id)
Exemplo n.º 4
0
def solve_subproblems(job_id, config_path):

    fu.log("start processing job %i" % job_id)
    fu.log("reading config from %s" % config_path)

    # get the config
    with open(config_path) as f:
        config = json.load(f)
    # input configs
    problem_path = config['problem_path']
    scale = config['scale']
    block_shape = config['block_shape']
    block_list = config['block_list']
    n_threads = config['threads_per_job']
    agglomerator_key = config['agglomerator']
    time_limit = config.get('time_limit_solver', None)

    fu.log("reading problem from %s" % problem_path)
    problem = z5py.N5File(problem_path)
    shape = problem['s0/graph'].attrs['shape']

    # load the costs
    costs_key = 's%i/costs' % scale
    fu.log("reading costs from path in problem: %s" % costs_key)
    ds = problem[costs_key]
    ds.n_threads = n_threads
    costs = ds[:]

    # load the graph
    graph_key = 's%i/graph' % scale
    fu.log("reading graph from path in problem: %s" % graph_key)
    graph = ndist.Graph(problem_path, graph_key, numberOfThreads=n_threads)
    uv_ids = graph.uvIds()
    # check if the problem has an ignore-label
    ignore_label = problem[graph_key].attrs['ignore_label']
    fu.log("ignore label is %s" % ('true' if ignore_label else 'false'))

    fu.log("using solver %s" % agglomerator_key)
    solver = get_multicut_solver(agglomerator_key)

    # the output group
    out = problem['s%i/sub_results' % scale]

    node_ds_key = 's%i/sub_graphs/nodes' % scale
    ds_nodes = problem[node_ds_key]

    blocking = nt.blocking([0, 0, 0], shape, list(block_shape))

    with futures.ThreadPoolExecutor(n_threads) as tp:
        tasks = [
            tp.submit(_solve_block_problem, block_id, graph, uv_ids, ds_nodes,
                      costs, solver, ignore_label, blocking, out, time_limit)
            for block_id in block_list
        ]
        [t.result() for t in tasks]

    fu.log_job_success(job_id)
    def test_2d_vigra_along_z(self):
        """Test if 2d files generated through vigra are recognized correctly"""
        # Prepare some data set for this case
        data = numpy.random.randint(0, 255,
                                    (20, 100, 200, 3)).astype(numpy.uint8)
        axistags = vigra.defaultAxistags("yxc")
        expected_axistags = vigra.defaultAxistags("zyxc")

        h5_op = OpStreamingH5N5SequenceReaderM(graph=self.graph)
        n5_op = OpStreamingH5N5SequenceReaderM(graph=self.graph)

        tempdir = tempfile.TemporaryDirectory()
        try:
            for sliceIndex, zSlice in enumerate(data):
                testDataH5FileName = f"{tempdir.name}/test-{sliceIndex:02d}.h5"
                testDataN5FileName = f"{tempdir.name}/test-{sliceIndex:02d}.n5"
                # Write the dataset to an hdf5 and a n5 file
                # (Note: Don't use vigra to do this, which may reorder the axes)
                h5File = h5py.File(testDataH5FileName)
                n5File = z5py.N5File(testDataN5FileName)
                try:
                    h5File.create_group("volume")
                    n5File.create_group("volume")

                    h5File["volume"].create_dataset("subvolume", data=zSlice)
                    n5File["volume"].create_dataset("subvolume", data=zSlice)
                    # Write the axistags attribute
                    current_path = "volume/subvolume"
                    h5File[current_path].attrs["axistags"] = axistags.toJSON()
                    n5File[current_path].attrs["axistags"] = axistags.toJSON()
                finally:
                    h5File.close()
                    n5File.close()

            # Read the data with an operator
            hdf5GlobString = f"{tempdir.name}/test-*.h5/volume/subvolume"
            n5GlobString = f"{tempdir.name}/test-*.n5/volume/subvolume"
            h5_op.SequenceAxis.setValue("z")
            n5_op.SequenceAxis.setValue("z")
            h5_op.GlobString.setValue(hdf5GlobString)
            n5_op.GlobString.setValue(n5GlobString)

            assert h5_op.OutputImage.ready()
            assert n5_op.OutputImage.ready()
            assert h5_op.OutputImage.meta.axistags == expected_axistags
            assert n5_op.OutputImage.meta.axistags == expected_axistags
            numpy.testing.assert_array_equal(
                h5_op.OutputImage.value[5:10, 50:100, 100:150],
                data[5:10, 50:100, 100:150])
            numpy.testing.assert_array_equal(
                n5_op.OutputImage.value[5:10, 50:100, 100:150],
                data[5:10, 50:100, 100:150])
        finally:
            h5_op.cleanUp()
            n5_op.cleanUp()
    def test_3d_vigra_along_t(self):
        """Test if 3d volumes generated through vigra are recognized correctly"""
        # Prepare some data set for this case
        data = numpy.random.randint(0, 255,
                                    (10, 15, 50, 100, 3)).astype(numpy.uint8)

        axistags = vigra.defaultAxistags("zyxc")
        expected_axistags = vigra.defaultAxistags("tzyxc")

        h5_op = OpStreamingH5N5SequenceReaderS(graph=self.graph)
        n5_op = OpStreamingH5N5SequenceReaderS(graph=self.graph)

        try:
            testDataH5FileName = f"{self.tempdir_normalized_name}/test.h5"
            testDataN5FileName = f"{self.tempdir_normalized_name}/test.n5"
            # Write the dataset to an hdf5 file
            # (Note: Don't use vigra to do this, which may reorder the axes)
            h5File = h5py.File(testDataH5FileName)
            n5File = z5py.N5File(testDataN5FileName)

            try:
                h5File.create_group("volumes")
                n5File.create_group("volumes")

                internalPathString = "subvolume-{sliceIndex:02d}"
                for sliceIndex, tSlice in enumerate(data):
                    subpath = internalPathString.format(sliceIndex=sliceIndex)
                    h5File["volumes"].create_dataset(subpath, data=tSlice)
                    n5File["volumes"].create_dataset(subpath, data=tSlice)
                    # Write the axistags attribute
                    current_path = "volumes/{}".format(subpath)
                    h5File[current_path].attrs["axistags"] = axistags.toJSON()
                    n5File[current_path].attrs["axistags"] = axistags.toJSON()
            finally:
                h5File.close()
                n5File.close()

            # Read the data with an operator
            hdf5GlobString = f"{testDataH5FileName}/volumes/subvolume-*"
            n5GlobString = f"{testDataN5FileName}/volumes/subvolume-*"
            h5_op.SequenceAxis.setValue("t")
            n5_op.SequenceAxis.setValue("t")
            h5_op.GlobString.setValue(hdf5GlobString)
            n5_op.GlobString.setValue(n5GlobString)

            assert h5_op.OutputImage.ready()
            assert n5_op.OutputImage.ready()
            assert h5_op.OutputImage.meta.axistags == expected_axistags
            assert n5_op.OutputImage.meta.axistags == expected_axistags
            numpy.testing.assert_array_equal(h5_op.OutputImage.value, data)
            numpy.testing.assert_array_equal(n5_op.OutputImage.value, data)
        finally:
            h5_op.cleanUp()
            n5_op.cleanUp()
Exemplo n.º 7
0
 def get_h5_n5_file(filepath, mode="a"):
     """
     returns, depending on the file-extension of filepath, either a hdf5 or a N5 file defined by filepath
     If the file is created when it does not exist depends on mode and on the function z5py.N5File/h5py.File.
     default mode = 'a':  Read/write if exists, create otherwise
     """
     name, ext = os.path.splitext(filepath)
     if ext in OpStreamingH5N5Reader.N5EXTS:
         return z5py.N5File(filepath, mode)
     elif ext in OpStreamingH5N5Reader.H5EXTS:
         return h5py.File(filepath, mode)
Exemplo n.º 8
0
    def test_Writer(self):
        # Create the h5 file
        hdf5File = h5py.File(self.testDataH5FileName)
        n5File = z5py.N5File(self.testDataN5FileName)

        opPiper = OpArrayPiper(graph=self.graph)
        opPiper.Input.setValue(self.testData)

        h5_opWriter = OpH5N5WriterBigDataset(graph=self.graph)
        n5_opWriter = OpH5N5WriterBigDataset(graph=self.graph)
        h5_opWriter.h5N5File.setValue(hdf5File)
        n5_opWriter.h5N5File.setValue(n5File)
        h5_opWriter.h5N5Path.setValue(self.datasetInternalPath)
        n5_opWriter.h5N5Path.setValue(self.datasetInternalPath)
        h5_opWriter.Image.connect(opPiper.Output)
        n5_opWriter.Image.connect(opPiper.Output)

        # Force the operator to execute by asking for the output (a bool)
        h5_success = h5_opWriter.WriteImage.value
        n5_success = n5_opWriter.WriteImage.value

        assert h5_success
        assert n5_success

        hdf5File.close()
        n5File.close()

        # Check the file.
        hdf5File = h5py.File(self.testDataH5FileName, "r")
        n5File = z5py.N5File(self.testDataN5FileName, "r")
        h5_dataset = hdf5File[self.datasetInternalPath]
        n5_dataset = n5File[self.datasetInternalPath]
        assert h5_dataset.shape == self.dataShape
        assert n5_dataset.shape == self.dataShape
        assert (numpy.all(
            h5_dataset[...] == self.testData.view(numpy.ndarray)[...])).all()
        assert (numpy.all(
            n5_dataset[...] == self.testData.view(numpy.ndarray)[...])).all()
        hdf5File.close()
        n5File.close()
Exemplo n.º 9
0
    def getPossibleInternalPathsFor(cls, file_path: Path, min_ndim=2, max_ndim=5) -> List[str]:
        datasetNames = []

        def accumulateInternalPaths(name, val):
            if isinstance(val, (h5py.Dataset, z5py.dataset.Dataset)) and min_ndim <= len(val.shape) <= max_ndim:
                datasetNames.append("/" + name)

        if cls.pathIsHdf5(file_path):
            with h5py.File(file_path, "r") as f:
                f.visititems(accumulateInternalPaths)
        elif cls.pathIsN5(file_path):
            with z5py.N5File(file_path, mode="r+") as f:
                f.visititems(accumulateInternalPaths)

        return datasetNames
Exemplo n.º 10
0
    def test_Writer(self):
        # Create the h5 file
        hdf5File = h5py.File(self.testDataH5FileName)
        n5File = z5py.N5File(self.testDataN5FileName)

        opPiper = OpArrayPiper(graph=self.graph)
        opPiper.Input.setValue(self.testData)

        # Force extra metadata onto the output
        opPiper.Output.meta.ideal_blockshape = (1, 1, 0, 0, 1)
        # Pretend the RAM usage will be really high to force lots of tiny blocks
        opPiper.Output.meta.ram_usage_per_requested_pixel = 1000000.0

        h5_opWriter = OpH5N5WriterBigDataset(graph=self.graph)
        n5_opWriter = OpH5N5WriterBigDataset(graph=self.graph)

        # This checks that you can give a preexisting group as the file
        h5_g = hdf5File.create_group("volume")
        n5_g = n5File.create_group("volume")
        h5_opWriter.h5N5File.setValue(h5_g)
        n5_opWriter.h5N5File.setValue(n5_g)
        h5_opWriter.h5N5Path.setValue("data")
        n5_opWriter.h5N5Path.setValue("data")
        h5_opWriter.Image.connect(opPiper.Output)
        n5_opWriter.Image.connect(opPiper.Output)

        # Force the operator to execute by asking for the output (a bool)
        h5_success = h5_opWriter.WriteImage.value
        n5_success = n5_opWriter.WriteImage.value
        assert h5_success
        assert n5_success

        hdf5File.close()
        n5File.close()

        # Check the file.
        hdf5File = h5py.File(self.testDataH5FileName, "r")
        n5File = h5py.File(self.testDataH5FileName, "r")
        h5_dataset = hdf5File[self.datasetInternalPath]
        n5_dataset = n5File[self.datasetInternalPath]
        assert h5_dataset.shape == self.dataShape
        assert n5_dataset.shape == self.dataShape
        assert (numpy.all(
            h5_dataset[...] == self.testData.view(numpy.ndarray)[...])).all()
        assert (numpy.all(
            n5_dataset[...] == self.testData.view(numpy.ndarray)[...])).all()
        hdf5File.close()
        n5File.close()
Exemplo n.º 11
0
    def getPossibleN5InternalPaths(cls, absPath, min_ndim=2, max_ndim=5):
        """
        Returns the name of all datasets in the file with at least 2 axes.
        """
        datasetNames = []
        # Open the file as a read-only so we can get a list of the internal paths
        with z5py.N5File(absPath, mode='r+') as f:

            def accumulate_names(path, val):
                if isinstance(val, z5py.dataset.Dataset) and min_ndim <= len(
                        val.shape) <= max_ndim:
                    name = path.replace(absPath,
                                        '')  # Need only the internal path here
                    datasetNames.append(name)

        f.visititems(accumulate_names)
        return datasetNames
Exemplo n.º 12
0
    def __init__(self, n5_path, ds_path, offset_px=N5_OFFSET):
        """

        Parameters
        ----------
        n5_path
        ds_path
        offset_px
            N5 dataset offset compared to the canonical JPEG image stack. Default (0, -1, 0)
        """

        self.offset_px = offset_px or (0, 0, 0)

        self.n5_path = n5_path
        self.ds_path = ds_path
        self.n5_file = z5py.N5File(self.n5_path, mode='r')
        self.n5_ds = self.n5_file[self.ds_path]
Exemplo n.º 13
0
 def globInternalPaths(cls, file_path: str, glob_str: str, cwd: str = None) -> List[str]:
     glob_str = glob_str.lstrip("/")
     internal_paths = set()
     for path in cls.expand_path(file_path, cwd=cwd):
         f = None
         try:
             if cls.pathIsNpz(path):
                 internal_paths |= set(globNpz(path, glob_str))
                 continue
             elif cls.pathIsHdf5(path):
                 f = h5py.File(path, "r")
             elif cls.pathIsN5(path):
                 f = z5py.N5File(path)  # FIXME
             else:
                 raise Exception(f"{path} is not an 'n5' or 'h5' file")
             internal_paths |= set(globH5N5(f, glob_str))
         finally:
             if f is not None:
                 f.close()
     return sorted(internal_paths)
    def test_expandGlobStrings(self):
        expected_datasets = ["g1/g2/data2", "g1/g2/data3"]

        h5_file_name = f"{self.tempdir_normalized_name}/test.h5"
        n5_file_name = f"{self.tempdir_normalized_name}/test.n5"
        try:
            h5_file = h5py.File(h5_file_name, mode="w")
            n5_file = z5py.N5File(n5_file_name, mode="w")
            h5_g1 = h5_file.create_group("g1")
            n5_g1 = n5_file.create_group("g1")
            h5_g2 = h5_g1.create_group("g2")
            n5_g2 = n5_g1.create_group("g2")
            h5_g3 = h5_file.create_group("g3")
            n5_g3 = n5_file.create_group("g3")
            h5_g1.create_dataset("data1", data=numpy.ones((10, 10)))
            n5_g1.create_dataset("data1", data=numpy.ones((10, 10)))
            h5_g2.create_dataset("data2", data=numpy.ones((10, 10)))
            n5_g2.create_dataset("data2", data=numpy.ones((10, 10)))
            h5_g2.create_dataset("data3", data=numpy.ones((10, 10)))
            n5_g2.create_dataset("data3", data=numpy.ones((10, 10)))
            h5_g3.create_dataset("data4", data=numpy.ones((10, 10)))
            n5_g3.create_dataset("data4", data=numpy.ones((10, 10)))
            h5_file.flush()

            h5_glob_res1 = OpStreamingH5N5SequenceReaderS.expandGlobStrings(
                h5_file, f"{h5_file_name}/g1/g2/data*")
            n5_glob_res1 = OpStreamingH5N5SequenceReaderS.expandGlobStrings(
                n5_file, f"{n5_file_name}/g1/g2/data*")
            self.assertEqual(h5_glob_res1, expected_datasets)
            self.assertEqual(n5_glob_res1, expected_datasets)

        finally:
            h5_file.close()
            n5_file.close()

        h5_glob_res2 = OpStreamingH5N5SequenceReaderS.expandGlobStrings(
            h5_file_name, f"{h5_file_name}/g1/g2/data*")
        n5_glob_res2 = OpStreamingH5N5SequenceReaderS.expandGlobStrings(
            n5_file_name, f"{n5_file_name}/g1/g2/data*")
        self.assertEqual(h5_glob_res2, expected_datasets)
        self.assertEqual(n5_glob_res2, expected_datasets)
Exemplo n.º 15
0
Arquivo: test_file.py Projeto: hobu/z5
 def test_direct_constructor(self):
     self.assertFalse(os.path.exists(self.path))
     f = z5py.N5File(self.path)
     self.assertFalse(f.is_zarr)
Exemplo n.º 16
0
def solve_lifted_subproblems(job_id, config_path):

    fu.log("start processing job %i" % job_id)
    fu.log("reading config from %s" % config_path)

    # get the config
    with open(config_path) as f:
        config = json.load(f)
    # input configs
    problem_path = config['problem_path']
    scale = config['scale']
    block_shape = config['block_shape']
    block_list = config['block_list']

    lifted_prefix = config['lifted_prefix']
    agglomerator_key = config['agglomerator']
    time_limit = config.get('time_limit_solver', None)
    n_threads = config.get('threads_per_job', 1)

    fu.log("reading problem from %s" % problem_path)
    problem = z5py.N5File(problem_path)
    shape = problem.attrs['shape']

    # load the costs
    # NOTE we use different cost identifiers for multicut and lifted multicut
    # in order to run both in the same n5-container.
    # However, for scale level 0 the costs come from the CostsWorkflow and
    # hence the identifier is identical
    costs_key = 's%i/costs_lmc' % scale if scale > 0 else 's0/costs'
    fu.log("reading costs from path in problem: %s" % costs_key)
    ds = problem[costs_key]
    ds.n_threads = n_threads
    costs = ds[:]

    # load the graph
    # NOTE we use different graph identifiers for multicut and lifted multicut
    # in order to run both in the same n5-container.
    # However, for scale level 0 the graph comes from the GraphWorkflow and
    # hence the identifier is identical
    graph_key = 's%i/graph_lmc' % scale if scale > 0 else 's0/graph'
    fu.log("reading graph from path in problem: %s" % graph_key)
    graph = ndist.Graph(os.path.join(problem_path, graph_key),
                        numberOfThreads=n_threads)
    uv_ids = graph.uvIds()
    # check if the problem has an ignore-label
    ignore_label = problem[graph_key].attrs['ignoreLabel']
    fu.log("ignore label is %s" % ('true' if ignore_label else 'false'))

    fu.log("using agglomerator %s" % agglomerator_key)
    lifted_agglomerator = su.key_to_lifted_agglomerator(agglomerator_key)
    # TODO enable different multicut agglomerator
    agglomerator = su.key_to_agglomerator(agglomerator_key)

    # load the lifted edges and costs
    nh_key = 's%i/lifted_nh_%s' % (scale, lifted_prefix)
    lifted_costs_key = 's%i/lifted_costs_%s' % (scale, lifted_prefix)
    ds = problem[nh_key]
    fu.log("reading lifted uvs")
    ds.n_threads = n_threads
    lifted_uvs = ds[:]

    fu.log("reading lifted costs")
    ds = problem[lifted_costs_key]
    ds.n_threads = n_threads
    lifted_costs = ds[:]

    # the output group
    out = problem['s%i/sub_results_lmc' % scale]

    # NOTE we use different sub-graph identifiers for multicut and lifted multicut
    # in order to run both in the same n5-container.
    # However, for scale level 0 the sub-graphs come from the GraphWorkflow and
    # are hence identical
    sub_graph_identifier = 'sub_graphs' if scale == 0 else 'sub_graphs_lmc'
    block_prefix = os.path.join(problem_path, 's%i' % scale,
                                sub_graph_identifier, 'block_')
    blocking = nt.blocking([0, 0, 0], shape, list(block_shape))

    fu.log("start processsing %i blocks" % len(block_list))
    with futures.ThreadPoolExecutor(n_threads) as tp:
        tasks = [
            tp.submit(_solve_block_problem, block_id, graph, uv_ids,
                      block_prefix, costs, lifted_uvs, lifted_costs,
                      lifted_agglomerator, agglomerator, ignore_label,
                      blocking, out, time_limit) for block_id in block_list
        ]
        [t.result() for t in tasks]

    fu.log_job_success(job_id)
Exemplo n.º 17
0
def _accumulate_block(block_id, blocking, ds_in, ds_labels, out_prefix,
                      graph_block_prefix, filters, sigmas, halo, ignore_label,
                      apply_in_2d, channel_agglomeration):

    fu.log("start processing block %i" % block_id)
    # load graph and check if this block has edges
    graph = ndist.Graph(graph_block_prefix + str(block_id))
    if graph.numberOfEdges == 0:
        fu.log("block %i has no edges" % block_id)
        fu.log_block_success(block_id)
        return

    shape = ds_labels.shape
    # get the bounding
    if sum(halo) > 0:
        block = blocking.getBlockWithHalo(block_id, halo)
        block_shape = block.outerBlock.shape
        bb_in = vu.block_to_bb(block.outerBlock)
        bb = vu.block_to_bb(block.innerBlock)
        bb_local = vu.block_to_bb(block.innerBlockLocal)
        # increase inner bounding box by 1 in posirive direction
        # in accordance with the graph extraction
        bb = tuple(
            slice(b.start, min(b.stop + 1, sh)) for b, sh in zip(bb, shape))
        bb_local = tuple(
            slice(b.start, min(b.stop + 1, bsh))
            for b, bsh in zip(bb_local, block_shape))
    else:
        block = blocking.getBlock(block_id)
        bb = vu.block_to_bb(block)
        bb = tuple(
            slice(b.start, min(b.stop + 1, sh)) for b, sh in zip(bb, shape))
        bb_in = bb
        bb_local = slice(None)

    input_dim = ds_in.ndim
    # TODO make choice of channels optional
    if input_dim == 4:
        bb_in = (slice(0, 3), ) + bb_in

    input_ = vu.normalize(ds_in[bb_in])
    if input_dim == 4:
        assert channel_agglomeration is not None
        input_ = getattr(np, channel_agglomeration)(input_, axis=0)

    # load labels
    labels = ds_labels[bb]

    # TODO pre-smoothing ?!
    # accumulate the edge features
    edge_features = [
        _accumulate_filter(input_, graph, labels, bb_local, filter_name, sigma,
                           ignore_label, filter_name == filters[-1]
                           and sigma == sigmas[-1], apply_in_2d)
        for filter_name in filters for sigma in sigmas
    ]
    edge_features = np.concatenate(edge_features, axis=1)

    # save the features
    save_path = out_prefix + str(block_id)
    fu.log("saving feature result of shape %s to %s" %
           (str(edge_features.shape), save_path))
    save_root, save_key = os.path.split(save_path)
    with z5py.N5File(save_root) as f:
        f.create_dataset(save_key,
                         data=edge_features,
                         chunks=edge_features.shape)

    fu.log_block_success(block_id)