コード例 #1
0
ファイル: scene.py プロジェクト: vigji/BrainRender
    def add_plane(self, plane, **kwargs):
        """
            Adds one or more planes to the scene.
            For more details on how to build custom planes, check:
            brainrender/atlases/base.py -> Base.get_plane_at_point 
            method.

            :param plane: either a string with the name of one of 
                the predifined planes ['sagittal', 'coronal', 'horizontal'] 
                or an instance of the Plane class from vedo.shapes
        """
        if isinstance(plane, (list, tuple)):
            planes = plane.copy()
        else:
            planes = [plane]

        actors = []
        for plane in planes:
            if isinstance(plane, str):
                plane = self.atlas.get_plane_at_point(plane=plane, **kwargs)
            else:
                if not isinstance(plane, Plane):
                    raise ValueError(
                        "The plane arguments should either be a Plane actor or"
                        + "a string with the name of predefined planes." +
                        f" Not: {plane.__type__}")

            plane.name = "plane"
            plane._br_class = "plane"
            actors.append(plane)

        self.add_actor(*actors)
        return return_list_smart(actors)
コード例 #2
0
    def add_actor(self, *actors, name=None, br_class=None, store=None):
        """
        Add a vtk actor to the scene

        :param actor:
        :param store: a list to store added actors

        """
        # Parse inputs to match a name and br class to each actor
        actors, names, br_classes = parse_add_actors_inputs(
            actors, name, br_class)

        # Add actors to scene
        to_return = []
        for actor, name, br_class in zip(actors, names, br_classes):
            for act in listify(actor):
                if act is None:
                    continue

                try:
                    act = Actor(act, name=name, br_class=br_class)
                except Exception:  # doesn't work for annotations
                    act.name = name
                    act.br_class = br_class
                    act._is_transformed = False

                if store is None:
                    self.actors.append(act)
                else:
                    store.append(act)
                to_return.append(act)

        return return_list_smart(to_return)
コード例 #3
0
ファイル: scene.py プロジェクト: vigji/BrainRender
    def add_brain_regions(self, *args, **kwargs):
        """
            Adds brain regions meshes to scene.
            Check the atlas' method to know how it works
        """
        add_labels = kwargs.pop("add_labels", False)

        allactors = self.atlas.get_brain_regions(*args,
                                                 verbose=self.verbose,
                                                 **kwargs)

        actors = []
        for region, actor in allactors.items():
            if region in [a.name for a in self.actors if isinstance(a, Mesh)]:
                # Avoid inserting again
                continue

            if add_labels:
                self.add_actor_label(actor, region, **kwargs)

            actor.name = region
            actor._br_class = "brain region"
            actors.append(actor)

        self.actors.extend(actors)
        return return_list_smart(actors)
コード例 #4
0
 def add_streamlines(self, *args, **kwargs):
     """
     Render streamline data.
     Check the function definition in ABA for more details
     """
     actors = self.atlas.get_streamlines(*args, **kwargs)
     for act in actors:
         self.add_actor(actors, name="streamlines", br_class="streamlines")
     return return_list_smart(actors)
コード例 #5
0
    def add_tractography(self, *args, **kwargs):
        """
        Renders tractography data and adds it to the scene. 
        Check the function definition in ABA for more details
        """

        actors = self.atlas.get_tractography(*args, **kwargs)
        for act in actors:
            self.add_actor(actors,
                           name="tractography",
                           br_class="tractography")
        return return_list_smart(actors)
コード例 #6
0
ファイル: scene.py プロジェクト: vigji/BrainRender
    def add_actor(self, *actors, store=None):
        """
        Add a vtk actor to the scene

        :param actor:
        :param store: a list to store added actors

        """
        for actor in actors:
            if store is None:
                self.actors.append(actor)
            else:
                store.append(actor)
        return return_list_smart(actors)
コード例 #7
0
    def add_from_file(self, *filepaths, **kwargs):
        """
        Add data to the scene by loading them from a file. Should handle .obj, .vtk and .nii files.

        :param filepaths: path to the file. Can pass as many arguments as needed
        :param **kwargs:

        """
        actors = []
        for filepath in filepaths:
            actor = load_mesh_from_file(filepath, **kwargs)
            name = Path(filepath).name
            act = self.add_actor(actor, name=name, br_class=name)
            actors.append(act)
        return return_list_smart(actors)
