Пример #1
0
 def neurites_parser_swc(self, neurites, color):
     coords = [self.soma_coords]
     coords.extend([
         get_coords(sample,
                    mirror=self.mirror_coord,
                    mirror_ax=self.mirror_ax)
         for i, sample in neurites.iterrows()
     ])
     lines = Spheres(coords, r=38, c=color, res=4)
     regions = []
     return lines, regions
Пример #2
0
    def parse_neurons_swc_allen(self, morphology, neuron_number):
        # Get params
        neurite_radius = self._get_neurites_radius()
        soma_color, axon_color, dendrites_color, soma_region =  \
         self._render_neuron_get_params(neuron_number, soma=morphology.soma)

        # Create soma actor
        neuron_actors, regions = {
            "soma": None,
            "axon": [],
            "dendrites": []
        }, {
            'soma': soma_region,
            'dendrites': [],
            'axon': []
        }
        neuron_actors['soma'] = Sphere(pos=get_coords(morphology.soma)[::-1],
                                       c=soma_color,
                                       r=SOMA_RADIUS)

        # loop over trees
        if self.render_neurites:
            for tree in morphology._tree_list:
                tree = pd.DataFrame(tree)

                # get node numbers in t
                # get the first non soma node
                first_node_type = tree.loc[
                    tree.type != morphology.SOMA].type.values[0]

                # get the branch type
                if first_node_type == morphology.AXON:
                    neurite = "axon"
                    color = axon_color
                else:
                    neurite = "dendrites"
                    color = dendrites_color

                # Get all the points that make the branch
                branch_points = [[x, y, z] for x, y, z in zip(
                    tree.x.values, tree.y.values, tree.z.values)]

                # Create actor
                neuron_actors[neurite].append(\
                 shapes.Tube(branch_points, r=neurite_radius,
                   c=color, alpha=1, res=NEURON_RESOLUTION))

            # merge actors' meshes to make rendering faster
            for neurite, color in zip(["axon", "dendrites"],
                                      [axon_color, dendrites_color]):
                if neuron_actors[neurite]:
                    neuron_actors[neurite] = merge(*neuron_actors[neurite])
                    neuron_actors[neurite].color(color)

        self.decimate_neuron_actors(neuron_actors)
        self.smooth_neurons(neuron_actors)

        # force to hemisphere
        if self.force_to_hemisphere is not None:
            neuron_actors = self.mirror_neuron(neuron_actors)

        # Check output
        if not neuron_actors["axon"]: neuron_actors["axon"] = None
        if not neuron_actors["dendrites"]: neuron_actors["dendrites"] = None

        return neuron_actors, regions
Пример #3
0
    def render_neuron(self, neuron, neuron_number, neuron_name):
        """[This function takes care of rendering a single neuron.]
		"""
        # Prepare variables for rendering
        soma_color, axon_color, dendrites_color, soma_region = self._render_neuron_get_params(
            neuron_number, neuron=neuron)

        # create soma actor
        neuron_actors = None
        if USE_MORPHOLOGY_CACHE:
            neuron_actors = self._load_cached_neuron(neuron_name)
            if neuron_actors is not None:
                for component, color in zip(
                    ['soma', 'dendrites', 'axon'],
                    [soma_color, dendrites_color, axon_color]):
                    if component in list(neuron_actors.keys()):
                        neuron_actors[component].color(color)
                return neuron_actors, {
                    'soma': soma_region,
                    'dendrites': None,
                    'axons': None
                }

        if not USE_MORPHOLOGY_CACHE or neuron_actors is None:
            neuron_actors = {}

            self.soma_coords = get_coords(neuron["soma"],
                                          mirror=self.mirror_coord,
                                          mirror_ax=self.mirror_ax)
            neuron_actors['soma'] = Sphere(pos=self.soma_coords,
                                           c=soma_color,
                                           r=SOMA_RADIUS)

            # Draw dendrites and axons
            if self.render_neurites:
                if self.is_json:
                    neuron_actors[
                        'dendrites'], dendrites_regions = self.neurites_parser(
                            pd.DataFrame(neuron["dendrite"]), dendrites_color)
                    neuron_actors['axon'], axon_regions = self.neurites_parser(
                        pd.DataFrame(neuron["axon"]), axon_color)
                else:
                    neuron_actors[
                        'dendrites'], dendrites_regions = self.neurites_parser_swc(
                            pd.DataFrame(neuron["dendrite"]), dendrites_color)
                    neuron_actors[
                        'axon'], axon_regions = self.neurites_parser_swc(
                            pd.DataFrame(neuron["axon"]), axon_color)
            else:
                neuron_actors['dendrites'], dendrites_regions = [], None
                neuron_actors['axon'], axon_regions = [], None

            self.decimate_neuron_actors(neuron_actors)
            self.smooth_neurons(neuron_actors)

            # force to hemisphere
            if self.force_to_hemisphere is not None:
                neuron_actors = self.mirror_neuron(neuron_actors)

            if USE_MORPHOLOGY_CACHE:
                self._cache_neuron(neuron_actors, neuron_name)

            return neuron_actors, {
                'soma': soma_region,
                'dendrites': dendrites_regions,
                'axon': axon_regions
            }
