def _extract_sections(data_block):
    '''Make a list of sections from an SWC-style data wrapper block'''
    structure_block = data_block[:, COLS.TYPE:COLS.COL_COUNT].astype(np.int)

    # SWC ID -> structure_block position
    id_map = {-1: -1}
    for i, row in enumerate(structure_block):
        id_map[row[ID]] = i

    # end points have either no children, more than one, or are the start
    # of a new gap
    sec_end_pts = _section_end_points(structure_block, id_map)

    # a 'gap' is when a section has part of it's segments interleaved
    # with those of another section
    gap_sections = set()

    sections = []

    def new_section():
        '''new_section'''
        sections.append(DataBlockSection())
        return sections[-1]

    curr_section = new_section()

    parent_section = {-1: -1}

    for row in structure_block:
        row_id = id_map[row[ID]]
        parent_id = id_map[row[PID]]
        if not curr_section.ids:
            # first in section point is parent
            curr_section.ids.append(parent_id)
            curr_section.ntype = row[TYPE]

        gap = parent_id != curr_section.ids[-1]

        # If parent is not the previous point, create a section end-point.
        # Else add the point to this section
        if gap:
            sec_end_pts.add(row_id)
        else:
            curr_section.ids.append(row_id)

        if row_id in sec_end_pts:
            parent_section[curr_section.ids[-1]] = len(sections) - 1
            # Parent-child discontinuity section
            if gap:
                curr_section = new_section()
                curr_section.ids.extend((parent_id, row_id))
                curr_section.ntype = row[TYPE]
                gap_sections.add(len(sections) - 2)
            elif row_id != len(data_block) - 1:
                # avoid creating an extra DataBlockSection for last row if it's a leaf
                curr_section = new_section()

    for sec in sections:
        # get the section parent ID from the id of the first point.
        if sec.ids:
            sec.pid = parent_section[sec.ids[0]]

        # join gap sections and "disable" first half
        if sec.pid in gap_sections:
            _merge_sections(sections[sec.pid], sec)

    # TODO find a way to remove empty sections.  Currently they are
    # required to maintain tree integrity.
    return sections
def _extract_sections ( data_block ) : structure_block = data_block [ : , COLS . TYPE : COLS . COL_COUNT ] . astype ( np . int ) id_map = { - 1 : - 1 } for i , row in enumerate ( structure_block ) : id_map [ row [ ID ] ] = i sec_end_pts = _section_end_points ( structure_block , id_map ) gap_sections = set ( ) sections = [ ] def new_section ( ) : sections . append ( DataBlockSection ( ) ) return sections [ - 1 ] curr_section = new_section ( ) parent_section = { - 1 : - 1 } for row in structure_block : row_id = id_map [ row [ ID ] ] parent_id = id_map [ row [ PID ] ] if not curr_section . ids : curr_section . ids . append ( parent_id ) curr_section . ntype = row [ TYPE ] gap = parent_id != curr_section . ids [ - 1 ] if gap : sec_end_pts . add ( row_id ) else : curr_section . ids . append ( row_id ) if row_id in sec_end_pts : parent_section [ curr_section . ids [ - 1 ] ] = len ( sections ) - 1 if gap : curr_section = new_section ( ) curr_section . ids . extend ( ( parent_id , row_id ) ) curr_section . ntype = row [ TYPE ] gap_sections . add ( len ( sections ) - 2 ) elif row_id != len ( data_block ) - 1 : curr_section = new_section ( ) for sec in sections : if sec . ids : sec . pid = parent_section [ sec . ids [ 0 ] ] if sec . pid in gap_sections : _merge_sections ( sections [ sec . pid ] , sec ) return sections
Make a list of sections from an SWC-style data wrapper block