def _cache_neuron(self, neuron_actors, neuron_name, params): """ Save a loaded neuron :param neuron_actors: list of neuron's actors :param neuron_name: name of the neuron """ if not neuron_name or neuron_name is None: return # Create/update entry in metadata self.cache_metadata[neuron_name] = params save_json(self.morphology_cache_metadata, self.cache_metadata, append=True) self.cache_metadata = load_json(self.morphology_cache_metadata) for neurite, actor in neuron_actors.items(): if actor is None: continue fl = os.path.join(self.morphology_cache, neuron_name + "_" + neurite + ".vtk") if isinstance(actor, list): if not actor: continue else: raise ValueError( "Something went wrong while saving the actor") actor.write(fl)
def _get_data(self): """ Loads data and metadata for the C. elegans connectome. """ # Get subfolder with .obj files subdirs = get_subdirs(self.data_folder) if not subdirs: raise ValueError( "The data folder should include a subfolder which stores the neurons .obj files" ) try: self.objs_fld = [f for f in subdirs if "objs_smoothed" in f][0] except: raise FileNotFoundError( "Could not find subdirectory with .obj files") # Get filepath to each .obj self.neurons_files = [ f for f in listdir(self.objs_fld) if f.lower().endswith(".obj") ] # Get synapses and skeleton files try: skeletons_file = [ f for f in listdir(self.data_folder) if f.endswith("skeletons.json") ][0] except: raise FileNotFoundError( "Could not find file with neurons skeleton data") try: synapses_file = [ f for f in listdir(self.data_folder) if f.endswith("synapses.csv") ][0] except: raise FileNotFoundError("Could not find file with synapses data") # load data self.skeletons_data = load_json(skeletons_file) self.synapses_data = pd.read_csv(synapses_file, sep=";") # Get neurons metadata try: metadata_file = [ f for f in listdir(self.data_folder) if "neuron_metadata.csv" in f ][0] except: raise FileNotFoundError( f"Could not find neurons metadata file {metadata_file}") self.neurons_metadata = pd.read_csv(metadata_file) self.neurons_names = list(self.neurons_metadata.neuron.values)
def __init__(self, scene=None, render_neurites=True, mirror=False, neurite_radius=None, color_by_region=False, force_to_hemisphere=None, base_dir=None, render_dendrites=True, render_axons=True, color_neurites=True, axon_color=None, soma_color=None, dendrites_color=None, random_color=False, **kwargs): """ Set up variables used for rendering :param scene: instance of class brainrender.Scene (Default value = None) :param render_neurites: Bool, If true, axons and dendrites are rendered (Default value = True) :param render_dendrites: Bool, if render neurites is true and this is false dendrites are not rendred :param render_axons: Bool, if render neurites is true and this is false axons are not rendred :param neurite_radius: float with radius of axons and dendrites. If None default is used. (Default value = None) :param color_neurites: Bool, if True axons and neurites are colored differently from the soma (Default value = True) :param mirror: Bool if True neurons are mirrored so that there is a version in each hemisphere (Default value = None) :param soma_color: soma_color color of the neurons' soma. Also used for neurites if they are not to be colored differently (Default value = None) :param axon_color: color of the neurons' axon. If none or False, the soma's color is used. (Default value = None) :param dendrites_color: color of the neurons' dendrites. If none or False, the soma's color is used.(Default value = None) :param random_color: Bool, if True a random color is used for each neuron. (Default value = False) :param color_by_region: bool, if True, neurons are colored according to the Allen Brain Atlas color for the region the soma is in. (Default value = False) :param force_to_hemisphere: str, if 'left' or 'right' neurons are rendered in the selected hemisphere, if False or None they are rendered in the original hemisphere. (Default value = None) :param base_dir: path to directory to use for saving data (default value None) :param kwargs: can be used to pass path to individual data folders. See brainrender/Utils/paths_manager.py """ self.scene = scene # for the meaning of the arguments check self.render_neurons self.render_neurites = render_neurites self.render_dendrites = render_dendrites self.render_axons = render_axons self.neurite_radius = neurite_radius self.color_neurites = color_neurites self.axon_color = axon_color self.soma_color = soma_color self.dendrites_color = dendrites_color self.random_color = random_color self.mirror = mirror self.color_by_region = color_by_region self.force_to_hemisphere = force_to_hemisphere Paths.__init__(self, base_dir=base_dir, **kwargs) # Load cache metadata self.cache_metadata = load_json(self.morphology_cache_metadata)
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]
def render_neurons(self, ml_file, **kwargs): """ Given a file with JSON data about neuronal structures downloaded from the Mouse Light neurons browser website, this function creates VTKplotter actors that can be used to render the neurons, returns them as nested dictionaries. :param ml_file: str, path to a JSON file with neurons data :param **kwargs: see kwargs of NeuronsParser.__init__ :returns: actors [list] -- [list of dictionaries, each dictionary contains the VTK actors of one neuron] """ # parse options if "scene" in list(kwargs.keys()): self.scene = kwargs['scene'] if "render_neurites" in list(kwargs.keys()): self.render_neurites = kwargs['render_neurites'] if "neurite_radius" in list(kwargs.keys()): self.neurite_radius = kwargs['neurite_radius'] if "color_neurites" in list(kwargs.keys()): self.color_neurites = kwargs['color_neurites'] if "axon_color" in list(kwargs.keys()): self.axon_color = kwargs['axon_color'] if "soma_color" in list(kwargs.keys()): self.soma_color = kwargs['soma_color'] if "dendrites_color" in list(kwargs.keys()): self.dendrites_color = kwargs['dendrites_color'] if "random_color" in list(kwargs.keys()): self.random_color = kwargs['random_color'] if "mirror" in list(kwargs.keys()): self.mirror = kwargs['mirror'] if "force_to_hemisphere" in list(kwargs.keys()): self.force_to_hemisphere = kwargs['force_to_hemisphere'] if 'color_by_region' in list(kwargs.keys()): self.color_by_region = kwargs['color_by_region'] self.rendering_necessary = True # It won't be if we are dealing with a list of Allen .swc files # if mirror get mirror coordinates if self.mirror: self.mirror_coord = self.scene.get_region_CenterOfMass( 'root', unilateral=False)[2] else: self.mirror_coord = False self.mirror_ax = 'x' # Check neurite radius if self.neurite_radius is None: neurite_radius = DEFAULT_NEURITE_RADIUS # Load the data if isinstance(ml_file, (tuple, list)): checkfile = ml_file[0] is_iter = True neurons_names = [ os.path.split(f)[-1].split(".")[0] for f in ml_file ] else: checkfile = ml_file is_iter = False neurons_names = [os.path.split(ml_file)[-1].split(".")[0]] if ".swc" in checkfile.lower(): self.is_json = False data = self.handle_parsing_swc(ml_file, is_iter) else: self.is_json = True if not is_iter: data = load_json(checkfile) data = data["neurons"] else: data = [] for f in ml_file: fdata = load_json(f) data.extend(fdata['neurons']) if not self.rendering_necessary: return self.actors, self.regions else: # Render neurons self.n_neurons = len(data) self.actors, self.regions = [], [] if len(neurons_names) < self.n_neurons: name = neurons_names[0] neurons_names = [ name + "_{}".format(i) for i in range(self.n_neurons) ] # Loop over neurons for nn, neuron in enumerate(data): neuron_actors, soma_region = self.render_neuron( neuron, nn, neurons_names[nn]) self.actors.append(neuron_actors) self.regions.append(soma_region) return self.actors, self.regions