Example #1
0
def iter_neurites(obj, mapfun=None, filt=None, neurite_order=NeuriteIter.FileOrder):
    """Iterator to a neurite, neuron or neuron population.

    Applies optional neurite filter and mapping functions.

    Arguments:
        obj: a neurite, neuron or neuron population.
        mapfun: optional neurite mapping function.
        filt: optional neurite filter function.
        neurite_order (NeuriteIter): order upon which neurites should be iterated
            - NeuriteIter.FileOrder: order of appearance in the file
            - NeuriteIter.NRN: NRN simulator order: soma -> axon -> basal -> apical

    Examples:
        Get the number of points in each neurite in a neuron population

        >>> from neurom.core import iter_neurites
        >>> n_points = [n for n in iter_neurites(pop, lambda x : len(x.points))]

        Get the number of points in each axon in a neuron population

        >>> import neurom as nm
        >>> from neurom.core import iter_neurites
        >>> filter = lambda n : n.type == nm.AXON
        >>> mapping = lambda n : len(n.points)
        >>> n_points = [n for n in iter_neurites(pop, mapping, filter)]
    """
    neurites = ((obj,) if isinstance(obj, Neurite) else
                obj.neurites if hasattr(obj, 'neurites') else obj)
    if neurite_order == NeuriteIter.NRN:
        last_position = max(NRN_ORDER.values()) + 1
        neurites = sorted(neurites, key=lambda neurite: NRN_ORDER.get(neurite.type, last_position))

    neurite_iter = iter(neurites) if filt is None else filter(filt, neurites)
    return neurite_iter if mapfun is None else map(mapfun, neurite_iter)
Example #2
0
def iter_neurites(obj, mapfun=None, filt=None):
    '''Iterator to a neurite, neuron or neuron population

    Applies optional neurite filter and mapping functions.

    Parameters:
        obj: a neurite, neuron or neuron population.
        mapfun: optional neurite mapping function.
        filt: optional neurite filter function.

    Examples:

        Get the number of points in each neurite in a neuron population

        >>> from neurom.core import iter_neurites
        >>> n_points = [n for n in iter_neurites(pop, lambda x : len(x.points))]

        Get the number of points in each axon in a neuron population

        >>> import neurom as nm
        >>> from neurom.core import iter_neurites
        >>> filter = lambda n : n.type == nm.AXON
        >>> mapping = lambda n : len(n.points)
        >>> n_points = [n for n in iter_neurites(pop, mapping, filter)]

    '''
    neurites = ((obj,) if isinstance(obj, Neurite) else
                obj.neurites if hasattr(obj, 'neurites') else obj)

    neurite_iter = iter(neurites) if filt is None else filter(filt, neurites)
    return neurite_iter if mapfun is None else map(mapfun, neurite_iter)
Example #3
0
def iter_neurites(obj, mapfun=None, filt=None):
    '''Iterator to a neurite, neuron or neuron population

    Applies optional neurite filter and mapping functions.

    Parameters:
        obj: a neurite, neuron or neuron population.
        mapfun: optional neurite mapping function.
        filt: optional neurite filter function.

    Examples:

        Get the number of points in each neurite in a neuron population

        >>> from neurom.core import iter_neurites
        >>> n_points = [n for n in iter_neurites(pop, lambda x : len(x.points))]

        Get the number of points in each axon in a neuron population

        >>> import neurom as nm
        >>> from neurom.core import iter_neurites
        >>> filter = lambda n : n.type == nm.AXON
        >>> mapping = lambda n : len(n.points)
        >>> n_points = [n for n in iter_neurites(pop, mapping, filter)]

    '''
    neurites = ((obj, ) if isinstance(obj, Neurite) else
                obj.neurites if hasattr(obj, 'neurites') else obj)

    neurite_iter = iter(neurites) if filt is None else filter(filt, neurites)
    return neurite_iter if mapfun is None else map(mapfun, neurite_iter)
Example #4
0
def test_iter_sections_filter():

    for ntyp in nm.NEURITE_TYPES:
        a = [s for n in filter(lambda nn: nn.type == ntyp, POP.neurites)
             for s in n.iter_sections()]
        b = [n for n in core.iter_sections(POP, neurite_filter=lambda n: n.type == ntyp)]
        assert_sequence_equal(a, b)