Пример #4
0
    def neurites_parser(self, neurites, color):
        """[Given a dataframe with all the samples for some neurites, create "Tube" actors that render each neurite segment.]
		
		Arguments:
			neurites {[DataFrame]} -- [dataframe with each sample for the neurites]
			neurite_radius {[float]} -- [radius of the Tube actors]
			color {[color object]} -- [color to be assigned to the Tube actor]
			alleninfo {Data frame]} -- [dataframe with Info about brain regions from Allen]


		Returns:
			actors {[list]} -- [list of VTK actors]

		----------------------------------------------------------------
		This function works by first identifyingt the branching points of a neurite structure. Then each segment between either two branchin points
		or between a branching point and a terminal is modelled as a Tube. This minimizes the number of actors needed to represent the neurites
		while stil accurately modelling the neuron. 

		Known issue: the axon initial segment is missing from renderings. 
		"""
        neurite_radius = self._get_neurites_radius()

        # get branching points
        try:
            parent_counts = neurites["parentNumber"].value_counts()
        except:
            if len(neurites) == 0:
                print("Couldn't find neurites data")
                return [], []
            else:
                raise ValueError(
                    "Something went wrong while rendering neurites:\n{}".
                    format(neurites))
        branching_points = parent_counts.loc[parent_counts > 1]

        # loop over each branching point
        actors = []
        for idx, bp in branching_points.iteritems():
            # get neurites after the branching point
            bp = neurites.loc[neurites.sampleNumber == idx]
            post_bp = neurites.loc[neurites.parentNumber == idx]

            # loop on each branch after the branching point
            for bi, branch in post_bp.iterrows():
                if bi == 0:
                    branch_points = [
                        self.soma_coords,
                        get_coords(bp,
                                   mirror=self.mirror_coord,
                                   mirror_ax=self.mirror_ax),
                        get_coords(branch,
                                   mirror=self.mirror_coord,
                                   mirror_ax=self.mirror_ax)
                    ]  # this list stores all the samples that  are part of a branch
                else:
                    branch_points = [
                        get_coords(bp,
                                   mirror=self.mirror_coord,
                                   mirror_ax=self.mirror_ax),
                        get_coords(branch,
                                   mirror=self.mirror_coord,
                                   mirror_ax=self.mirror_ax)
                    ]

                # loop over all following points along the branch, until you meet either a terminal or another branching point. store the points
                idx = branch.sampleNumber
                while True:
                    nxt = neurites.loc[neurites.parentNumber == idx]
                    if len(nxt) != 1:
                        break
                    else:
                        branch_points.append(
                            get_coords(nxt,
                                       mirror=self.mirror_coord,
                                       mirror_ax=self.mirror_ax))
                        idx += 1

                # if the branch is too short for a tube, create a sphere instead
                if len(
                        branch_points
                ) < 2:  # plot either a line between two branch_points or  a spheere
                    actors.append(Sphere(branch_points[0], c="g", r=100))
                    continue

                # create tube actor
                actors.append(
                    shapes.Tube(branch_points,
                                r=neurite_radius,
                                c=color,
                                alpha=1,
                                res=NEURON_RESOLUTION))

        # merge actors' meshes to make rendering faster
        merged = merge(*actors)
        if merged is None:
            return None, None
        merged.color(color)

        # get regions the neurites go through
        regions = []
        if "allenId" in neurites.columns:
            for rid in set(neurites.allenId.values):
                try:
                    region = self.alleninfo.loc[self.alleninfo.allenId ==
                                                rid].acronym.values[0]
                    regions.append(
                        self.scene.get_structure_parent(region)['acronym'])
                except:
                    pass

        return merged, regions
