Пример #1
0
def showSolution3D(S, start, goal):
    from vedo import Text3D, Cube, Line, Grid, merge, show

    pts, cubes, txts = [], [], []
    pts = [(x, -y) for y, x in S[0]]
    for y, line in enumerate(Z):
        for x, c in enumerate(line):
            if c: cubes.append(Cube([x, -y, 0]))

    path = Line(pts).lw(6).c('tomato')
    walls = merge(cubes).clean().flat().texture('wood1')

    sy, sx = S[1].shape
    gradient = np.flip(S[1], axis=0).ravel()
    grd = Grid(pos=((sx - 1) / 2, -(sy - 1) / 2, -0.49),
               sx=sx,
               sy=sy,
               resx=sx,
               resy=sy)
    grd.lw(0).wireframe(False).cmap('gist_earth_r', gradient, on='cells')
    grd.addScalarBar(title='Gradient', horizontal=True, c='k', nlabels=2)

    txts.append(__doc__)
    txts.append(Text3D('Start', pos=[start[1] - 1, -start[0] + 1.5, 1], c='k'))
    txts.append(Text3D('Goal!', pos=[goal[1] - 2, -goal[0] - 2.7, 1], c='k'))
    show(path, walls, grd, txts, axes=0, zoom=1.2)
Пример #2
0
    def _parse_neuron_skeleton(self, neuron):
        """
            Parses a neuron's skeleton information from skeleton .json file
            to create a vtk actor that represents the neuron

            :param neuron: str, neuron name
        """
        try:  # make this work if called by a Scene class
            cs = self.atlas
        except:
            cs = self
        try:
            data = cs.skeletons_data[neuron]
        except:
            print(f"No skeleton data found for {neuron}")
            return None

        # Create an actor for each neuron's branch and then merge
        actors = []
        for branch in data["branches"]:
            coords = [data["coordinates"][str(p)] for p in branch]

            # Just like for synapses we need to adjust the coordinates to match the .obj files
            # coords are x z -y
            adjusted_coords = [(c[0], c[2], -c[1]) for c in coords]
            actors.append(
                Tube(
                    adjusted_coords,
                    r=cs.skeleton_radius,
                    res=NEURON_RESOLUTION,
                ))

        return merge(*actors)
Пример #3
0
    def _make_root(self, rootpath):
        """
            Creates a root mesh by merging the mesh corresponding to each neuron,
            then saves it as an obj file at rootpath
        """
        raise NotImplementedError(
            "Create root method not supported yet, sorry")

        print(f"Creating root mesh for atlas {self.atlas_name}")
        temp_scene = Scene(
            atlas=Celegans,
            add_root=False,
            display_inset=False,
            atlas_kwargs=dict(data_folder=self.data_folder),
        )

        temp_scene.add_neurons(self.neurons_names)
        temp_scene.render(interactive=False)
        temp_scene.close()

        root = merge(*temp_scene.actors["neurons"]).clean().cap()
        # root = mesh2Volume(root, spacing=(0.02, 0.02, 0.02)).isosurface()

        points = Points(root.points()).smoothMLS2D(f=0.8).clean(tol=0.005)

        root = recoSurface(points, dims=100, radius=0.2)

        # Save
        write(root, rootpath)

        del temp_scene
        return root
Пример #4
0
def ruler(p1, p2, unit_scale=1, units=None, s=50):
    actors = []

    # Make two line segments
    midpoint = np.array([(x + y) / 2 for x, y in zip(p1, p2)])
    gap1 = ((midpoint - p1) * 0.8) + p1
    gap2 = ((midpoint - p2) * 0.8) + p2

    actors.append(Line(p1, gap1, lw=200))
    actors.append(Line(gap2, p2, lw=200))

    # Add label
    if units is None:
        units = ""
    dist = mag(p2 - p1) * unit_scale
    label = precision(dist, 3) + " " + units
    lbl = Text(label, pos=midpoint, s=s + 100, justify="center")
    lbl.SetOrientation([0, 0, 180])
    actors.append(lbl)

    # Add spheres add end
    actors.append(Sphere(p1, r=s, c=[0.3, 0.3, 0.3]))
    actors.append(Sphere(p2, r=s, c=[0.3, 0.3, 0.3]))

    acts = merge(*actors).c((0.3, 0.3, 0.3)).alpha(1).lw(2)
    acts.name = "Ruler"
    acts.bg_class = "Ruler"
    return acts
