def test_colors(): if not isinstance(get_random_colormap(), str): raise ValueError cols = get_n_shades_of("green", 40) if not isinstance(cols, list): raise ValueError if len(cols) != 40: raise ValueError getColor("orange") getColor([1, 1, 1]) getColor("k") getColor("#ffffff") getColor(7) getColor(-7) getColorName("#ffffff") cols = colorMap([0, 1, 2]) if not isinstance(cols, (list, np.ndarray)): raise ValueError if len(cols) != 3: raise ValueError c = colorMap(3, vmin=-3, vmax=4) check_colors(cols) check_colors(c)
def get_colors(tags): colors = [] for n, (i, tag) in enumerate(tags.iterrows()): if 'Loom' in tag.event_type: cmap = CMAP elif 'US' in tag.event_type: cmap = CMAP2 elif 'None' in tag.event_type: cmap = CMAP3 else: raise NotImplementedError colors.append( colorMap(n, name=cmap.mpl_colormap, vmin=-1, vmax=len(tags) + 1)) return colors
def test_animated_scene(): # --------------------------------- Variables -------------------------------- # minalpha = 0.01 # transparency of background neurons darkcolor = "lightgray" # background neurons color N_FRAMES = 50 N_neurons = 4 # number of neurons to show in total, if -1 all neurons are shown but it might take a while to render them at first N_neurons_in_frame = ( 2 # number of neurons to be highlighted in a given frame ) N_frames_for_change = 15 # every N frames which neurons are shown changes # Variables to specify camera position at each frame zoom = np.linspace(1, 1.5, N_FRAMES) frac = np.zeros_like( zoom) # for camera transition, interpolation value between cameras frac[:10] = np.linspace(0, 1, 10) frac[10:] = np.linspace(1, 0, len(frac[10:])) # -------------------------------- Fetch data -------------------------------- # # Then we can download the files and save them as a .json file ml_api = MouseLightAPI() # Fetch metadata for neurons with some in the secondary motor cortex neurons_metadata = ml_api.fetch_neurons_metadata(filterby="soma", filter_regions=["MOs"]) neurons_files = ml_api.download_neurons(neurons_metadata[:N_neurons]) # ------------------------------- Create scene ------------------------------- # scene = Scene(display_inset=False, use_default_key_bindings=True) neurons_actors = scene.add_neurons(neurons_files, neurite_radius=12, alpha=0) # Create new cameras cam1 = buildcam(sagittal_camera) cam2 = buildcam( dict( position=[-16624.081, -33431.408, 33527.412], focal=[6587.835, 3849.085, 5688.164], viewup=[0.634, -0.676, -0.376], distance=51996.653, clipping=[34765.671, 73812.327], )) cam3 = buildcam( dict( position=[1862.135, -4020.792, -36292.348], focal=[6587.835, 3849.085, 5688.164], viewup=[0.185, -0.97, 0.161], distance=42972.44, clipping=[29629.503, 59872.10], )) # ------------------------------- Create frames ------------------------------ # # Create frames prev_neurons = [] for step in track(np.arange(N_FRAMES), total=N_FRAMES, description="Generating frames..."): if step % N_frames_for_change == 0: # change neurons every N framse # reset neurons from previous set of neurons for neuron in prev_neurons: for component, actor in neuron.items(): actor.alpha(minalpha) actor.color(darkcolor) prev_neurons = [] # highlight new neurons neurons = choices(neurons_actors, k=N_neurons_in_frame) for n, neuron in enumerate(neurons): color = colorMap(n, "Greens_r", vmin=-2, vmax=N_neurons_in_frame + 3) for component, actor in neuron.items(): actor.alpha(1) actor.color(color) prev_neurons.append(neuron) # Move scene camera between 3 cameras scene.plotter.moveCamera(cam1, cam2, frac[step]) if frac[step] == 1: cam1 = cam3 # Update rendered window time.sleep(0.1) scene.render(zoom=zoom[step], interactive=False, video=True) scene.close()
def _add_neurons_get_colors(self, neurons, color): """ Parses color argument for self.add_neurons :para, neurons: list of Neuron object or file paths... :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 """ N = len(neurons) colors = dict( soma=None, axon=None, dendrites=None, ) # If no color is passed, get random colors if color is None: cols = [self.default_neuron_color for n in np.arange(N)] colors = dict( soma=cols.copy(), axon=cols.copy(), dendrites=cols.copy(), ) else: if isinstance(color, str): # Deal with a a cmap being passed if color in _mapscales_cmaps: cols = [ colorMap(n, name=color, vmin=-2, vmax=N + 2) for n in np.arange(N) ] colors = dict( soma=cols.copy(), axon=cols.copy(), dendrites=cols.copy(), ) else: # Deal with a single color being passed cols = [getColor(color) for n in np.arange(N)] colors = dict( soma=cols.copy(), axon=cols.copy(), dendrites=cols.copy(), ) elif isinstance(color, dict): # Deal with a dictionary with color for each component if "soma" not in color.keys(): raise ValueError( f"When passing a dictionary as color argument, \ soma should be one fo the keys: {color}" ) dendrites_color = color.pop("dendrites", color["soma"]) axon_color = color.pop("axon", color["soma"]) colors = dict( soma=[color["soma"] for n in np.arange(N)], axon=[axon_color for n in np.arange(N)], dendrites=[dendrites_color for n in np.arange(N)], ) elif isinstance(color, (list, tuple)): # Check that the list content makes sense if len(color) != N: raise ValueError( "When passing a list of color arguments, the list length" + f" ({len(color)}) should match the number of neurons ({N})." ) if len(set([type(c) for c in color])) > 1: raise ValueError( "When passing a list of color arguments, all list elements" + " should have the same type (e.g. str or dict)") if isinstance(color[0], dict): # Deal with a list of dictionaries soma_colors, dendrites_colors, axon_colors = [], [], [] for col in color: if "soma" not in col.keys(): raise ValueError( f"When passing a dictionary as col argument, \ soma should be one fo the keys: {col}" ) dendrites_colors.append( col.pop("dendrites", col["soma"])) axon_colors.append(col.pop("axon", col["soma"])) soma_colors.append(col["soma"]) colors = dict( soma=soma_colors, axon=axon_colors, dendrites=dendrites_colors, ) else: # Deal with a list of colors colors = dict( soma=color.copy(), axon=color.copy(), dendrites=color.copy(), ) else: raise ValueError( f"Color argument passed is not valid. Should be a \ str, dict, list or None, not {type(color)}:{color}" ) # Check colors, if everything went well we should have N colors per entry for k, v in colors.items(): if len(v) != N: raise ValueError( f"Something went wrong while preparing colors. Not all \ entries have right length. We got: {colors}") return colors
n_trials = bss[0].shape[0] n_rois = len(bss) f, axarr = plt.subplots(nrows=6, ncols=4, sharex=True, sharey=False, figsize=(24, 10), num=name) f.suptitle(f'Baseline variability - {mouse} {sess}') axarr = axarr.flatten() # Plot each trial for each ROI colors = np.array([ colorMap(i, 'Reds', vmin=-4, vmax=n_trials + 4) for i in np.arange(n_trials) ]) # Get means for speed and X baselines x, spd = behaviour_baselines[name] x, spd = np.nanmean(x, 1), np.nanmean(spd, 1) rois_means = [] # used for PCA for n, (ax, bs) in enumerate(zip(axarr, bss)): # get rois data means = np.array([np.mean(b) for b in bs]) rois_means.append(means) stds = np.array([np.std(b) * 2 for b in bs]) sortidx = np.argsort(means)[::-1]
def edit_neurons(neurons, **kwargs): """ Modify neurons actors after they have been created, at render time. neurons should be a list of dictionaries with soma, dendrite and axon actors of each neuron. :param neurons: list of dictionaries with vtk actors for each neuron :param **kwargs: """ soma_color, axon_color, dendrites_color = None, None, None for neuron in neurons: if "random_color" in kwargs: if kwargs["random_color"]: if not isinstance(kwargs["random_color"], str): color = get_random_colors(n_colors=1) else: # random_color is a colormap color = colorMap(np.random.randint(1000), name=kwargs["random_color"], vmin=0, vmax=1000) axon_color = soma_color = dendrites_color = color elif "color_neurites" in kwargs: soma_color = neuron["soma"].color() if not kwargs["color_neurites"]: axon_color = dendrites_color = soma_color else: if not "axon_color" in kwargs: # print("no axon color provided, using somacolor") axon_color = soma_color else: axon_color = kwargs["axon_color"] if not "dendrites_color" in kwargs: # print("no dendrites color provided, using somacolor") dendrites_color = soma_color else: dendrites_color = kwargs["dendrites_color"] elif "soma_color" in kwargs: if check_colors(kwargs["soma_color"]): soma_color = kwargs["soma_color"] else: print("Invalid soma color provided") soma_color = neuron["soma"].color() elif "axon_color" in kwargs: if check_colors(kwargs["axon_color"]): axon_color = kwargs["axon_color"] else: print("Invalid axon color provided") axon_color = neuron["axon"].color() elif "dendrites_color" in kwargs: if check_colors(kwargs["dendrites_color"]): dendrites_color = kwargs["dendrites_color"] else: print("Invalid dendrites color provided") dendrites_color = neuron["dendrites"].color() if soma_color is not None: neuron["soma"].color(soma_color) if axon_color is not None: neuron["axon"].color(axon_color) if dendrites_color is not None: neuron["dendrites"].color(dendrites_color) if "mirror" in kwargs: if "mirror_coord" in kwargs: mcoord = kwargs["mirror_coord"] else: raise ValueError("Need to pass the mirror point coordinate") # mirror X positoin for name, actor in neuron.items(): if "only_soma" in kwargs: if kwargs["only_soma"] and name != "soma": continue # get mesh points coords and shift them to other hemisphere if isinstance(actor, list): continue coords = actor.points() shifted_coords = [[c[0], c[1], mcoord + (mcoord - c[2])] for c in coords] actor.points(shifted_coords) neuron[name] = actor.mirror(axis='n') return neurons
def _render_neuron_get_params(self, neuron_number, neuron=None, soma_region=None, soma=None): """ Makes sure that all the parameters to specify how neurons should be rendered. :param neuron_number: number of the neuron being rendered :param neuron: neuron's metadata (Default value = None) :param soma_region: str with the acronym of the region the soma is in (Default value = None) :param soma: list with XYZ coordinates of the neuron's soma. (Default value = 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 isinstance(neuron, dict): self.alleninfo = None soma_region = self.scene.get_structure_from_coordinates( get_coords(neuron['soma'])) else: self.alleninfo = None soma_region = None elif soma_region is None: self.alleninfo = None if soma is not None: soma_region = self.scene.get_structure_from_coordinates( get_coords(soma)) 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
total=N_FRAMES, description="Generating frames..."): if step % N_frames_for_change == 0: # change neurons every N framse # reset neurons from previous set of neurons for neuron in prev_neurons: for component, actor in neuron.items(): actor.alpha(minalpha) actor.color(darkcolor) prev_neurons = [] # highlight new neurons neurons = choices(neurons, k=N_neurons_in_frame) for n, neuron in enumerate(neurons): color = colorMap(n, "Greens_r", vmin=-2, vmax=N_neurons_in_frame + 3) for component, actor in neuron.items(): actor.alpha(1) actor.color(color) prev_neurons.append(neuron) # Move scene camera between 3 cameras scene.plotter.moveCamera(cam1, cam2, frac[step]) if frac[step] == 1: cam1 = cam3 # Update rendered window time.sleep(0.1) scene.render(zoom=zoom[step], interactive=False, video=True)
def get_neurons(self, neurons, color=None, display_axon=True, display_dendrites=True, alpha=1, neurite_radius=None): """ Gets rendered morphological data of neurons reconstructions downloaded from the Mouse Light project at Janelia (or other sources). Accepts neurons argument as: - file(s) with morphological data - vtkplotter 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 """ if not isinstance(neurons, (list, tuple)): neurons = [neurons] # ------------------------------ Prepare colors ------------------------------ # N = len(neurons) colors = dict( soma = None, axon = None, dendrites = None, ) # If no color is passed, get random colors if color is None: cols = get_random_colors(N) colors = dict( soma = cols.copy(), axon = cols.copy(), dendrites = cols.copy(),) else: if isinstance(color, str): # Deal with a a cmap being passed if color in _mapscales_cmaps: cols = [colorMap(n, name=color, vmin=-2, vmax=N+2) for n in np.arange(N)] colors = dict( soma = cols.copy(), axon = cols.copy(), dendrites = cols.copy(),) else: # Deal with a single color being passed cols = [getColor(color) for n in np.arange(N)] colors = dict( soma = cols.copy(), axon = cols.copy(), dendrites = cols.copy(),) elif isinstance(color, dict): # Deal with a dictionary with color for each component if not 'soma' in color.keys(): raise ValueError(f"When passing a dictionary as color argument, \ soma should be one fo the keys: {color}") dendrites_color = color.pop('dendrites', color['soma']) axon_color = color.pop('axon', color['soma']) colors = dict( soma = [color['soma'] for n in np.arange(N)], axon = [axon_color for n in np.arange(N)], dendrites = [dendrites_color for n in np.arange(N)],) elif isinstance(color, (list, tuple)): # Check that the list content makes sense if len(color) != N: raise ValueError(f"When passing a list of color arguments, the list length"+ f" ({len(color)}) should match the number of neurons ({N}).") if len(set([type(c) for c in color])) > 1: raise ValueError(f"When passing a list of color arguments, all list elements"+ " should have the same type (e.g. str or dict)") if isinstance(color[0], dict): # Deal with a list of dictionaries soma_colors, dendrites_colors, axon_colors = [], [], [] for col in colors: if not 'soma' in col.keys(): raise ValueError(f"When passing a dictionary as col argument, \ soma should be one fo the keys: {col}") dendrites_colors.append(col.pop('dendrites', col['soma'])) axon_colors.append(col.pop('axon', col['soma'])) soma_colors.append(col['soma']) colors = dict( soma = soma_colors, axon = axon_colors, dendrites = dendrites_colors,) else: # Deal with a list of colors colors = dict( soma = color.copy(), axon = color.copy(), dendrites = color.copy(),) else: raise ValueError(f"Color argument passed is not valid. Should be a \ str, dict, list or None, not {type(color)}:{color}") # Check colors, if everything went well we should have N colors per entry for k,v in colors.items(): if len(v) != N: raise ValueError(f"Something went wrong while preparing colors. Not all \ entries have right length. We got: {colors}") # ---------------------------------- 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_ctors['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 vtkplotter 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]) # Return if len(_neurons_actors) == 1: return _neurons_actors[0], None elif not _neurons_actors: return None, None else: return _neurons_actors, None