Пример #5
0
    def _render_neuron_get_params(self,
                                  neuron_number,
                                  neuron=None,
                                  soma_region=None,
                                  soma=None):
        # Define colors of different components
        if not self.color_by_region:
            if self.random_color:
                if not isinstance(self.random_color, str):
                    color = get_random_colors(n_colors=1)
                else:  # random_color is a colormap
                    color = colorMap(neuron_number,
                                     name=self.random_color,
                                     vmin=0,
                                     vmax=self.n_neurons)
                axon_color = soma_color = dendrites_color = color
            else:
                if self.soma_color is None:
                    soma_color = get_random_colors(n_colors=1)

                if not self.color_neurites:
                    axon_color = dendrites_color = soma_color = self.soma_color
                else:
                    soma_color = self.soma_color
                    if self.axon_color is None:
                        axon_color = soma_color
                    else:
                        axon_color = self.axon_color
                    if self.dendrites_color is None:
                        dendrites_color = soma_color
                    else:
                        dendrites_color = self.dendrites_color

            # check that the colors make sense
            if not check_colors([soma_color, axon_color, dendrites_color]):
                raise ValueError(
                    "The colors chosen are not valid: soma - {}, dendrites {}, axon {}"
                    .format(soma_color, dendrites_color, axon_color))

            # check if we have lists of colors or single colors
            if isinstance(soma_color, list):
                if isinstance(soma_color[0], str) or isinstance(
                        soma_color[0], list):
                    soma_color = soma_color[neuron_number]
            if isinstance(dendrites_color, list):
                if isinstance(dendrites_color[0], str) or isinstance(
                        dendrites_color[0], list):
                    dendrites_color = dendrites_color[neuron_number]
            if isinstance(axon_color, list):
                if isinstance(axon_color[0], str) or isinstance(
                        axon_color[0], list):
                    axon_color = axon_color[neuron_number]

        # get allen info: it containes the allenID of each brain region
        # each sample has the corresponding allen ID so we can recontruct in which brain region it is
        if neuron is not None:
            if 'allenInformation' in list(neuron.keys()):
                self.alleninfo = pd.DataFrame(
                    neuron['allenInformation']
                )  # get brain structure in which is the soma
                soma_region = self.scene.get_structure_parent(
                    self.alleninfo.loc[
                        self.alleninfo.allenId == neuron['soma']
                        ['allenId']].acronym.values[0])['acronym']
            else:
                self.alleninfo = None
                soma_region = self.scene.get_structure_from_coordinates(
                    get_coords(neuron['soma']))
                if soma_region is not None:
                    soma_region = soma_region['acronym']
        elif soma_region is None:
            self.alleninfo = None
            if soma is not None:
                soma_region = self.scene.get_structure_from_coordinates(
                    get_coords(soma))
                if soma_region is not None:
                    soma_region = soma_region['acronym']
            else:
                raise ValueError(
                    "You need to pass either a neuron, or a soma region or a soma"
                )
        else:
            self.alleninfo = None

        if soma_region is not None:
            soma_region = self.scene.get_structure_parent(
                soma_region)['acronym']
        else:
            soma_region = "root"

        if self.color_by_region:
            try:
                region_color = self.scene.structure_tree.get_structures_by_acronym(
                    [soma_region])[0]['rgb_triplet']
            except:
                print(
                    "could not find default color for region: {}. Using random color instead"
                    .format(soma_region))
                region_color = get_random_colors(n_colors=1)

            axon_color = soma_color = dendrites_color = region_color

        return soma_color, axon_color, dendrites_color, soma_region