コード例 #8
0
    def get_colors_from_coordinates(self, p0):
        """
            Given a point or a list of points returns a list of colors where
            each item is the color of the brain region each point is in
        """
        if isinstance(p0[0], (float, int)):
            p0 = [p0]

        resolution = int(self.metadata["resolution"][0])

        colors = []
        for point in p0:
            point = np.round(np.array(point) / resolution).astype(int)
            try:
                struct = self.structure_from_coords(point, as_acronym=True)
            except KeyError:  # couldn't find any region
                struct = "root"
            colors.append(self._get_from_structure(struct, "rgb_triplet"))
        return return_list_smart(colors)
コード例 #9
0
ファイル: scene.py プロジェクト: vigji/BrainRender
    def add_actor_label(self, actors, labels, **kwargs):
        """
            Adds a 2D text ancored to a point on the actor's mesh
            to label what the actor is

            :param kwargs: key word arguments can be passed to determine 
                    text appearance and location:
                        - size: int, text size. Default 300
                        - color: str, text color. A list of colors can be passed
                                if None the actor's color is used. Default None.
                        - xoffset, yoffset, zoffset: integers that shift the label position
                        - radius: radius of sphere used to denote label anchor. Set to 0 or None to hide. 
        """
        labels = make_actor_label(self.atlas, actors, labels, **kwargs)

        # Add to scene and return
        self.add_actor(*labels, store=self.actors_labels)

        return return_list_smart(labels)
コード例 #10
0
    def add_plane(self, plane, **kwargs):
        """
            Adds one or more planes to the scene.
            For more details on how to build custom planes, check:
            brainrender/atlases/base.py -> Base.get_plane_at_point 
            method.

            :param plane: either a string with the name of one of 
                the predifined planes ['sagittal', 'coronal', 'horizontal'] 
                or an instance of the Plane class from vedo.shapes
        """
        if self.transform_applied:
            rprint(
                f"[b {salmon}]Warning: [/b {salmon}][{mocassin}]you're attempting to add a plane "
                +
                "after having rendered the scene at lest once, this might give unpredicable results."
                +
                "\nIt's advised to perform add all planes before the first call to `render`"
            )

        planes = listify(plane).copy()
        actors = []
        for plane in planes:
            if isinstance(plane, str):
                plane = self.atlas.get_plane_at_point(plane=plane, **kwargs)
            else:
                if not isinstance(plane, Plane):
                    raise ValueError(
                        "The plane arguments should either be a Plane actor or"
                        + "a string with the name of predefined planes." +
                        f" Not: {plane.__type__}")

            actors.append(plane)

        self.add_actor(*actors, name="plane", br_class="plane")
        return return_list_smart(actors)