Пример #5
0
    def make_root_mesh(self):
        if self.structures is None:
            return

        obj_path = os.path.join(self.meshes_folder, "root.vtk")
        if os.path.isfile(obj_path):
            return

        # Get the mesh for each brain region to create root
        meshes = [
            self._get_structure_mesh(reg) for reg in self.region_acronyms
        ]
        root = merge(meshes)
        write(root, obj_path)
Пример #6
0
 def get_mesh(self):
     """
         Returns the current mesh representation of the probe
     """
     shaft = Cylinder(pos=[self.top, self.tip],
                      c="k",
                      r=self.radius,
                      alpha=1)
     tip = Sphere(pos=self.tip, r=self.radius + 20, c="k")
     rois = Spheres([p.coordinates for p in self.points],
                    r=self.radius + 30,
                    c="r")
     mesh = merge(shaft, tip, rois).c(self.color)
     return mesh
Пример #7
0
    def write_neuron_to_cache(self, neuron_name, neuron, _params):
        # Write params to file
        save_yaml(self.get_cache_params_filename(neuron_name), _params)

        # Write neurons to file
        file_names = self.get_cache_filenames(neuron_name)

        if isinstance(neuron, Mesh):
            write(neuron, [f for f in file_names if f.endswith("soma.obj")][0])
        else:
            if not isinstance(neuron, dict):
                raise ValueError(
                    f"Invalid neuron argument passed while caching: {neuron}")
            for key, actor in neuron.items():
                if key == "whole_neuron":
                    fname = [f for f in file_names if f.endswith(f"{key}.obj")]
                    write(actor, fname[0])
                else:
                    # Get a single actor for each neuron component.
                    # If there's no data for the component create an empty actor
                    if not isinstance(actor, Mesh):
                        if isinstance(actor, (list, tuple)):
                            if len(actor) == 1:
                                actor = actor[0]
                            elif not actor or actor is None:
                                actor = Mesh()
                            else:
                                try:
                                    actor = merge(actor)
                                except:
                                    raise ValueError(
                                        f"{key} actor should be a mesh or a list of 1 mesh not {actor}"
                                    )

                    if actor is None:
                        actor = Mesh()

                    # Save to file
                    fname = [f for f in file_names if f.endswith(f"{key}.obj")]
                    if fname:
                        write(actor, fname[0])
                    else:
                        raise ValueError(
                            f"No filename found for {key}. Filenames {file_names}"
                        )
Пример #8
0
    def _make_mesh(self, data):
        lines = []
        if len(data["lines"]) == 1:
            try:
                lines_data = data["lines"][0]
            except KeyError:  # pragma: no cover
                lines_data = data["lines"]["0"]  # pragma: no cover
        else:
            lines_data = data["lines"]
        for line in lines_data:
            points = [[l["x"], l["y"], l["z"]] for l in line]
            lines.append(Tube(
                points,
                r=self.radius,
                res=8,
            ))

        return merge(*lines)
