Example #1
0
def main():
    """ Executes all methods given above in the correct order
    """
    # |>-<-><-><-><-><-><-><-<|
    # |>- Process arguments -<|
    # |>-<-><-><-><-><-><-><-<|

    output_data_path, input_data_path = get_data_paths_from_args()
    patient = input_data_path.name

    print(f"\nstage-07 current patient: {patient}\n")

    # |>-<-><-><-><->-<|
    # |>- Load graph -<|
    # |>-<-><-><-><->-<|

    graph = load_graph(input_data_path / "tree.graphml")

    # |>-<-><-><-><-><-<|
    # |>- Write lobes -<|
    # |>-<-><-><-><-><-<|

    if not output_data_path.exists():
        output_data_path.mkdir(parents=True)
    nx.write_graphml(graph, output_data_path / "tree.graphml")

    # Store subtrees and connection statistics
    create_subtrees(graph, patient, output_data_path)
def get_inputs():
    output_data_path, tree_input_path = get_data_paths_from_args(inputs=1)
    config_path = Path("configs") / "classification.yaml"
    with open(config_path) as config_file:
        classification_config = yaml.load(config_file, yaml.FullLoader)
    tree = nx.read_graphml(tree_input_path / "tree.graphml")
    output_path = output_data_path / "tree.graphml"
    return output_path, tree, classification_config
Example #3
0
def main():
    """
    Executes procedures in right order
    """

    output_data_path, input_data_path = get_data_paths_from_args()

    lobe_graph_dict = build_connection_matrix(input_data_path)
    plot_connection_status(output_data_path / 'connection-status.png',
                           lobe_graph_dict)
Example #4
0
def main():
    output_data_path, input_data_path = get_data_paths_from_args()
    data = read_metadata(input_data_path)
    formatted_data = reformat_data(data)
    first_row = True
    for patient in formatted_data:
        print('| ', ' | '.join(patient), ' |', sep='')
        if first_row:
            print("|:----" * len(patient), end='|\n')
            first_row = False
    write_table(output_data_path, formatted_data)
Example #5
0
def main():
    output_data_path, reduced_model_path, distance_mask_path, tree_path, = get_data_paths_from_args(
        inputs=3)
    model = np.load(reduced_model_path / "reduced_model.npz")['arr_0']
    distance_mask = np.load(distance_mask_path / "distance_mask.npz")['arr_0']
    # np_dist = np.full(model.shape, 0)
    # for (x, y, z), val in distances.items():
    #     np_dist[x, y, z] = val
    # lu_lobe = nx.read_graphml(tree_path / f"lobe-3-{tree_path.name}.graphml")
    tree = nx.read_graphml(tree_path / f"tree.graphml")
    # lu_traversing = nx.bfs_successors(lu_lobe, "5")
    color_mask = np.full(model.shape, 0)

    color_hex_codes = [color_hex_to_floats('ffffff')]

    map_node_id_to_color = {}

    nodes_visit_order = []
    first_node = list(tree.nodes)[0]
    for curr_color, (node_index, successors) in enumerate(nx.bfs_successors(
            tree, first_node),
                                                          start=1):
        node = tree.nodes[node_index]
        # point = find_legal_point(node, distances, node["group"])
        point = (round(node['x']), round(node['y']), round(node['z']))
        radius = node['group_size'] / 2
        nodes_visit_order.append((node, point, curr_color, radius))
        if 'color' in node:
            color_hex_codes.append(color_hex_to_floats(node['color']))
        elif node_index in map_node_id_to_color:
            color_hex_codes.append(
                get_color_variation(map_node_id_to_color[node_index]))
        else:
            color_hex_codes.append(color_hex_to_floats("ffffff"))
        for s in successors:
            map_node_id_to_color[s] = get_color_variation(color_hex_codes[-1])
        # fill_sphere_around_point(radius, point, model, color_mask, curr_color)
        # fill_color_mask_with_bfs(point, color_mask, curr_color, model, distance_mask)
    print(color_hex_codes)

    for node, point, curr_color, radius in reversed(nodes_visit_order):
        fill_color_mask_with_bfs(point, color_mask, curr_color, model,
                                 distance_mask, radius)

    print("Colors:")
    for color, occ in zip(*np.unique(color_mask, return_counts=True)):
        print(f"Color {color} appears {occ:,} times in color mask")
    np.savez_compressed(output_data_path / "bronchus_color_mask.npz",
                        color_mask=color_mask,
                        color_codes=np.array(color_hex_codes))