コード例 #11
0
ファイル: atlas.py プロジェクト: vigji/BrainRender
    def get_neurons(
        self,
        neurons,
        color=None,
        display_axon=True,
        display_dendrites=True,
        alpha=1,
        neurite_radius=None,
        soma_radius=None,
        use_cache=True,
    ):
        """
        Gets rendered morphological data of neurons reconstructions
        Accepts neurons argument as:
            - file(s) with morphological data
            - vedo mesh actor(s) of entire neurons reconstructions
            - dictionary or list of dictionary with actors for different neuron parts

        :param neurons: str, list, dict. File(s) with neurons data or list of rendered neurons.
        :param display_axon, display_dendrites: if set to False the corresponding neurite is not rendered
        :param color: default None. Can be:
                - None: each neuron is given a random color
                - color: rbg, hex etc. If a single color is passed all neurons will have that color
                - cmap: str with name of a colormap: neurons are colored based on their sequential order and cmap
                - dict: a dictionary specifying a color for soma, dendrites and axon actors, will be the same for all neurons
                - list: a list of length = number of neurons with either a single color for each neuron
                        or a dictionary of colors for each neuron
        :param alpha: float in range 0,1. Neurons transparency
        :param neurite_radius: float > 0 , radius of tube actor representing neurites
        :param use_cache: bool, if True a cache is used to avoid having to crate a neuron's mesh anew, otherwise a new mesh is created
        """

        if not isinstance(neurons, (list, tuple)):
            neurons = [neurons]

        # ---------------------------------- Render ---------------------------------- #
        _neurons_actors = []
        for neuron in neurons:
            neuron_actors = {"soma": None, "dendrites": None, "axon": None}

            # Deal with neuron as filepath
            if isinstance(neuron, str):
                if os.path.isfile(neuron):
                    if neuron.endswith(".swc"):
                        neuron_actors, _ = get_neuron_actors_with_morphapi(
                            swcfile=neuron,
                            neurite_radius=neurite_radius,
                            soma_radius=soma_radius,
                            use_cache=use_cache,
                        )
                    else:
                        raise NotImplementedError(
                            "Currently we can only parse morphological reconstructions from swc files"
                        )
                else:
                    raise ValueError(
                        f"Passed neruon {neuron} is not a valid input. Maybe the file doesn't exist?"
                    )

            # Deal with neuron as single actor
            elif isinstance(neuron, Mesh):
                # A single actor was passed, maybe it's the entire neuron
                neuron_actors["soma"] = neuron  # store it as soma
                pass

            # Deal with neuron as dictionary of actor
            elif isinstance(neuron, dict):
                neuron_actors["soma"] = neuron.pop("soma", None)
                neuron_actors["axon"] = neuron.pop("axon", None)

                # Get dendrites actors
                if (
                    "apical_dendrites" in neuron.keys()
                    or "basal_dendrites" in neuron.keys()
                ):
                    if "apical_dendrites" not in neuron.keys():
                        neuron_actors["dendrites"] = neuron["basal_dendrites"]
                    elif "basal_dendrites" not in neuron.keys():
                        neuron_actors["dendrites"] = neuron["apical_dendrites"]
                    else:
                        neuron_actors["dendrites"] = merge(
                            neuron["apical_dendrites"],
                            neuron["basal_dendrites"],
                        )
                else:
                    neuron_actors["dendrites"] = neuron.pop("dendrites", None)

            # Deal with neuron as instance of Neuron from morphapi
            elif isinstance(neuron, Neuron):
                neuron_actors, _ = get_neuron_actors_with_morphapi(
                    neuron=neuron,
                    neurite_radius=neurite_radius,
                    use_cache=use_cache,
                )
            # Deal with other inputs
            else:
                raise ValueError(
                    f"Passed neuron {neuron} is not a valid input"
                )

            # Check that we don't have anything weird in neuron_actors
            for key, act in neuron_actors.items():
                if act is not None:
                    if not isinstance(act, Mesh):
                        raise ValueError(
                            f"Neuron actor {key} is {type(act)} but should be a vedo Mesh. Not: {act}"
                        )

            if not display_axon:
                neuron_actors["axon"] = None
            if not display_dendrites:
                neuron_actors["dendrites"] = None
            _neurons_actors.append(neuron_actors)

        # Color actors
        colors = parse_neurons_colors(neurons, color)
        for n, neuron in enumerate(_neurons_actors):
            if neuron["axon"] is not None:
                neuron["axon"].c(colors["axon"][n])
                neuron["axon"].name = "neuron-axon"
            if neuron["soma"] is not None:
                neuron["soma"].c(colors["soma"][n])
                neuron["soma"].name = "neuron-soma"
            if neuron["dendrites"] is not None:
                neuron["dendrites"].c(colors["dendrites"][n])
                neuron["dendrites"].name = "neuron-dendrites"

        # Return
        return return_list_smart(_neurons_actors), None
