Exemplo n.º 1
0
def validate_type_thirty_count(marker_file):
    """ This function checks whether there is exactly one type 30 in the file """

    result = []
    type_30_markers = []

    for marker in marker_file:
        if marker['name'] is TYPE_30:
            type_30_markers.append(marker)

    if len(type_30_markers) > 1:
        for marker in type_30_markers:
            result.append(
                ve(
                    "Total number of type 30s is %s" % len(type_30_markers), {
                        'x': marker['original_x'],
                        'y': marker['original_y'],
                        'z': marker['original_z'],
                        'name': marker['name']
                    }, "Warning"))
    if len(type_30_markers) < 1:
        result.append(
            ve("Total number of type 30s is %s" % len(type_30_markers), {},
               "Warning"))

    return result
Exemplo n.º 2
0
def validate_extreme_taper(morphology):
    """ This function checks whether there is an extreme taper.
        Extreme taper occurs when for each segment, the average
        radius of the first two nodes is more than two times the
        average radius of the last two nodes.
         
         Note: This test is limited to segments of at lease 8 nodes. """

    result = []

    for segment_list in morphology.segment_lists:
        for segment in segment_list:
            nodes_in_segment = segment.node_list

            if len(nodes_in_segment) > 7:
                if nodes_in_segment[0].t in [BASAL_DENDRITE, APICAL_DENDRITE]:

                    average_radius_beg = (nodes_in_segment[0].radius +
                                          nodes_in_segment[1].radius) / 2
                    average_radius_end = (nodes_in_segment[-1].radius +
                                          nodes_in_segment[-2].radius) / 2

                    if average_radius_beg > 4 * average_radius_end:
                        result.append(
                            ve(
                                "Extreme Taper: For types 3 and 4, the average radius of the first two nodes "
                                "in a segment should not be greater than four times the average radius of the "
                                "last two nodes in a segment (For segments that have more than 8 nodes)",
                                [
                                    nodes_in_segment[0].original_n,
                                    nodes_in_segment[-2].original_n
                                ], "Info"))

    return result
Exemplo n.º 3
0
def validate_constrictions(morphology):
    """ This function checks if the radius of basal dendrite and apical dendrite 
        nodes is smaller 2.0px """

    result = []

    depth = dict()
    to_visit = {morphology.soma_root()}
    while to_visit:
        node = to_visit.pop()
        if morphology.parent_of(node):
            depth[node] = depth[morphology.parent_of(node)] + 1
        else:
            depth[node] = 0
        to_visit.update(morphology.children_of(node))

    eligible_nodes = sorted(
        [node for node in depth.keys() if depth[node] < 10])
    for node in eligible_nodes:
        if node.t in [BASAL_DENDRITE, APICAL_DENDRITE]:
            if node.radius < 2.0:
                result.append(
                    ve(
                        "Constriction: The radius of types 3 and 4 should not be less than 2.0px",
                        node.original_n, "Warning"))

    return result
Exemplo n.º 4
0
def validate_expected_types(node):
    """ This function validates the expected types of the nodes """

    result = []

    if node.t not in valid_types:
        result.append(
            ve("Node type needs to be one of these values: %s" % valid_types,
               node.original_n, "Warning"))

    return result
Exemplo n.º 5
0
def validate_node_parent(morphology, node):
    """ This function validates the type of parent node for a specific type of child node """

    result = []
    valid_soma_parents = {None}
    valid_axon_parents = {SOMA, AXON, BASAL_DENDRITE, None}
    valid_basal_dendrite_parents = {SOMA, BASAL_DENDRITE}
    valid_apical_dendrite_parents = {SOMA, APICAL_DENDRITE}

    if node.t == SOMA:
        if morphology.parent_of(node):
            result.append(
                ve(
                    "Type 1 can only have a parent of the following types: %s"
                    % valid_soma_parents, node.original_n, "Warning"))
    if node.t == AXON:
        if morphology.parent_of(node):
            if morphology.parent_of(node).t not in valid_axon_parents:
                result.append(
                    ve(
                        "Type 2 can only have a parent of the following types: %s"
                        % valid_axon_parents, node.original_n, "Warning"))
    if node.t == BASAL_DENDRITE:
        parent = morphology.parent_of(node)
        if not parent or parent.t not in valid_basal_dendrite_parents:
            result.append(
                ve(
                    "Type 3 can only have a parent of the following types: %s"
                    % valid_basal_dendrite_parents, node.original_n,
                    "Warning"))
    if node.t == APICAL_DENDRITE:
        parent = morphology.parent_of(node)
        if not parent or parent.t not in valid_apical_dendrite_parents:
            result.append(
                ve(
                    "Type 4 can only have a parent of the following types: %s"
                    % valid_apical_dendrite_parents, node.original_n,
                    "Warning"))

    return result