Example #6
0
def main():
    output_data_path, tree_input_data_path, reduced_model_data_path = get_data_paths_from_args(
        inputs=2)

    patient_id = tree_input_data_path.parts[-1]

    if tree_input_data_path.is_dir and output_data_path.is_dir:
        coord_file_path = tree_input_data_path / "final_coords.npz"
        edges_file_path = tree_input_data_path / "final_edges.npz"
        coord_attributes_file_path = tree_input_data_path / "coord_attributes.npz"
        edge_attributes_file_path = tree_input_data_path / "edge_attributes.npz"
    else:
        sys.exit(1)

    if not reduced_model_data_path.exists():
        print("ERROR: stage-02 needed")
        print(reduced_model_data_path)
        sys.exit(-1)

    reduced_model = np.load(reduced_model_data_path /
                            "reduced_model.npz")['arr_0']
    print(np.unique(reduced_model))
    reduced_model[reduced_model >= 7] = 0
    # Remove all voxels 7, 8 and 9 since these are veins/arteries and not useful in classification
    print(np.unique(reduced_model))

    np_coord = np.load(coord_file_path)['arr_0']
    np_edges = np.load(edges_file_path)['arr_0']
    np_coord_attributes = np.load(coord_attributes_file_path,
                                  allow_pickle=True)['arr_0']
    np_edges_attributes = np.load(edge_attributes_file_path,
                                  allow_pickle=True)['arr_0']

    # create empty graphs
    graph = nx.Graph(patient=int(patient_id))
    # compose graphs
    # assert False, "Crashes not here"
    dic_coords = create_nodes(graph, np_coord, np_coord_attributes,
                              reduced_model)
    dic_edges = create_edges(graph, np_edges, dic_coords, np_edges_attributes)

    # set levels to the graph
    graph = set_level(graph)
    # level 2 does not belong to a lobe
    graph = set_attribute_to_node(graph, ('level', 2), ('lobe', 0))

    show_stats(graph, patient_id)

    nx.write_graphml(graph, output_data_path / "tree.graphml")
Example #7
0
def main():
    output_data_path, input_data_path, reduced_model_data_path = get_data_paths_from_args(
        inputs=2)

    rot_mat = np.array([[0, 0, -1], [-1, 0, 0], [0, 1, 0]])
    model = np.load(reduced_model_data_path / 'reduced_model.npz')['arr_0']

    if not output_data_path.exists():
        output_data_path.mkdir(parents=True, exist_ok=True)

    graph = nx.read_graphml(input_data_path / "tree.graphml")
    gen_split_obj(output_data_path / "splits.obj",
                  graph,
                  rot_mat=rot_mat,
                  model_shape=model.shape)
Example #8
0
def main():
    output_data_path, input_data_path, distance_mask_path, color_mask_path = get_data_paths_from_args(
        inputs=3)

    model = np.load(input_data_path / "reduced_model.npz")['arr_0']
    print(f"Loaded model with shape {model.shape}")

    distance_mask = np.load(distance_mask_path / "distance_mask.npz")['arr_0']
    print(f"Loaded color mask with shape {distance_mask.shape}")

    bronchus_color_mask = np.load(color_mask_path /
                                  "bronchus_color_mask.npz")['color_mask']
    bronchus_color_codes = np.load(color_mask_path /
                                   "bronchus_color_mask.npz")['color_codes']
    color_codes = {i: code for i, code in enumerate(bronchus_color_codes)}
    print(color_codes)
    print(f"Loaded color mask with shape {bronchus_color_mask.shape}")

    if not output_data_path.exists():
        output_data_path.mkdir(parents=True, exist_ok=True)

    rot_mat = np.array([[0, 0, -1], [-1, 0, 0], [0, 1, 0]])

    print("Running skeletonize on model")
    # Remove lobe coordinates from model by clipping everything
    # between 0 and 2, then modulo everything by 2 to remove 2s
    skeleton = skeletonize(np.clip(model, 0, 2) % 2)
    generate_obj(output_data_path / "skeleton.obj",
                 set(),
                 skeleton,
                 rot_mat=rot_mat)
    # generate_obj(output_data_path / "bav.obj", {1, 7, 8}, model)
    generate_obj(output_data_path / "bronchus.obj", {1},
                 model,
                 color_mask=bronchus_color_mask,
                 color_to_rgb_tuple=color_codes,
                 rot_mat=rot_mat)
Example #9
0
from util.util import get_data_paths_from_args

plt.rcParams.update({'font.size': 4})

# |>--><-><-><-><-><->-<|
# |>- Parse arguments -<|
# |>--><-><-><-><-><->-<|

(
    output_data_path,
    bronchus_shell_data_path,
    map_coord_to_dist_data_path,
    final_coords_data_path,
    pre_post_processing_data_path,
    post_post_processing_data_path,
) = get_data_paths_from_args(inputs=5)

try:
    show_plot = sys.argv[7].lower() == "true"
except IndexError:
    show_plot = True

try:
    show_bronchus = sys.argv[8].lower() == "true"
except IndexError:
    show_bronchus = False