コード例 #12
0
    def add_neurons(
        self,
        neurons,
        color=None,
        display_axon=True,
        display_dendrites=True,
        alpha=1,
        neurite_radius=None,
    ):
        """
            Adds rendered morphological data of neurons reconstructions downloaded from the
            Mouse Light project at Janelia, neuromorpho.org and other sources. 
            Accepts neurons argument as:
                - file(s) with morphological data
                - vedo mesh actor(s) of neurons reconstructions
                - dictionary or list of dictionary with actors for different neuron parts

            :param self: instance of brainrender Scene to use to render neurons
            :param neurons: str, list, dict. File(s) with neurons data or list of rendered neurons.
            :param display_axon, display_dendrites: if set to False the corresponding neurite is not rendered
            :param color: default None. Can be:
                    - None: each neuron is colored according to the default color
                    - color: rbg, hex etc. If a single color is passed all neurons will have that color
                    - cmap: str with name of a colormap: neurons are colored based on their sequential order and cmap
                    - dict: a dictionary specifying a color for soma, dendrites and axon actors, will be the same for all neurons
                    - list: a list of length = number of neurons with either a single color for each neuron
                            or a dictionary of colors for each neuron
            :param alpha: float in range 0,1. Neurons transparency
            :param neurite_radius: float > 0 , radius of tube actor representing neurites
        """

        if not isinstance(neurons, (list, tuple)):
            neurons = [neurons]

        # ------------------------------ Prepare colors ------------------------------ #
        colors = self._add_neurons_get_colors(neurons, color)

        # ---------------------------------- Render ---------------------------------- #
        _neurons_actors = []
        for neuron in neurons:
            neuron_actors = {"soma": None, "dendrites": None, "axon": None}

            # Deal with neuron as filepath
            if isinstance(neuron, str):
                if os.path.isfile(neuron):
                    if neuron.endswith(".swc"):
                        neuron_actors, _ = get_neuron_actors_with_morphapi(
                            swcfile=neuron, neurite_radius=neurite_radius)
                    else:
                        raise NotImplementedError(
                            "Currently we can only parse morphological reconstructions from swc files"
                        )
                else:
                    raise ValueError(
                        f"Passed neruon {neuron} is not a valid input. Maybe the file doesn't exist?"
                    )

            # Deal with neuron as single actor
            elif isinstance(neuron, Actor):
                # A single actor was passed, maybe it's the entire neuron
                neuron_actors["soma"] = neuron  # store it as soma anyway
                pass

            # Deal with neuron as dictionary of actor
            elif isinstance(neuron, dict):
                neuron_actors["soma"] = neuron.pop("soma", None)
                neuron_actors["axon"] = neuron.pop("axon", None)

                # Get dendrites actors
                if ("apical_dendrites" in neuron.keys()
                        or "basal_dendrites" in neuron.keys()):
                    if "apical_dendrites" not in neuron.keys():
                        neuron_actors["dendrites"] = neuron["basal_dendrites"]
                    elif "basal_dendrites" not in neuron.keys():
                        neuron_actors["dendrites"] = neuron["apical_dendrites"]
                    else:
                        neuron_actors["dendrites"] = merge(
                            neuron["apical_dendrites"],
                            neuron["basal_dendrites"],
                        )
                else:
                    neuron_actors["dendrites"] = neuron.pop("dendrites", None)

            # Deal with neuron as instance of Neuron from morphapi
            elif isinstance(neuron, Neuron):
                neuron_actors, _ = get_neuron_actors_with_morphapi(
                    neuron=neuron)
            # Deal with other inputs
            else:
                raise ValueError(
                    f"Passed neuron {neuron} is not a valid input")

            # Check that we don't have anything weird in neuron_actors
            for key, act in neuron_actors.items():
                if act is not None:
                    if not isinstance(act, Actor):
                        raise ValueError(
                            f"Neuron actor {key} is {act.__type__} but should be a vedo Mesh. Not: {act}"
                        )

            if not display_axon:
                neuron_actors["axon"] = None
            if not display_dendrites:
                neuron_actors["dendrites"] = None
            _neurons_actors.append(neuron_actors)

        # Color actors
        for n, neuron in enumerate(_neurons_actors):
            if neuron["axon"] is not None:
                neuron["axon"].c(colors["axon"][n])
            neuron["soma"].c(colors["soma"][n])
            if neuron["dendrites"] is not None:
                neuron["dendrites"].c(colors["dendrites"][n])

        # Add to actors storage
        self.actors.extend([list(n.values()) for n in _neurons_actors])

        return return_list_smart(_neurons_actors)