Example #5
0
def test_iter_sections_filter():

    for ntyp in nm.NEURITE_TYPES:
        a = [s.id for n in filter(lambda nn: nn.type == ntyp, POP.neurites)
             for s in n.iter_sections()]
        b = [n.id for n in core.iter_sections(POP, neurite_filter=lambda n: n.type == ntyp)]
        assert_sequence_equal(a, b)
Example #6
0
File: tree.py Project: MFSY/NeuroM
    def iforking_point(self, iter_mode=ipreorder):
        """Iterator to forking points. Returns a tree object.

        Arguments:
            tree: the tree over which to iterate
            iter_mode: iteration mode. Default: ipreorder.
        """
        return filter(Tree.is_forking_point, iter_mode(self))
Example #7
0
def get_morph_files(directory):
    '''Get a list of all morphology files in a directory

    Returns:
        list with all files with extensions '.swc' , 'h5' or '.asc' (case insensitive)
    '''
    lsdir = (os.path.join(directory, m) for m in os.listdir(directory))
    return list(filter(_is_morphology_file, lsdir))
Example #8
0
    def iforking_point(self, iter_mode=ipreorder):
        '''Iterator to forking points. Returns a tree object.

        Parameters:
            tree: the tree over which to iterate
            iter_mode: iteration mode. Default: ipreorder.
        '''
        return filter(Tree.is_forking_point, iter_mode(self))
Example #9
0
    def iforking_point(self, iter_mode=ipreorder):
        '''Iterator to forking points. Returns a tree object.

        Parameters:
            tree: the tree over which to iterate
            iter_mode: iteration mode. Default: ipreorder.
        '''
        return filter(Tree.is_forking_point, iter_mode(self))
Example #10
0
def get_morph_files(directory):
    '''Get a list of all morphology files in a directory

    Returns:
        list with all files with extensions '.swc' , 'h5' or '.asc' (case insensitive)
    '''
    lsdir = (os.path.join(directory, m) for m in os.listdir(directory))
    return list(filter(_is_morphology_file, lsdir))
Example #11
0
 def _filepath(self, name):
     """ File path to `name` morphology file. """
     if self.file_ext is None:
         candidates = glob.glob(os.path.join(self.directory, name + ".*"))
         try:
             return next(filter(_is_morphology_file, candidates))
         except StopIteration:
             raise NeuroMError("Can not find morphology file for '%s' " % name)
     else:
         return os.path.join(self.directory, name + self.file_ext)
Example #12
0
 def _filepath(self, name):
     """ File path to `name` morphology file. """
     if self.file_ext is None:
         candidates = glob.glob(os.path.join(self.directory, name + ".*"))
         try:
             return next(filter(_is_morphology_file, candidates))
         except StopIteration:
             raise NeuroMError("Can not find morphology file for '%s' " % name)
     else:
         return os.path.join(self.directory, name + self.file_ext)
Example #13
0
def iter_neurites(obj, mapfun=None, filt=None, neurite_order=NeuriteIter.FileOrder):
    '''Iterator to a neurite, neuron or neuron population

    Applies optional neurite filter and mapping functions.

    Parameters:
        obj: a neurite, neuron or neuron population.
        mapfun: optional neurite mapping function.
        filt: optional neurite filter function.
        neurite_order (NeuriteIter): order upon which neurites should be iterated
            - NeuriteIter.FileOrder: order of appearance in the file
            - NeuriteIter.NRN: NRN simulator order: soma -> axon -> basal -> apical

    Examples:

        Get the number of points in each neurite in a neuron population

        >>> from neurom.core import iter_neurites
        >>> n_points = [n for n in iter_neurites(pop, lambda x : len(x.points))]

        Get the number of points in each axon in a neuron population

        >>> import neurom as nm
        >>> from neurom.core import iter_neurites
        >>> filter = lambda n : n.type == nm.AXON
        >>> mapping = lambda n : len(n.points)
        >>> n_points = [n for n in iter_neurites(pop, mapping, filter)]

    '''
    neurites = ((obj,) if isinstance(obj, Neurite) else
                obj.neurites if hasattr(obj, 'neurites') else obj)
    if neurite_order == NeuriteIter.NRN:
        last_position = max(NRN_ORDER.values()) + 1
        neurites = sorted(neurites, key=lambda neurite: NRN_ORDER.get(neurite.type, last_position))

    neurite_iter = iter(neurites) if filt is None else filter(filt, neurites)
    return neurite_iter if mapfun is None else map(mapfun, neurite_iter)