# |>-<-><-><-><-><-><->-<|
# |>- Define color map -<|
# |>-<-><-><-><-><-><->-<|
Example #10
0
""" Converts images to booleans, then saves them as numpy array
"""

import os

import numpy as np
import pydicom

from util.util import get_data_paths_from_args

# Process arguments supplied
output_data_path, input_data_path = get_data_paths_from_args()

dir_names_to_id = {
    "Bronchus": 1,
    "LeftLowerLobe": 2,
    "LeftUpperLobe": 3,
    "RightLowerLobe": 4,
    "RightMiddleLobe": 5,
    "RightUpperLobe": 6,
    "Vein": 7,
    "Artery": 8,
}


def save_images_as_npz(raw_data_path, processed_data_path):
    """Saves a 3D numpy matrix of the model to $processed_data_path

    The matrix has 0 for empty space and dir_names_to_id for each
    type given. 
    """
Example #11
0
this script now checks whenever a group splits in 2 (there is no path between them), whenever this
happens it marks this as a split and saves it later on.

After doing that it backtracks all nodes and creates all the edges. 
"""

import queue
import math
from typing import Tuple, Set

import numpy as np

from util.helper_functions import adjacent, find_radius_via_sphere
from util.util import get_data_paths_from_args

output_data_path, input_data_path, reduced_model_data_path = get_data_paths_from_args(
    inputs=2)

REDUCED_MODEL = reduced_model_data_path / "reduced_model.npz"
DISTANCE_TO_COORDS_FILE = input_data_path / "map_distance_to_coords.npz"
MAP_COORD_TO_PREVIOUS_FILE = input_data_path / "map_coord_to_previous.txt"
MAP_COORD_TO_NEXT_COUNT_FILE = input_data_path / "map_coord_to_next_count.txt"

FINAL_COORDS_FILE = output_data_path / "final_coords"
FINAL_EDGES_FILE = output_data_path / "final_edges"
EDGE_ATTRIBUTES_FILE = output_data_path / "edge_attributes"
COORD_ATTRIBUTES_FILE = output_data_path / "coord_attributes"

model = np.load(REDUCED_MODEL)['arr_0']
print(model.shape)

Example #12
0
def main():
    """ Executes all methods given above in the correct order
    """
    # |>-<-><-><-><-><-><-><-<|
    # |>- Process arguments -<|
    # |>-<-><-><-><-><-><-><-<|

    output_data_path, input_data_path = get_data_paths_from_args()

    # |>-<-><-><-><->-<|
    # |>- Load graph -<|
    # |>-<-><-><-><->-<|

    graph = load_graph(input_data_path / "tree.graphml")

    assert nx.is_tree(graph), "ERROR: Graph is not a tree!"

    # |>-><-><-><-><-><-<|
    # |>- Process tree -<|
    # |>-><-><-><-><-><-<|

    print(f"===== Node Removal =====")

    # Run each of these multiple times since they do something on each
    # iteration. Quit when nothing changes
    iteration = 0
    while True:
        node_count = graph.number_of_nodes()
        print(f"=== Iteration {iteration} ===")

        remove_minor_edges(graph)
        straighten_edges(graph)
        merge_close_nodes(graph)
        remove_children_without_children(graph)

        iteration += 1
        if node_count == graph.number_of_nodes():
            break

    # |>--><-><-><-><-><-><-><-><-><-><-><-><-><--<|
    # |>- Reset attributes from the other script -<|
    # |>--><-><-><-><-><-><-><-><-><-><-><-><-><--<|

    assign_children_count(graph)

    graph = set_level(graph)
    graph = set_attribute_to_node(graph, ('level', 2), ('lobe', 0))
    graph = set_attribute_to_node(graph, ('level', 3), ('lobe', 0))

    assert nx.is_tree(graph), "ERROR: Graph is no longer a tree!"

    # |>-<-><-><-><-><-><-><-><->-<|
    # |>- Write pre-colored tree -<|
    # |>-<-><-><-><-><-><-><-><->-<|

    print(f"===== Recoloring =====")

    if not output_data_path.exists():
        output_data_path.mkdir(parents=True, exist_ok=True)

    nx.write_graphml(graph, output_data_path / "pre-recoloring.graphml")

    # |>-<-><-><-><->-<|
    # |>- Recoloring -<|
    # |>-<-><-><-><->-<|

    for _ in range(5):
        recolor_if_all_adjacent_have_different_color(graph)
        recolor_if_successors_all_different_color(graph)

    recolor_entire_subtree_to_majority_at_level_4_or_5(graph)
    possibly_make_neutral_above_level_4(graph)
    add_new_parent_for_lobe(graph)

    # |>-<-><-><-><->-<|
    # |>- Write tree -<|
    # |>-<-><-><-><->-<|

    nx.write_graphml(graph, output_data_path / "tree.graphml")