Пример #9
0
    def __init__(self, mesh1, mesh2, n):  ############################### init

        self.n = n  # desired nr. of intermediate shapes
        self.mode = '2d'
        self.mesh1 = mesh1
        self.mesh2 = mesh2
        self.merged_meshes = merge(mesh1, mesh2)
        self.mesh1.lw(4).c('grey2').pickable(False)
        self.mesh2.lw(4).c('grey1').pickable(False)

        self.arrow_starts = []
        self.arrow_stops = []
        self.dottedln = None
        self.toggle = False
        self.instructions = (
            "Click to add arrows interactively on the left panel\n"
            "right-click to remove last arrow. Then press:\n"
            "- m to morph the plane\n"
            "- c to clear\n"
            "- g to generate interpolation")
        self.msg1 = Text2D(self.instructions,
                           pos='top-left',
                           font="VictorMono",
                           bg='g2',
                           alpha=0.6)
        self.msg2 = Text2D('[output will show here]',
                           pos='top-left',
                           font="VictorMono")

        sz = self.merged_meshes.diagonalSize()
        self.plane1 = Grid(sx=sz, sy=sz, resx=50,
                           resy=50).pos(self.merged_meshes.centerOfMass())
        self.plane1.wireframe(False).alpha(1).lineWidth(0.1).c('white').lc(
            'grey5')
        self.plane2 = self.plane1.clone().pickable(False)

        self.plotter = Plotter(N=2, bg='light blue', size=(2000, 1000))
        self.plotter.addCallback('left click', self.onleftclick)
        self.plotter.addCallback('right click', self.onrightclick)
        self.plotter.addCallback('key press', self.onkeypress)
Пример #10
0
def ruler(p1, p2, unit_scale=1, units=None, s=50):
    """ 
        Creates a ruler showing the distance between two points.
        The ruler is composed of a line between the points and 
        a text indicating the distance.

        :param p1: list, np.ndarray with coordinates of first point
        :param p2: list, np.ndarray with coordinates of second point
        :param unit_scale: float. To scale the units (e.g. show mm instead of µm)
        :param units: str, name of unit (e.g. 'mm')
        :param s: float size of text

    """
    actors = []

    # Make two line segments
    midpoint = np.array([(x + y) / 2 for x, y in zip(p1, p2)])
    gap1 = ((midpoint - p1) * 0.8) + p1
    gap2 = ((midpoint - p2) * 0.8) + p2

    actors.append(Line(p1, gap1, lw=200))
    actors.append(Line(gap2, p2, lw=200))

    # Add label
    if units is None:  # pragma: no cover
        units = ""  # pragma: no cover
    dist = mag(p2 - p1) * unit_scale
    label = precision(dist, 3) + " " + units
    lbl = Text(label, pos=midpoint, s=s + 100, justify="center")
    lbl.SetOrientation([0, 0, 180])
    actors.append(lbl)

    # Add spheres add end
    actors.append(Sphere(p1, r=s, c=[0.3, 0.3, 0.3]))
    actors.append(Sphere(p2, r=s, c=[0.3, 0.3, 0.3]))

    act = Actor(merge(*actors), name="Ruler", br_class="Ruler")
    act.c((0.3, 0.3, 0.3)).alpha(1).lw(2)
    return act
Пример #11
0
    def _make_mesh(self, data, show_injection=True):
        lines = []
        if len(data["lines"]) == 1:
            try:
                lines_data = data["lines"][0]
            except KeyError:  # pragma: no cover
                lines_data = data["lines"]["0"]  # pragma: no cover
        else:
            lines_data = data["lines"]

        for line in lines_data:
            points = [[lin["x"], lin["y"], lin["z"]] for lin in line]
            lines.append(
                Tube(
                    points,
                    r=self.radius,
                    res=8,
                )
            )

        if show_injection:
            coords = np.vstack(
                [
                    list(point.values())
                    for point in data.injection_sites.iloc[0]
                ]
            )
            lines.append(
                Spheres(
                    coords,
                    r=self.radius * 10,
                    res=8,
                )
            )

        return merge(*lines)
Пример #12
0
def get_neuron_actors_with_morphapi(
    swcfile=None,
    neuron=None,
    neurite_radius=None,
    use_cache=True,
    soma_radius=None,
):
    if swcfile is None and neuron is None:
        raise ValueError("No input passed")

    if swcfile is not None:
        neuron = Neuron(swc_file=swcfile)

    if neurite_radius is None:
        neurite_radius = DEFAULT_NEURITE_RADIUS
    if soma_radius is None:
        soma_radius = SOMA_RADIUS

    actors = neuron.create_mesh(
        neurite_radius=neurite_radius,
        use_cache=use_cache,
        soma_radius=soma_radius,
    )
    if actors is None:
        raise ValueError(f"Failed to get neuron actors. {swcfile} - {neuron}")
    else:
        neurites, whole_neuron = actors

    actors = dict(
        soma=neurites["soma"],
        axon=neurites["axon"],
        dendrites=merge(neurites["basal_dendrites"],
                        neurites["apical_dendrites"]),
    )

    return actors, whole_neuron