Example #14
0
 def ileaf(self):
     '''Iterator to all leaves of a tree'''
     return filter(Tree.is_leaf, self.ipreorder())
Example #15
0
def is_back_tracking(neurite):
    ''' Check if a neurite process backtracks to a previous node. Back-tracking takes place
    when a daughter of a branching process goes back and either overlaps with a previous point, or
    lies inside the cylindrical volume of the latter.

    Args:
        neurite(Neurite): neurite to operate on

    Returns:
        True Under the following scenaria:
            1. A segment endpoint falls back and overlaps with a previous segment's point
            2. The geometry of a segment overlaps with a previous one in the section
    '''
    def pair(segs):
        ''' Pairs the input list into triplets'''
        return zip(segs, segs[1:])

    def coords(node):
        ''' Returns the first three values of the tree that correspond to the x, y, z coordinates'''
        return node[COLS.XYZ]

    def max_radius(seg):
        ''' Returns maximum radius from the two segment endpoints'''
        return max(seg[0][COLS.R], seg[1][COLS.R])

    def is_not_zero_seg(seg):
        ''' Returns True if segment has zero length'''
        return not np.allclose(coords(seg[0]), coords(seg[1]))

    def is_in_the_same_verse(seg1, seg2):
        ''' Checks if the vectors face the same direction. This
        is true if their dot product is greater than zero.
        '''
        v1 = coords(seg2[1]) - coords(seg2[0])
        v2 = coords(seg1[1]) - coords(seg1[0])
        return np.dot(v1, v2) >= 0

    def is_seg2_within_seg1_radius(dist, seg1, seg2):
        ''' Checks whether the orthogonal distance from the point at the end of
        seg1 to seg2 segment body is smaller than the sum of their radii
        '''
        return dist <= max_radius(seg1) + max_radius(seg2)

    def is_seg1_overlapping_with_seg2(seg1, seg2):
        '''Checks if a segment is in proximity of another one upstream'''
        # get the coordinates of seg2 (from the origin)
        s1 = coords(seg2[0])
        s2 = coords(seg2[1])

        # vector of the center of seg2 (from the origin)
        C = 0.5 * (s1 + s2)

        # endpoint of seg1 (from the origin)
        P = coords(seg1[1])

        # vector from the center C of seg2 to the endpoint P of seg1
        CP = P - C

        # vector of seg2
        S1S2 = s2 - s1

        # projection of CP upon seg2
        prj = mm.vector_projection(CP, S1S2)

        # check if the distance of the orthogonal complement of CP projection on S1S2
        # (vertical distance from P to seg2) is smaller than the sum of the radii. (overlap)
        # If not exit early, because there is no way that backtracking can feasible
        if not is_seg2_within_seg1_radius(np.linalg.norm(CP - prj), seg1, seg2):
            return False

        # projection lies within the length of the cylinder. Check if the distance between
        # the center C of seg2 and the projection of the end point of seg1, P is smaller than
        # half of the others length plus a 5% tolerance
        return np.linalg.norm(prj) < 0.55 * np.linalg.norm(S1S2)

    def is_inside_cylinder(seg1, seg2):
        ''' Checks if seg2 approximately lies within a cylindrical volume of seg1.
        Two conditions must be satisfied:
            1. The two segments are not facing the same direction  (seg2 comes back to seg1)
            2. seg2 is overlaping with seg1
        '''
        return not is_in_the_same_verse(seg1, seg2) and is_seg1_overlapping_with_seg2(seg1, seg2)

    # filter out single segment sections
    section_itr = (snode for snode in neurite.iter_sections() if snode.points.shape[0] > 2)
    for snode in section_itr:
        # group each section's points intro triplets
        segment_pairs = list(filter(is_not_zero_seg, pair(snode.points)))

        # filter out zero length segments
        for i, seg1 in enumerate(segment_pairs[1:]):
            # check if the end point of the segment lies within the previous
            # ones in the current sectionmake
            for seg2 in segment_pairs[0: i + 1]:
                if is_inside_cylinder(seg1, seg2):
                    return True
    return False
