From a464356dc5779644a062627794d5681a23baf35f Mon Sep 17 00:00:00 2001 From: Anna Grim <108307071+anna-grim@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:19:26 -0800 Subject: [PATCH] bug: read swc files with permuted node ids (#56) Co-authored-by: anna-grim --- src/deep_neurographs/neurograph.py | 1 - src/deep_neurographs/swc_utils.py | 60 ++++++++++++++---------------- src/deep_neurographs/utils.py | 29 +-------------- 3 files changed, 29 insertions(+), 61 deletions(-) diff --git a/src/deep_neurographs/neurograph.py b/src/deep_neurographs/neurograph.py index 5c6e7f2..f0ebb27 100644 --- a/src/deep_neurographs/neurograph.py +++ b/src/deep_neurographs/neurograph.py @@ -169,7 +169,6 @@ def generate_proposals( len1 = self.node_xyz_dist(leaf, xyz) len2 = self.proposal_length(edge) if len1 < len2: - print("Removing proposal:", edge) node1, node2 = tuple(edge) self.nodes[node1]["proposals"].remove(node2) self.nodes[node2]["proposals"].remove(node1) diff --git a/src/deep_neurographs/swc_utils.py b/src/deep_neurographs/swc_utils.py index 807b2ed..fd615af 100644 --- a/src/deep_neurographs/swc_utils.py +++ b/src/deep_neurographs/swc_utils.py @@ -215,13 +215,13 @@ def read_xyz(xyz, offset=[0, 0, 0]): return tuple([float(xyz[i]) + offset[i] for i in range(3)]) -def write(path, contents): +def write(path, contents, color=None): if type(contents) is list: - write_list(path, contents) + write_list(path, contents, color=color) elif type(contents) is dict: - write_dict(path, contents) + write_dict(path, contents, color=color) elif type(contents) is nx.Graph: - write_graph(path, contents) + write_graph(path, contents, color=color) else: assert True, "Unable to write {} to swc".format(type(contents)) @@ -251,34 +251,20 @@ def write_list(path, entry_list, color=None): f.write("# id, type, z, y, x, r, pid") f.write("\n") for i, entry in enumerate(entry_list): - for x in entry: - f.write(str(x) + " ") + for item in entry: + f.write(str(item) + " ") f.write("\n") def write_dict(path, swc_dict, color=None): - with open(path, "w") as f: - if color is not None: - f.write("# COLOR" + color) - else: - f.write("# id, type, x, y, z, r, pid") - f.write("\n") - shift = 1 if swc_dict["id"][0] == 0 else 0 - first = True - for i in swc_dict["id"]: - f.write(str(i + shift) + " " + str(2) + " ") - for j in range(3): - f.write(str(swc_dict["xyz"][i][j]) + " ") - pid = -1 if first else swc_dict["pid"][i] + shift - f.write(str(swc_dict["radius"][i]) + " ") - f.write(str(pid) + " ") - f.write("\n") - first = False + graph, _ = to_graph(swc_dict, set_attrs=True) + return write_graph(path, graph, color=color) -def write_graph(path, graph): +def write_graph(path, graph, color=None): """ - Makes a list of entries to be written in an swc file. + Makes a list of entries to be written in an swc file. This routine assumes + that "graph" has a single connected components. Parameters ---------- @@ -293,17 +279,27 @@ def write_graph(path, graph): List of swc file entries to be written. """ - # loop through connected components - reindex = dict() - for i, j in graph.edges: + for i, j in nx.dfs_edges(graph): + # Initialize entry list if len(reindex) < 1: - entry, reindex = make_entry(graph, i, -1, reindex) + r = set_radius(graph, i) + entry, reindex = make_entry(graph, i, -1, r, reindex) entry_list = [entry] - entry, reindex = make_entry(graph, j, reindex[i], reindex) + + # Add entry + r = set_radius(graph, j) + entry, reindex = make_entry(graph, j, reindex[i], r, reindex) entry_list.append(entry) - return entry_list + write_list(path, entry_list) + print("finished") + +def set_radius(graph, i): + try: + return graph[i]["radius"] + except: + return 2 def make_entry(graph, i, parent, r, reindex): """ @@ -326,7 +322,7 @@ def make_entry(graph, i, parent, r, reindex): reindex[i] = len(reindex) + 1 r = graph.nodes[i]["radius"] x, y, z = tuple(map(str, graph.nodes[i]["xyz"])) - return [x, y, z, r, parent], reindex + return [reindex[i], 2, x, y, z, r, parent], reindex # -- Conversions -- diff --git a/src/deep_neurographs/utils.py b/src/deep_neurographs/utils.py index 5754694..39f4f3a 100644 --- a/src/deep_neurographs/utils.py +++ b/src/deep_neurographs/utils.py @@ -429,33 +429,6 @@ def write_txt(path, contents): f.close() -# --- coordinate conversions --- -def img_to_patch(xyz, patch_centroid, patch_dims): - half_patch_dims = [patch_dims[i] // 2 for i in range(3)] - patch_coord = xyz - patch_centroid + half_patch_dims - return tuple(patch_coord.astype(int)) - - -def patch_to_img(xyz, patch_centroid, patch_dims): - half_patch_dims = [patch_dims[i] // 2 for i in range(3)] - return np.round(xyz + patch_centroid - half_patch_dims).astype(int) - - -def to_world(xyz, shift=[0, 0, 0]): - return tuple([xyz[i] * ANISOTROPY[i] - shift[i] for i in range(3)]) - - -def to_img(xyz): - return (xyz / ANISOTROPY).astype(int) - - -def apply_anisotropy(xyz, return_int=False): - if return_int: - return - else: - return xyz / ANISOTROPY - - # --- math utils --- def get_avg_std(data, weights=None): avg = np.average(data, weights=weights) @@ -477,7 +450,7 @@ def get_img_bbox(origin, shape): """ if origin and shape: origin = np.array(origin) - shape = np.array(shape) # for i in [2, 1, 0]]) + shape = np.array(shape) return {"min": origin, "max": origin + shape} else: return None