Пример #13
0
sphere.addElevationScalars()

cone.computeNormals()
sphere.computeNormals()


###################################### test clone()
c2 = cone.clone()
print('clone()', cone.N(), c2.N())
assert cone.N() == c2.N()
print('clone()', cone.NCells(), c2.NCells())
assert cone.NCells() == c2.NCells()


###################################### test merge()
m = merge(sphere, cone)
print('merge()', m.N(), cone.N() + sphere.N())
assert m.N() == cone.N() + sphere.N()
print('merge()', m.NCells(), cone.NCells() + sphere.NCells())
assert m.NCells() == cone.NCells() + sphere.NCells()


###################################### inputdata
print('inputdata', [cone.inputdata()], "vtk.vtkPolyData")
assert isinstance(cone.inputdata(), vtk.vtkPolyData)


###################################### mapper
print('mapper',[cone.mapper()], "vtk.vtkPolyDataMapper")
assert isinstance(cone.mapper(), vtk.vtkPolyDataMapper)
Пример #14
0
def parse_streamline(
    *args,
    filepath=None,
    data=None,
    show_injection_site=True,
    color="ivory",
    alpha=0.8,
    radius=10,
    **kwargs,
):
    """
        Given a path to a .json file with streamline data (or the data themselves), render the streamline as tubes actors.
        Either  filepath or data should be passed

        :param filepath: str, optional. Path to .json file with streamline data (Default value = None)
        :param data: panadas.DataFrame, optional. DataFrame with streamline data. (Default value = None)
        :param color: str color of the streamlines (Default value = 'ivory')
        :param alpha: float transparency of the streamlines (Default value = .8)
        :param radius: int radius of the streamlines actor (Default value = 10)
        :param show_injection_site: bool, if True spheres are used to render the injection volume (Default value = True)
        :param *args: 
        :param **kwargs: 

    """
    if filepath is not None and data is None:
        data = load_json(filepath)
    elif filepath is None and data is not None:
        pass
    else:
        raise ValueError(
            "Need to pass eiteher a filepath or data argument to parse_streamline"
        )

    # create actors for streamlines
    lines = []
    if len(data["lines"]) == 1:
        try:
            lines_data = data["lines"][0]
        except KeyError:
            lines_data = data["lines"]["0"]
    else:
        lines_data = data["lines"]
    for line in lines_data:
        points = [[l["x"], l["y"], l["z"]] for l in line]
        lines.append(
            shapes.Tube(
                points,
                r=radius,
                c=color,
                alpha=alpha,
                res=brainrender.STREAMLINES_RESOLUTION,
            ))

    coords = []
    if show_injection_site:
        if len(data["injection_sites"]) == 1:
            try:
                injection_data = data["injection_sites"][0]
            except KeyError:
                injection_data = data["injection_sites"]["0"]
        else:
            injection_data = data["injection_sites"]

        for inj in injection_data:
            coords.append(list(inj.values()))
        spheres = [shapes.Spheres(coords, r=brainrender.INJECTION_VOLUME_SIZE)]
    else:
        spheres = []

    merged = merge(*lines, *spheres)
    merged.color(color)
    merged.alpha(alpha)
    return [merged]
Пример #15
0
for place, theta, phi, confirmed, deaths, recos in data:
    pos = spher2cart(1, theta, phi)
    fl = 'cases: ' + str(confirmed) + '\ndeaths: ' + str(deaths)
    radius = np.power(confirmed, 1 / 3) / 2000
    sph1 = Sphere(pos, radius, alpha=0.4, res=12).flag(place + fl)
    if deaths > 5000:
        sph1.flag(fl)
        anchorpt = sph1.pos() * (1 + radius)
        vig = sph1.vignette(place, anchorpt, font="Kanopus")
        vig.c('k').scale(1.5 * (1 + radius)).followCamera()
        vigs.append(vig)
    s1.append(sph1)
    s2.append(
        Sphere(pos, np.power(deaths, 1 / 3) / 2000, alpha=0.4, c='k', res=10))