Exemplo n.º 6
0
def validate_immediate_children_of_soma_cannot_branch(morphology, node):
    """ This function validates that immediate children of soma cannot branch """

    result = []

    if morphology.parent_of(node):
        if morphology.parent_of(node).t == SOMA:
            if len(morphology.children_of(node)) > 1:
                result.append(
                    ve("Immediate children of soma cannnot branch",
                       node.original_n, "Error"))

    return result
Exemplo n.º 7
0
def validate_children_nodes_appear_before_parent_nodes(morphology):

    result = []

    for tree in range(0, morphology.num_trees):
        for tree_node in morphology.tree(tree):
            parent = morphology.parent_of(tree_node)
            if parent and tree_node.original_n < parent.original_n:
                result.append(
                    ve("Child node needs to come before parent node",
                       tree_node.original_n, "Error"))

    return result
Exemplo n.º 8
0
def validate_node_type_radius(node):
    """ This function validates the radius for types 1, 3, and 4 """

    result = []

    soma_radius_threshold = 35
    basal_dendrite_apical_dendrite_radius_threshold = 20

    if node.t == SOMA:
        if node.radius < soma_radius_threshold:
            result.append(
                ve(
                    "The radius must be above %spx for type 1" %
                    soma_radius_threshold, node.original_n, "Info"))
    if node.t == BASAL_DENDRITE or node.t == APICAL_DENDRITE:
        if node.radius > basal_dendrite_apical_dendrite_radius_threshold:
            result.append(
                ve(
                    "The radius must be below %spx for types 3 and 4" %
                    basal_dendrite_apical_dendrite_radius_threshold,
                    node.original_n, "Info"))

    return result
Exemplo n.º 9
0
def validate_radius_has_negative_slope_dendrite(morphology, dendrite):
    """ This function checks whether the radius for dendrite nodes decreases
        when you are going away from the soma. """

    result = []

    branch_order = dict()
    to_visit = {morphology.soma_root()}

    while to_visit:
        node = to_visit.pop()
        if morphology.parent_of(node) and len(
                morphology.children_of(node)) > 1:
            branch_order[node] = branch_order[morphology.parent_of(node)] + 1
        elif morphology.parent_of(node) and len(
                morphology.children_of(node)) <= 1:
            branch_order[node] = branch_order[morphology.parent_of(node)]
        elif not morphology.parent_of(node):
            branch_order[node] = 1
        to_visit.update(morphology.children_of(node))

    dendrite_nodes_in_morphology = morphology.node_list_by_type(dendrite)
    if dendrite_nodes_in_morphology:
        nodes_by_branch_order = dict()
        for node, order in branch_order.iteritems():
            if node.t == dendrite:
                nodes_by_branch_order[order] = nodes_by_branch_order.get(
                    order, [])
                nodes_by_branch_order[order].append(node)

        orders = sorted(nodes_by_branch_order.keys())
        avg_radius = []

        for order in orders:
            nodes = nodes_by_branch_order[order]
            total_radius = 0
            for node in nodes:
                total_radius += node.radius
            avg_radius.append(total_radius / len(nodes))

        if len(orders) > 1:
            if slope_linear_regression_branch_order_avg_radius(
                    orders, avg_radius) >= 0:
                result.append(
                    ve(
                        "Radius should have a negative slope for the following type: %s"
                        % dendrite, [], "Warning"))

    return result
Exemplo n.º 10
0
def validate_distance_between_connected_nodes(morphology):

    result = []

    for comp in range(0, len(morphology.compartment_list)):
        if morphology.compartment(
                comp).node1.t is not SOMA and morphology.compartment(
                    comp).node2.t is not SOMA:
            if morphology.compartment(comp).length > 50.0:
                result.append(
                    ve(
                        "The distance between two nodes should be less than 50px",
                        [
                            morphology.compartment(comp).node1.original_n,
                            morphology.compartment(comp).node2.original_n
                        ], "Warning"))

    return result
Exemplo n.º 11
0
def validate_number_of_soma_nodes(morphology):
    """ This function validates the number of type 1 nodes """

    result = []
    matched_node_numbers = []

    for tree in range(0, morphology.num_trees):
        for node in morphology.tree(tree):
            if node.t == SOMA:
                matched_node_numbers.append(node.original_n)

    if len(matched_node_numbers) != 1:
        for node_number in matched_node_numbers:
            result.append(
                ve("The morphology needs to have one soma node", node_number,
                   "Error"))

    return result
Exemplo n.º 12
0
def validate_expected_name(marker_file):
    """ This function checks whether the markers have the expected types """

    result = []
    valid_names = [CUT_DENDRITE, NO_RECONSTRUCTION, TYPE_30]

    for marker in marker_file:
        if marker['name'] not in valid_names:
            result.append(
                ve(
                    "Marker name needs to be one of these values: %s" %
                    valid_names, {
                        'x': marker['original_x'],
                        'y': marker['original_y'],
                        'z': marker['original_z'],
                        'name': marker['name']
                    }, "Warning"))

    return result
