def provide(self, request):

        timing = Timing(self)
        timing.start()

        batch = Batch()

        for key, spec in request.items():
            logger.debug(f"fetching {key} in roi {spec.roi}")
            requested_graph = self.graph_provider.get_graph(
                spec.roi,
                edge_inclusion="either",
                node_inclusion="dangling",
                node_attrs=self.node_attrs,
                edge_attrs=self.edge_attrs,
                nodes_filter=self.nodes_filter,
                edges_filter=self.edges_filter,
            )
            logger.debug(
                f"got {len(requested_graph.nodes)} nodes and {len(requested_graph.edges)} edges"
            )
            for node, attrs in list(requested_graph.nodes.items()):
                if self.dist_attribute in attrs:
                    if attrs[self.dist_attribute] < self.min_dist:
                        requested_graph.remove_node(node)

            logger.debug(
                f"{len(requested_graph.nodes)} nodes remaining after filtering by distance"
            )

            if len(requested_graph.nodes) > self.num_nodes:
                nodes = list(requested_graph.nodes)
                nodes_to_keep = set(random.sample(nodes, self.num_nodes))

                for node in list(requested_graph.nodes()):
                    if node not in nodes_to_keep:
                        requested_graph.remove_node(node)

            for node, attrs in requested_graph.nodes.items():
                attrs["location"] = np.array(attrs[self.position_attribute],
                                             dtype=np.float32)
                attrs["id"] = node

            if spec.directed:
                requested_graph = requested_graph.to_directed()
            else:
                requested_graph = requested_graph.to_undirected()

            logger.debug(
                f"providing {key} with {len(requested_graph.nodes)} nodes and {len(requested_graph.edges)} edges"
            )

            points = Graph.from_nx_graph(requested_graph, spec)
            points.crop(spec.roi)
            batch[key] = points

        timing.stop()
        batch.profiling_stats.add(timing)

        return batch
    def provide(self, request):

        timing = Timing(self)
        timing.start()

        batch = Batch()

        for key, spec in request.items():
            logger.debug(f"fetching {key} in roi {spec.roi}")
            requested_graph = self.graph_provider.get_graph(
                spec.roi,
                edge_inclusion=self.edge_inclusion,
                node_inclusion=self.node_inclusion,
                node_attrs=self.node_attrs,
                edge_attrs=self.edge_attrs,
                nodes_filter=self.nodes_filter,
                edges_filter=self.edges_filter,
            )
            logger.debug(
                f"got {len(requested_graph.nodes)} nodes and {len(requested_graph.edges)} edges"
            )

            failed_nodes = []

            for node, attrs in requested_graph.nodes.items():
                try:
                    attrs["location"] = np.array(
                        attrs[self.position_attribute], dtype=np.float32)
                except KeyError:
                    logger.warning(
                        f"node: {node} was written (probably part of an edge), but never given coordinates!"
                    )
                    failed_nodes.append(node)
                attrs["id"] = node

            for node in failed_nodes:
                if self.fail_on_inconsistent_node:
                    raise ValueError(
                        f"Mongodb contains node {node} without location! "
                        f"It was probably written as part of an edge")
                requested_graph.remove_node(node)

            if spec.directed:
                requested_graph = requested_graph.to_directed()
            else:
                requested_graph = requested_graph.to_undirected()

            points = Graph.from_nx_graph(requested_graph, spec)
            points.relabel_connected_components()
            points.crop(spec.roi)
            batch[key] = points

            logger.debug(f"{key} with {len(list(points.nodes))} nodes")

        timing.stop()
        batch.profiling_stats.add(timing)

        return batch
Beispiel #3
0
    def downsample(self, graph, sample_distance):
        g = graph.to_nx_graph()
        sampled_nodes = [n for n in g.nodes if g.degree(n) != 2]
        chain_nodes = [n for n in g.nodes if g.degree(n) == 2]
        chain_g = g.subgraph(chain_nodes)
        for cc in nx.connected_components(chain_g):

            if len(cc) < 2:
                continue
            cc_graph = chain_g.subgraph(cc)
            try:
                head, tail = [n for n in cc_graph.nodes if cc_graph.degree(n) == 1]
            except:
                head = list(cc_graph.nodes)[0]
                tail = head
            cable_len = 0
            previous_location = None
            for node in nx.algorithms.dfs_preorder_nodes(cc_graph, source=head):
                current_loc = cc_graph.nodes[node]["location"]
                if previous_location is not None:
                    diff = abs(previous_location - current_loc)
                    dist = np.linalg.norm(diff)
                    cable_len += dist

                previous_location = current_loc
                if node == tail:
                    break

            num_cuts = cable_len // self.sample_distance
            if num_cuts > 0:
                every = cable_len / (num_cuts + 1)
            else:
                every = float("inf")
            seen_cable = 0
            previous_location = None
            for node in nx.algorithms.dfs_preorder_nodes(cc_graph, source=head):
                current_loc = cc_graph.nodes[node]["location"]
                if previous_location is not None:
                    seen_cable += np.linalg.norm(previous_location - current_loc)
                previous_location = current_loc

                if seen_cable > every:
                    sampled_nodes.append(node)
                    seen_cable -= every

                if node == tail:
                    break
        downsampled = g.subgraph(sampled_nodes)
        return Graph.from_nx_graph(downsampled, graph.spec)