Example #16
0
 def ileaf(self):
     '''Iterator to all leaves of a tree'''
     return filter(Tree.is_leaf, self.ipreorder())
Example #17
0
def is_back_tracking(neurite):
    ''' Check if a neurite process backtracks to a previous node. Back-tracking takes place
    when a daughter of a branching process goes back and either overlaps with a previous point, or
    lies inside the cylindrical volume of the latter.

    Args:
        neurite(Neurite): neurite to operate on

    Returns:
        True Under the following scenaria:
            1. A segment endpoint falls back and overlaps with a previous segment's point
            2. The geometry of a segment overlaps with a previous one in the section
    '''
    def pair(segs):
        ''' Pairs the input list into triplets'''
        return zip(segs, segs[1:])

    def coords(node):
        ''' Returns the first three values of the tree that correspond to the x, y, z coordinates'''
        return node[COLS.XYZ]

    def max_radius(seg):
        ''' Returns maximum radius from the two segment endpoints'''
        return max(seg[0][COLS.R], seg[1][COLS.R])

    def is_not_zero_seg(seg):
        ''' Returns True if segment has zero length'''
        return not np.allclose(coords(seg[0]), coords(seg[1]))

    def is_in_the_same_verse(seg1, seg2):
        ''' Checks if the vectors face the same direction. This
        is true if their dot product is greater than zero.
        '''
        v1 = coords(seg2[1]) - coords(seg2[0])
        v2 = coords(seg1[1]) - coords(seg1[0])
        return np.dot(v1, v2) >= 0

    def is_seg2_within_seg1_radius(dist, seg1, seg2):
        ''' Checks whether the orthogonal distance from the point at the end of
        seg1 to seg2 segment body is smaller than the sum of their radii
        '''
        return dist <= max_radius(seg1) + max_radius(seg2)

    def is_seg1_overlapping_with_seg2(seg1, seg2):
        '''Checks if a segment is in proximity of another one upstream'''
        # get the coordinates of seg2 (from the origin)
        s1 = coords(seg2[0])
        s2 = coords(seg2[1])

        # vector of the center of seg2 (from the origin)
        C = 0.5 * (s1 + s2)

        # endpoint of seg1 (from the origin)
        P = coords(seg1[1])

        # vector from the center C of seg2 to the endpoint P of seg1
        CP = P - C

        # vector of seg2
        S1S2 = s2 - s1

        # projection of CP upon seg2
        prj = mm.vector_projection(CP, S1S2)

        # check if the distance of the orthogonal complement of CP projection on S1S2
        # (vertical distance from P to seg2) is smaller than the sum of the radii. (overlap)
        # If not exit early, because there is no way that backtracking can feasible
        if not is_seg2_within_seg1_radius(np.linalg.norm(CP - prj), seg1,
                                          seg2):
            return False

        # projection lies within the length of the cylinder. Check if the distance between
        # the center C of seg2 and the projection of the end point of seg1, P is smaller than
        # half of the others length plus a 5% tolerance
        return np.linalg.norm(prj) < 0.55 * np.linalg.norm(S1S2)

    def is_inside_cylinder(seg1, seg2):
        ''' Checks if seg2 approximately lies within a cylindrical volume of seg1.
        Two conditions must be satisfied:
            1. The two segments are not facing the same direction  (seg2 comes back to seg1)
            2. seg2 is overlaping with seg1
        '''
        return not is_in_the_same_verse(
            seg1, seg2) and is_seg1_overlapping_with_seg2(seg1, seg2)

    # filter out single segment sections
    section_itr = (snode for snode in neurite.iter_sections()
                   if snode.points.shape[0] > 2)
    for snode in section_itr:
        # group each section's points intro triplets
        segment_pairs = list(filter(is_not_zero_seg, pair(snode.points)))

        # filter out zero length segments
        for i, seg1 in enumerate(segment_pairs[1:]):
            # check if the end point of the segment lies within the previous
            # ones in the current sectionmake
            for seg2 in segment_pairs[0:i + 1]:
                if is_inside_cylinder(seg1, seg2):
                    return True
    return False
Example #18
0
File: tree.py Project: MFSY/NeuroM
 def ileaf(self):
     """Iterator to all leaves of a tree."""
     return filter(Tree.is_leaf, self.ipreorder())