tx = Text2D('COVID-19 spread on ' + date + '\n# cases : ' + str(allconf) +
            '\n# deaths: ' + str(alldeat) + '\n# recovd: ' + str(allreco) +
            '\n(hover mouse for local info)',
            font="VictorMono")

show(Earth(),
     s1,
     merge(s2),
     vigs,
     tx,
     axes=11,
     bg2='lb',
     zoom=1.7,
     elevation=-70,
     size='fullscreen')
Пример #16
0
"""Thin Plate Spline transformations describe a nonlinear warp
transform defined by a set of source and target landmarks.
Any point on the mesh close to a source landmark will
be moved to a place close to the corresponding target landmark.
The points in between are interpolated using Bookstein's algorithm."""
from vedo import Grid, merge, Points, Arrows, show
import numpy as np
#np.random.seed(2)

grids = []
for i in range(5):
    gr = Grid([0, 0, i / 8], resx=12, resy=12)
    grids.append(gr)
mesh = merge(grids)  # merge grids into a single object

idxs = np.random.randint(0, mesh.N(), 10)  # pick 10 indices
pts = mesh.points()[idxs]

ptsource, pttarget = [], []
for pt in pts:
    ptold = pt + np.random.randn(3) * 0.02
    ptsource.append(ptold)
    ptnew = ptold + [0, 0, np.random.randn(1) * 0.1]  # move in z
    pttarget.append(ptnew)

warped = mesh.warp(ptsource, pttarget)
warped.color("b4").lc('light blue').wireframe(False).lw(1)

apts = Points(ptsource, r=10, c="r")
arrs = Arrows(ptsource, pttarget, c='k')
Пример #17
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)
Пример #18
0
# Create the scene -------------------------------------------------------------
from vedo import spher2cart, Sphere, Text2D, Earth, merge, show

date, data, allconf, alldeat, allreco = load_data()
s1, s2, vigs = [], [], []
for place, theta, phi, confirmed, deaths, recos in data:
    pos = spher2cart(1, theta, phi)
    fl = 'cases: '+str(confirmed) + '\ndeaths: '+str(deaths)
    radius = np.power(confirmed, 1/3)/4000
    sph1 = Sphere(pos, radius, alpha=0.4, res=12).flag(place+fl)
    if deaths > 10000:
        sph1.flag(fl)
        anchorpt = sph1.pos()*(1+radius)
        vig = sph1.vignette(place, anchorpt, font="Kanopus")
        vig.c('k').scale(1.5*(1+radius)).followCamera()
        vigs.append(vig)
    s1.append(sph1)
    s2.append(Sphere(pos, np.power(deaths, 1/3)/4000, alpha=0.4, c='k', res=10))

tx = Text2D('COVID-19 spread on '+date
           +'\n# cases : '+str(allconf)
           +'\n# deaths: '+str(alldeat)
           +'\n# recovd: '+str(allreco)
           +'\n(hover mouse for local info)',
           font="VictorMono")

show(Earth(), s1, merge(s2), vigs, tx,
     axes=11, bg2='lb', zoom=1.7, elevation=-70, size='fullscreen')

Пример #19
0
    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
Пример #20
0
"""Elliptic Fourier Descriptors
parametrizing a closed countour (in red)"""
import vedo, pyefd

shapes = vedo.load(vedo.dataurl+'timecourse1d.npy')

sh = shapes[55]
sr = vedo.Line(sh).mirror('x').reverse()
sm = vedo.merge(sh, sr).c('red5').lw(3)
pts = sm.points()[:,(0,1)]