Exemplo n.º 13
0
def validate_count_node_parent(morphology, node_type, parent_type,
                               expected_count):
    """ This function validates the number of nodes that have a specific type of parent """

    tree = morphology.tree(0)
    matched_node_numbers = []
    result = []

    for node in tree:
        if node.t == node_type and morphology.parent_of(node).t is parent_type:
            matched_node_numbers.append(node.original_n)

    if len(matched_node_numbers) > expected_count:
        for node_number in matched_node_numbers:
            result.append(
                ve(
                    "Nodes of type %s can only have %s parent of type %s" %
                    (node_type, expected_count, parent_type), node_number,
                    "Warning"))

    return result
Exemplo n.º 14
0
def validate_multiple_axon_initiation_points(morphology):
    """ This function validates that the parent of axon (either type 1 or 3) only happens once """

    tree = morphology.tree(0)
    expected_count = 1
    matched_node_numbers = []
    result = []
    for node in tree:
        if node.t == AXON:
            parent = morphology.parent_of(node)
            if parent and parent.t in [BASAL_DENDRITE, SOMA]:
                matched_node_numbers.append(node.original_n)

    if len(matched_node_numbers) > expected_count:
        for node_number in matched_node_numbers:
            result.append(
                ve(
                    "Axon can only have one parent of type basal dendrite or soma",
                    node_number, "Error"))

    return result
Exemplo n.º 15
0
def validate_coordinates_corresponding_to_dendrite_tip(marker_file,
                                                       morphology):
    """ This function checks whether the coordinates for each dendrite marker
        corresponds to a tip of a dendrite type in the related morphology """

    result = []
    marker_types = [CUT_DENDRITE]
    morphology_tip_nodes = []
    morphology_dendrite_nodes = morphology.node_list_by_type(
        BASAL_DENDRITE) + morphology.node_list_by_type(APICAL_DENDRITE)

    for node in morphology_dendrite_nodes:
        if len(morphology.children_of(node)) == 0:
            morphology_tip_nodes.append(node)

    for marker in marker_file:
        tip_marker = False
        if marker['name'] in marker_types:
            for node in morphology_tip_nodes:
                """ Subtract one from the coordinates because there is a known discrepancy between the coordinates of 
                    the marker file and the swc file
                """
                if (marker['original_x'] - 1) == node.x and (
                        marker['original_y'] -
                        1) == node.y and (marker['original_z'] - 1) == node.z:
                    tip_marker = True
            if not tip_marker:
                result.append(
                    ve(
                        "Coordinates for each dendrite (type 10) needs to correspond to a tip of a dendrite "
                        "type (type 3 or 4) in the related morphology", {
                            'x': marker['original_x'],
                            'y': marker['original_y'],
                            'z': marker['original_z'],
                            'name': marker['name']
                        }, "Info"))

    return result
Exemplo n.º 16
0
def validate_no_reconstruction_count(marker_file):
    """ This function checks whether there is exactly one type 20 in the file """

    result = []
    no_reconstruction_markers = []

    for marker in marker_file:
        if marker['name'] is NO_RECONSTRUCTION:
            no_reconstruction_markers.append(marker)

    if len(no_reconstruction_markers) > 1:
        for marker in no_reconstruction_markers:
            result.append(
                ve(
                    "Total number of type 20s is more than one: %s" %
                    len(no_reconstruction_markers), {
                        'x': marker['original_x'],
                        'y': marker['original_y'],
                        'z': marker['original_z'],
                        'name': marker['name']
                    }, "Warning"))

    return result
Exemplo n.º 17
0
def validate_coordinates_corresponding_to_axon_tip(marker_file, morphology):
    """ This function checks whether the coordinates for each axon marker
        corresponds to a tip of a axon type in the related morphology """

    result = []
    marker_types = [NO_RECONSTRUCTION]
    morphology_tip_nodes = []
    morphology_axon_nodes = morphology.node_list_by_type(AXON)

    for node in morphology_axon_nodes:
        if len(morphology.children_of(node)) == 0:
            morphology_tip_nodes.append(node)

    for marker in marker_file:
        tip_marker = False
        if marker['name'] in marker_types:
            for node in morphology_tip_nodes:
                """ Subtract one from the coordinates because there is a known discrepancy between the coordinates of 
                    the marker file and the swc file
                """
                if (marker['original_x'] - 1) == node.x and (
                        marker['original_y'] -
                        1) == node.y and (marker['original_z'] - 1) == node.z:
                    tip_marker = True
            if not tip_marker:
                result.append(
                    ve(
                        "Coordinates for each axon (type 20) needs to correspond to a tip of an axon "
                        "type (type 2) in the related morphology", {
                            'x': marker['original_x'],
                            'y': marker['original_y'],
                            'z': marker['original_z'],
                            'name': marker['name']
                        }, "Info"))

    return result