rlines = []
for order in range(5,30, 5):
    coeffs = pyefd.elliptic_fourier_descriptors(pts, order=order, normalize=False)
    a0, c0 = pyefd.calculate_dc_coefficients(pts)
    rpts = pyefd.reconstruct_contour(coeffs, locus=(a0,c0), num_points=400)
    color = vedo.colorMap(order, "Blues", 5,30)
    rline = vedo.Line(rpts).lw(3).c(color)
    rlines.append(rline)

sm.z(0.1) # move it on top so it's visible
vedo.show(sm, *rlines, __doc__, axes=1, bg='k', size=(1190, 630), zoom=1.8)
Пример #21
0
(2) `assembly.Assembly` - combines meshes (or other actors); preserves properties
(3) `+` - equivalent to `Assembly`
'''

import vedo
import numpy as np

# Define vertices and faces
verts = np.array([(0, 0, 0), (10, 0, 0), (0, 10, 0), (0, 0, 10)])
faces = np.array([(0, 1, 2), (2, 1, 3), (1, 0, 3), (0, 2, 3)])
# Create a tetrahedron and a copy
mesh = vedo.Mesh([verts, faces], c='red')
mesh2 = mesh.clone().x(15).y(15).c('blue')  # Create a copy, shift it; change color

# Merge: creates a new mesh, color of the second mesh is lost
mesh_all = vedo.merge(mesh, mesh2)
print('1. Type:', type(mesh_all))
# Show
plotter = vedo.show(mesh_all, viewup='z', axes=1)  # -> all red
plotter.close()

# Assembly: groups meshes
mesh_all = vedo.assembly.Assembly(mesh, mesh2)
print('2. Type:', type(mesh_all))
# Show
plotter = vedo.show(mesh_all, viewup='z', axes=1)  # -> red and blue
plotter.close()

# Equivalently, "+" also creates an Assembly
mesh_all = mesh + mesh2
print('3. Type:', type(mesh_all))
Пример #22
0
"""The butterfly effect with cylindrical mirrors and a laser"""
# Original idea from "The Action Lab": https://www.youtube.com/watch?v=kBow0kTVn3s
#
from vedo import Plotter, Grid, Cylinder, merge
from optics_base import Ray, Mirror, Detector  # see file ./optics_base.py

grid = Grid(resx=3, resy=4)  # pick a few points in space to place cylinders
pts = grid.points().tolist() + grid.cellCenters().tolist()

# Create the mirror by merging many (y-scaled) cylinders into a single mesh object
cyls = [
    Cylinder(p, r=0.065, height=0.2, res=720).scale([1, 1.5, 1]) for p in pts
]
mirror = Mirror(merge(cyls)).color("silver")

# Create a detector surface as a thin cylinder surrounding the mirror
sd = Cylinder(r=1, height=0.3, cap=False).cutWithPlane([0, -0.95, 0],
                                                       normal='y')
detector = Detector(sd)


def slider(widget, event):  ### callback to shift the beam along x
    dx = widget.GetRepresentation().GetValue()
    ray = Ray([dx, -1.2, -0.1], direction=(0, 1, 0.02))
    ray.maxiterations = 1000  # max nr. of reflections
    ray.trace([mirror, detector])  # cumpute trajectory
    detector.count().cmap("Reds", on='cells', vmax=10)
    line = ray.asLine().lineWidth(4).c('green5')
    if plt.actors[-1].name == "Line":
        plt.pop()  # remove the last Line
    plt.add(line)  # add the new one
Пример #23
0
        y += amp * np.sin(freq * time + phase + rotation)
        path.append([x, y])

    if len(points):
        hline = vedo.Line([x, y], points[-1], c='red5', lw=0.1)
        pline = vedo.Line(path, c='green5', lw=2)
        oline = vedo.Line(points, c='red4', lw=5)
        objs += [hline, pline, oline]
        plt.add(objs, resetcam=False)
    return [x, y]


# Load some 2D shape and make it symmetric
shape = vedo.load(vedo.dataurl + 'timecourse1d.npy')[55]
shaper = vedo.Line(shape).mirror('x').reverse()
shape = vedo.merge(shape, shaper)
x, y, _ = shape.points().T

# Compute Fourier Discrete Transform in x and y separately:
fourierX = DFT(x)
fourierY = DFT(y)

vedo.settings.defaultFont = 'Glasgo'
plt = vedo.Plotter(size=(1500, 750), bg='black', axes=1, interactive=False)
txt = vedo.Text2D(f"{__doc__} (order={order})",
                  c='red9',
                  bg='white',
                  pos='bottom-center')
plt.show(shape, txt, mode='image', zoom=1.9)

objs, points = [], []
Пример #24
0
    def create_mesh(self,
                    neurite_radius=2,
                    soma_radius=4,
                    use_cache=True,
                    **kwargs):
        if self.points is None:
            print("No data loaded, returning")
            return

        # Parse kwargs
        (
            soma_color,
            apical_dendrites_color,
            basal_dendrites_color,
            axon_color,
            whole_neuron_color,
            kwargs,
        ) = self._parse_mesh_kwargs(**kwargs)

        if (not isinstance(neurite_radius, (int, float))
                or not neurite_radius > 0):
            raise ValueError(
                f"Invalid value for parameter neurite_radius, should be a float > 0"
            )
        if not isinstance(soma_radius, (int, float)) or not soma_radius > 0:
            raise ValueError(
                f"Invalid value for parameter soma_radius, should be a float > 0"
            )
        # prepare params dict for caching
        _params = dict(neurite_radius=neurite_radius, soma_radius=soma_radius)

        # Check if cached files already exist
        if use_cache:
            neurites = self.load_cached_neuron(self.neuron_name, _params)
        else:
            neurites = None

        # Render
        if neurites is not None:
            whole_neuron = neurites.pop("whole_neuron")
            neurites["soma"].c(soma_color)
        else:
            # Create soma actor
            neurites = {}
            if not self.invert_dims:
                coords = self.points["soma"].coords
            else:
                coords = self.points["soma"].coords
                z, y, x = coords[0], coords[1], coords[2]
                coords = np.hstack([x, y, z]).T

            soma = Sphere(
                pos=coords,
                r=self.points["soma"].radius * soma_radius,
                c=soma_color,
            ).computeNormals()
            neurites["soma"] = soma.clone().c(soma_color)

            # Create neurites actors
            for ntype in self._neurite_types:
                actors = []
                for neurite in self.points[ntype]:
                    for section in iter_sections(neurite.component):
                        for child in section.children:
                            if not child.children:
                                coords = child.points[:, COLS.XYZ]
                                if self.invert_dims:
                                    z, y, x = (
                                        coords[:, 0],
                                        coords[:, 1],
                                        coords[:, 2],
                                    )
                                    coords = np.hstack([x, y, z]).T
                                actors.append(Tube(coords, r=neurite_radius))
                            else:
                                for grandchild in child.children:
                                    coords = grandchild.points[:, COLS.XYZ]
                                    if self.invert_dims:
                                        z, y, x = (
                                            coords[:, 0],
                                            coords[:, 1],
                                            coords[:, 2],
                                        )
                                        coords = np.vstack([x, y, z]).T
                                    actors.append(
                                        Tube(coords, r=neurite_radius))

                if actors:
                    neurites[ntype] = merge(
                        actors).computeNormals()  # .smoothMLS2D(f=0.1)
                else:
                    neurites[ntype] = None

            # Merge actors to get the entire neuron
            actors = [
                act.clone() for act in neurites.values() if act is not None
            ]
            whole_neuron = merge(actors).clean().computeNormals()

            # Write to cache
            to_write = neurites.copy()
            to_write["whole_neuron"] = whole_neuron
            self.write_neuron_to_cache(self.neuron_name, to_write, _params)

        # Color actors
        colors = [basal_dendrites_color, apical_dendrites_color, axon_color]
        for n, key in enumerate(
            ["basal_dendrites", "apical_dendrites", "axon"]):
            if neurites[key] is not None:
                neurites[key] = neurites[key].c(colors[n])
        whole_neuron.c(whole_neuron_color)

        return neurites, whole_neuron