Beispiel #1
0
def getExperiment(cell_id, stimtypes):
    ctc = CellTypesCache()
    ephys_sweeps = ctc.get_ephys_sweeps(specimen_id=cell_id)
    sweeps_by_type = defaultdict(list)
    sweeps = []
    for sweep in ephys_sweeps:
        if sweep['stimulus_name'] in stimtypes:
            sweeps.append(sweep['sweep_number'])
            sweeps_by_type[sweep['stimulus_name']].append(
                sweep['sweep_number'])

    ephys_filename = f'{cell_id}/{cell_id}_ephys.nwb'
    ctc.get_ephys_data(cell_id, ephys_filename)
    swc_filename = f'{cell_id}/{cell_id}.swc'
    ctc.get_reconstruction(cell_id, swc_filename)
    return ephys_filename, swc_filename, sweeps, sweeps_by_type
Beispiel #2
0
class AllenMorphology(Paths):
    def __init__(self, *args, **kwargs):
        if not connected_to_internet():
            raise ConnectionError("You will need to be connected to the internet to use the AllenMorphology class")

        Paths.__init__(self, *args, **kwargs)

        # Create a Cache for the Cell Types Cache API
        self.ctc = CellTypesCache(manifest_file=os.path.join(self.morphology_allen, 'manifest.json'))

        # Get a list of cell metadata for neurons with reconstructions, download if necessary
        self.neurons = pd.DataFrame(self.ctc.get_cells(species=[CellTypesApi.MOUSE], require_reconstruction = True))
        self.n_neurons = len(self.neurons)
        if not self.n_neurons: raise ValueError("Something went wrong and couldn't get neurons metadata from Allen")

        self.downloaded_neurons = self.get_downloaded_neurons()

    def get_downloaded_neurons(self):
        return [os.path.join(self.morphology_allen, f) for f in os.listdir(self.morphology_allen) if ".swc" in f]    

    def download_neurons(self, ids):
        if isinstance(ids, np.ndarray):
            ids = list(ids)
        if not isinstance(ids, (list)): ids = [ids]

        for neuron_id in ids:
            neuron_file = os.path.join(self.morphology_allen, "{}.swc".format(neuron_id))
            neuron = self.ctc.get_reconstruction(neuron_id, file_name=neuron_file)
def get_cell_morphXYZ(cell_id):

    from allensdk.core.cell_types_cache import CellTypesCache
    from allensdk.core.swc import Marker
    import pprint

    ctc = CellTypesCache(manifest_file='cell_types/manifest.json')
    morph = ctc.get_reconstruction(cell_id)

    markers = ctc.get_reconstruction_markers(cell_id)

    x = []
    y = []
    z = []
    for n in morph.compartment_list:
        #print(n['type']) #type=1, soma; type=2, axon; type=3, dendrite; type=4,apical dendrite
        if n['type'] == 4 or n['type'] == 3 or n['type'] == 1:
            x.append(n['x'] - morph.soma["x"])
            y.append(n['y'] - morph.soma["y"])
            z.append(n['z'] - morph.soma["z"])

    morph_data = np.array(np.column_stack((x, y, z)))
    morph_soma = [morph.soma["x"], morph.soma["y"], morph.soma["z"]]

    return (morph_data, morph_soma)
def load_realdata_morphology(cell_id = 464212183, desample_tree_factor=30):

    from allensdk.core.cell_types_cache import CellTypesCache
    # load real data
    ctc = CellTypesCache(manifest_file='cell_types/manifest.json')
    # load 3D morphology data
    morphology = ctc.get_reconstruction(cell_id)
    # extract
    compartments = morphology.compartment_list
    compartments_byid = { c['id']: c for c in compartments}

    num_children = np.array([len(c['children'])  for c in compartments])
    branch_indexes = np.where(num_children>1)[0] # branch compartment index

    # find all paths (terminate at branches)
    paths = find_branch_paths(compartments_byid, branch_indexes)

    # de-sample tree and paths
    select_compartments = [] # index selected
    path_compartments = [] # every connections between selected compartments (not limited to branches)
    path_filtered = [] #per branch, only keep selected one
    for k, path in enumerate(paths):
        n = len(path)
        if n < desample_tree_factor:
            select_compartments.extend([path[0], path[-1]])
            path_compartments.append([path[0], path[-1]])
            path_filtered.append([path[0], path[-1]])
        else:
            use = [path[int(i)] for i in np.linspace(0, n - 1, n//desample_tree_factor+1)]
            path_filtered.append(use)
            select_compartments.extend(use)
            for j in range(len(use) - 1):
                path_compartments.append([use[j], use[j+1]])
    select_compartments = np.unique(select_compartments)

    assert len(np.setdiff1d(branch_indexes, select_compartments)) == 0

    # map old id to new id
    new_id = {select_compartments[i]:i for i in range(len(select_compartments))}

    # calculate distance between selected compartments
    from numpy import linalg as LA
    C = len(select_compartments)
    dist = np.full((C, C), np.inf)

    for path in path_compartments:
        ID1, xyz1, _ = get_info(compartments_byid[path[0]])
        ID2, xyz2, _ = get_info(compartments_byid[path[1]])
        dist[new_id[path[0]], new_id[path[1]]] = LA.norm(xyz1 - xyz2, 2)
        dist[new_id[path[1]], new_id[path[0]]] = dist[new_id[path[0]], new_id[path[1]]]

    network = 1/dist
    return network, new_id, compartments_byid, paths, select_compartments, path_compartments, path_filtered, compartments, morphology
def cell_morphology_rot(cell_id, x_soma, y_soma, z_soma, theta):

    theta_z = theta[2]
    theta_y = theta[1]
    theta_x = theta[0]

    # download and open an SWC file
    ctc = CellTypesCache(manifest_file='cell_types/manifest.json')
    morph = ctc.get_reconstruction(cell_id)

    #First applying a rotation angle around z axis
    tr_rot_z = [
        math.cos(theta_z), -math.sin(theta_z), 0,
        math.sin(theta_z),
        math.cos(theta_z), 0, 0, 0, 1, 0, 0, 0
    ]

    #Second applying a rotation angle around y axis
    tr_rot_y = [
        math.cos(theta_y), 0,
        math.sin(theta_y), 0, 1, 0, -math.sin(theta_y), 0,
        math.cos(theta_y), 0, 0, 0
    ]

    #Third applying a rotation angle around x axis
    tr_rot_x = [
        1, 0, 0, 0,
        math.cos(theta_x), -math.sin(theta_x), 0,
        math.sin(theta_x),
        math.cos(theta_x), 0, 0, 0
    ]

    morph.apply_affine(tr_rot_z)
    morph.apply_affine(tr_rot_y)
    morph.apply_affine(tr_rot_x)

    # translate the soma location
    tr_soma = [
        1, 0, 0, 0, 1, 0, 0, 0, 1, -morph.soma["x"] + x_soma,
        -morph.soma["y"] + y_soma, -morph.soma["z"] + z_soma
    ]
    morph.apply_affine(tr_soma)

    # plot xy and xz views
    #   fig, axes = plt.subplots(1, 2, sharey=True, sharex=True)
    #    vm.plot_morph_swc(morph,axes,color='r')

    # fig, axes = plt.subplots(1, 2, sharey=True, sharex=True)

    # Make a line drawing of x-y and y-z views
    return morph
Beispiel #6
0
def main_specimen():
    from allensdk.core.cell_types_cache import CellTypesCache
    specimen_id = 485880739

    ctc = CellTypesCache()
    morphology = ctc.get_reconstruction(specimen_id)

    for c in morphology.compartment_list:
        c['z'] *= 3

    tube_pd = vtkmorph.generate_tube(morphology.compartment_index,
                                     morphology.root,
                                     color_by_type,
                                     6,
                                     radius=1.5)
    vtkmorph.write_ply(tube_pd, '%d.ply' % specimen_id)
    vtkmorph.write_vtk(tube_pd, '%d.vtk' % specimen_id)
#===============================================================================
# example 1
#===============================================================================

from allensdk.core.cell_types_cache import CellTypesCache

ctc = CellTypesCache(manifest_file='cell_types/manifest.json')

# a list of cell metadata for cells with reconstructions, download if necessary
cells = ctc.get_cells(require_reconstruction=True)

# open the electrophysiology data of one cell, download if necessary
data_set = ctc.get_ephys_data(cells[0]['id'])

# read the reconstruction, download if necessary
reconstruction = ctc.get_reconstruction(cells[0]['id'])

#===============================================================================
# example 2
#===============================================================================

from allensdk.core.cell_types_cache import CellTypesCache
from allensdk.ephys.extract_cell_features import extract_cell_features
from collections import defaultdict

# initialize the cache
ctc = CellTypesCache(manifest_file='cell_types/manifest.json')

# pick a cell to analyze
specimen_id = 324257146
Beispiel #8
0
# In[6]:

meta_and_morph_df = all_cells_df.join(morphology_df)
meta_and_morph_df.head()

# In[7]:

meta_and_morph_df.columns

# You can also acesss morphology of a single cell by exectuing the `get_recontruction()` method on your instance of the cells type cache. To do so, you must specify what cell you want to recontruct by inputing a `specimen_id`. This method returns a class instance with methods for accessing morphology compartments.

# In[8]:

cell_id = 478107198
single_cell_morphology = ctc.get_reconstruction(specimen_id=cell_id)

#help(single_cell_morphology)

# In[9]:

import matplotlib.pyplot as plt

# In[10]:

single_cell_morphology.soma

# Note that the type field refers to the type of neuronal compartment. The values can be 1 for the soma, 2 for the axon, 3 for dendrites, and 4 for apical dendrites (if present).

# Morphologies now also come with marker files, which contains points of interest in the reconstruction. The marker file contains locations where dendrites have been truncated due to slicing and when axons were not reconstructed. The name field indicates the type of marker (10 for dendrite truncation, 20 for no reconstruction).
Beispiel #9
0
class AllenMorphology(Paths):
    """ Handles the download and visualisation of neuronal morphology data from the Allen database. """
    def __init__(self, *args, scene_kwargs={}, **kwargs):
        """
			Initialise API interaction and fetch metadata of neurons in the Allen Database. 
		"""
        if not connected_to_internet():
            raise ConnectionError(
                "You will need to be connected to the internet to use the AllenMorphology class"
            )

        Paths.__init__(self, *args, **kwargs)
        self.scene = Scene(add_root=False, display_inset=False, **scene_kwargs)

        # Create a Cache for the Cell Types Cache API
        self.ctc = CellTypesCache(
            manifest_file=os.path.join(self.morphology_allen, 'manifest.json'))

        # Get a list of cell metadata for neurons with reconstructions, download if necessary
        self.neurons = pd.DataFrame(
            self.ctc.get_cells(species=[CellTypesApi.MOUSE],
                               require_reconstruction=True))
        self.n_neurons = len(self.neurons)
        if not self.n_neurons:
            raise ValueError(
                "Something went wrong and couldn't get neurons metadata from Allen"
            )

        self.downloaded_neurons = self.get_downloaded_neurons()

    def get_downloaded_neurons(self):
        """ 
			Get's the path to files of downloaded neurons
		"""
        return [
            os.path.join(self.morphology_allen, f)
            for f in os.listdir(self.morphology_allen) if ".swc" in f
        ]

    def download_neurons(self, ids):
        """
			Download neurons

		:param ids: list of integers with neurons IDs

		"""
        if isinstance(ids, np.ndarray):
            ids = list(ids)
        if not isinstance(ids, (list)): ids = [ids]

        neurons = []
        for neuron_id in ids:
            neuron_file = os.path.join(self.morphology_allen,
                                       "{}.swc".format(neuron_id))
            neurons.append(
                self.ctc.get_reconstruction(neuron_id, file_name=neuron_file))

        return neurons

    def parse_neurons_swc_allen(self, morphology, color='blackboard', alpha=1):
        """
		SWC parser for Allen neuron's morphology data, they're a bit different from the Mouse Light SWC

		:param morphology: data with morphology
		:param neuron_number: int, number of the neuron being rendered.

		"""
        # Create soma actor
        radius = 1
        neuron_actors = [
            shapes.Sphere(pos=get_coords(morphology.soma)[::-1],
                          c=color,
                          r=radius * 3)
        ]

        # loop over trees
        for tree in morphology._tree_list:

            tree = pd.DataFrame(tree)
            branching_points = [
                t.id for i, t in tree.iterrows()
                if len(t.children) > 2 and t.id < len(tree)
            ]

            branch_starts = []
            for bp in branching_points:
                branch_starts.extend(tree.iloc[bp].children)

            for bp in branch_starts:
                parent = tree.iloc[tree.iloc[bp].parent]
                branch = [(parent.x, parent.y, parent.z)]
                point = tree.iloc[bp]

                while True:
                    branch.append((point.x, point.y, point.z))

                    if not point.children:
                        break
                    else:
                        try:
                            point = tree.iloc[point.children[0]]
                        except:
                            break

                # Create actor
                neuron_actors.append(
                    shapes.Tube(branch, r=radius, c='red', alpha=1, res=24))

        actor = merge(*neuron_actors)
        actor.color(color)
        actor.alpha(alpha)
        return actor

    # # Todo load/save neurons??
    def load_save_neuron(self, neuron_file, neuron=None):
        neuron_name = os.path.split(neuron_file)[-1].split('.swc')[0]

        savepath = os.path.join(self.morphology_cache, neuron_name + '.vtk')

        if neuron is None and os.path.isfile(savepath):
            return load(savepath)
        elif neuron is None:
            return None
        elif neuron is not None:
            neuron.write(savepath)

    def parse_neuron_swc(self,
                         filepath,
                         color='blackboard',
                         alpha=1,
                         radius_multiplier=.1,
                         overwrite=False):
        """
		Given an swc file, render the neuron

		:param filepath: str with path to swc file
		:param neuron_number: numnber of neuron being rendered

		"""
        # See if we rendered this neuron already
        if not overwrite:
            loaded = self.load_save_neuron(filepath)
            if loaded is not None:
                return loaded.color(color)

        print(f"Parsing swc file: {filepath}")
        # details on swc files: http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html
        _sample = namedtuple("sample", "sampleN structureID x y z r parent"
                             )  # sampleN structureID x y z r parent

        if not os.path.isfile(filepath) or not ".swc" in filepath.lower():
            raise ValueError("unrecognized file path: {}".format(filepath))

        try:
            return self.parse_neurons_swc_allen(filepath)
        except:
            pass  #  the .swc file fas not generate with by allen

        f = open(filepath)
        content = f.readlines()
        f.close()
        content = [
            sample.replace("\n", "") for sample in content if sample[0] != '#'
        ]
        content = [sample for sample in content if len(sample) > 3]

        # crate empty dicts for soma axon and dendrites
        data = dict(id=[],
                    parentNumber=[],
                    radius=[],
                    sampleNumber=[],
                    x=[],
                    y=[],
                    z=[])

        # start looping around samples
        for sample in content:
            s = _sample(
                *[float(samp) for samp in sample.lstrip().rstrip().split(" ")])

            # append data to dictionary
            data['id'] = s.structureID
            data['parentNumber'].append(int(s.parent))
            data['radius'].append(s.r)
            data['x'].append(s.x)
            data['y'].append(s.y)
            data['z'].append(s.z)
            data['sampleNumber'].append(int(s.sampleN))

        # Get branches and soma
        print("		reconstructing neurites trees")
        data = pd.DataFrame(data)
        radius = data['radius'].values[0] * radius_multiplier

        soma = data.iloc[0]
        soma = shapes.Sphere(pos=[soma.x, soma.y, soma.z],
                             c=color,
                             r=radius * 4)
        neuron_actors = [soma]

        branches_end, branches_start = [], []  # Get branches start and end
        for parent in data.parentNumber.values:
            sons = data.loc[data.parentNumber == parent]
            if len(sons) > 1:
                branches_end.append(parent)
                for i, son in sons.iterrows():
                    branches_start.append(son.sampleNumber)

        print("		creating actors")
        for start in branches_start:
            node = data.loc[data.sampleNumber == start]
            parent = data.loc[data.sampleNumber == node.parentNumber.values[0]]

            branch = [(parent.x.values[0], parent.y.values[0],
                       parent.z.values[0])]
            while True:
                branch.append(
                    (node.x.values[0], node.y.values[0], node.z.values[0]))

                node = data.loc[data.parentNumber ==
                                node.sampleNumber.values[0]]
                if not len(node): break
                if node.sampleNumber.values[0] in branches_end:
                    branch.append(
                        (node.x.values[0], node.y.values[0], node.z.values[0]))
                    break

            neuron_actors.append(
                shapes.Tube(branch, r=radius, c='red', alpha=1, res=24))

        # Merge actors and save
        actor = merge(*neuron_actors)
        actor.color(color)
        actor.alpha(alpha)

        self.load_save_neuron(filepath, neuron=actor)
        return actor

    def add_neuron(self,
                   neuron,
                   shadow_axis=None,
                   shadow_offset=-20,
                   **kwargs):
        if isinstance(neuron, list):
            neurons = neuron
        else:
            if isinstance(neuron, str):
                if os.path.isdir(neuron):
                    neurons = listdir(neuron)
            else:
                neurons = [neuron]

        actors = []
        for neuron in neurons:
            if isinstance(neuron, str):
                neuron = self.parse_neuron_swc(neuron, **kwargs)
            elif isinstance(neuron, Morphology):
                neuron = self.parse_neurons_swc_allen(neuron, **kwargs)

            actor = self.scene.add_vtkactor(neuron)

            # scals = actor.points()[:, 1]
            # alphas = np.linspace(0.82, .83, 250)
            # actor.pointColors(scals, alpha=alphas, cmap="Greens_r")

            # actor.points()[:, 0] += np.random.normal(0, 2000)
            # actor.points()[:, 2] += np.random.normal(0, 2000)

            if shadow_axis == 'x':
                actor.addShadow(x=shadow_offset)
            elif shadow_axis == 'y':
                actor.addShadow(y=shadow_offset)
            elif shadow_axis == 'z':
                actor.addShadow(z=shadow_offset)

            actors.append(neuron)

        return actors

    def render(self, **kwargs):
        self.scene.render(**kwargs)
Beispiel #10
0
from allensdk.core.cell_types_cache import CellTypesCache

ctc = CellTypesCache()

# a list of cell metadata for cells with reconstructions, download if necessary
cells = ctc.get_cells(require_reconstruction=True)

# open the electrophysiology data of one cell, download if necessary
data_set = ctc.get_ephys_data(cells[0]['id'])

# read the reconstruction, download if necessary
reconstruction = ctc.get_reconstruction(cells[0]['id'])
Beispiel #11
0
def data_for_specimen_id(specimen_id,
                         sweep_qc_option,
                         data_source,
                         ap_window_length=0.005,
                         target_sampling_rate=50000):
    logging.debug("specimen_id: {}".format(specimen_id))

    # Find or retrieve NWB file and ancillary info and construct an AibsDataSet object
    ontology = StimulusOntology(
        ju.read(StimulusOntology.DEFAULT_STIMULUS_ONTOLOGY_FILE))
    if data_source == "lims":
        nwb_path, h5_path = lims_nwb_information(specimen_id)
        if type(nwb_path) is dict and "error" in nwb_path:
            logging.warning(
                "Problem getting NWB file for specimen {:d} from LIMS".format(
                    specimen_id))
            return nwb_path

        try:
            data_set = AibsDataSet(nwb_file=nwb_path,
                                   h5_file=h5_path,
                                   ontology=ontology)
        except Exception as detail:
            logging.warning(
                "Exception when loading specimen {:d} from LIMS".format(
                    specimen_id))
            logging.warning(detail)
            return {
                "error": {
                    "type": "dataset",
                    "details": traceback.format_exc(limit=None)
                }
            }
    elif data_source == "sdk":
        ctc = CellTypesCache()

        morph = ctc.get_reconstruction(specimen_id)
        morph_table = ctc.get_morphology_features(specimen_id)
        morph_table.to_csv('cell_types\\specimen_' + str(specimen_id) + '\\' +
                           'morphology_features.csv')

        print("morph dl failed")
        nwb_path, sweep_info = sdk_nwb_information(specimen_id)
        try:
            data_set = AibsDataSet(nwb_file=nwb_path,
                                   sweep_info=sweep_info,
                                   ontology=ontology)
        except Exception as detail:
            logging.warning(
                "Exception when loading specimen {:d} via Allen SDK".format(
                    specimen_id))
            logging.warning(detail)
            return {
                "error": {
                    "type": "dataset",
                    "details": traceback.format_exc(limit=None)
                }
            }
    else:
        logging.error("invalid data source specified ({})".format(data_source))

    # Identify and preprocess long square sweeps
    try:
        lsq_sweep_numbers = categorize_iclamp_sweeps(
            data_set,
            ontology.long_square_names,
            sweep_qc_option=sweep_qc_option,
            specimen_id=specimen_id)
        (lsq_sweeps, lsq_features, lsq_start, lsq_end,
         lsq_spx) = preprocess_long_square_sweeps(data_set, lsq_sweep_numbers)
    except Exception as detail:
        logging.warning(
            "Exception when preprocessing long square sweeps from specimen {:d}"
            .format(specimen_id))
        logging.warning(detail)
        return {
            "error": {
                "type": "sweep_table",
                "details": traceback.format_exc(limit=None)
            }
        }

    # Identify and preprocess short square sweeps
    try:
        ssq_sweep_numbers = categorize_iclamp_sweeps(
            data_set,
            ontology.short_square_names,
            sweep_qc_option=sweep_qc_option,
            specimen_id=specimen_id)
        ssq_sweeps, ssq_features = preprocess_short_square_sweeps(
            data_set, ssq_sweep_numbers)
    except Exception as detail:
        logging.warning(
            "Exception when preprocessing short square sweeps from specimen {:d}"
            .format(specimen_id))
        logging.warning(detail)
        return {
            "error": {
                "type": "sweep_table",
                "details": traceback.format_exc(limit=None)
            }
        }

    # Identify and preprocess ramp sweeps
    try:
        ramp_sweep_numbers = categorize_iclamp_sweeps(
            data_set,
            ontology.ramp_names,
            sweep_qc_option=sweep_qc_option,
            specimen_id=specimen_id)
        ramp_sweeps, ramp_features = preprocess_ramp_sweeps(
            data_set, ramp_sweep_numbers)
    except Exception as detail:
        logging.warning(
            "Exception when preprocessing ramp sweeps from specimen {:d}".
            format(specimen_id))
        logging.warning(detail)
        return {
            "error": {
                "type": "sweep_table",
                "details": traceback.format_exc(limit=None)
            }
        }

    # Calculate desired feature vectors
    result = {}

    (subthresh_hyperpol_dict, hyperpol_deflect_dict
     ) = fv.identify_subthreshold_hyperpol_with_amplitudes(
         lsq_features, lsq_sweeps)
    target_amps_for_step_subthresh = [-90, -70, -50, -30, -10]
    result["step_subthresh"] = fv.step_subthreshold(
        subthresh_hyperpol_dict,
        target_amps_for_step_subthresh,
        lsq_start,
        lsq_end,
        amp_tolerance=5)
    result["subthresh_norm"] = fv.subthresh_norm(subthresh_hyperpol_dict,
                                                 hyperpol_deflect_dict,
                                                 lsq_start, lsq_end)
    (subthresh_depol_dict,
     depol_deflect_dict) = fv.identify_subthreshold_depol_with_amplitudes(
         lsq_features, lsq_sweeps)
    result["subthresh_depol_norm"] = fv.subthresh_depol_norm(
        subthresh_depol_dict, depol_deflect_dict, lsq_start, lsq_end)
    isi_sweep, isi_sweep_spike_info = fv.identify_sweep_for_isi_shape(
        lsq_sweeps, lsq_features, lsq_end - lsq_start)
    result["isi_shape"] = fv.isi_shape(isi_sweep, isi_sweep_spike_info,
                                       lsq_end)

    # Calculate waveforms from each type of sweep
    spiking_ssq_sweep_list = [
        ssq_sweeps.sweeps[swp_ind]
        for swp_ind in ssq_features["common_amp_sweeps"].index
    ]
    spiking_ssq_info_list = [
        ssq_features["spikes_set"][swp_ind]
        for swp_ind in ssq_features["common_amp_sweeps"].index
    ]
    ssq_ap_v, ssq_ap_dv = fv.first_ap_vectors(
        spiking_ssq_sweep_list,
        spiking_ssq_info_list,
        target_sampling_rate=target_sampling_rate,
        window_length=ap_window_length,
        skip_clipped=True)

    rheo_ind = lsq_features["rheobase_sweep"].name
    sweep = lsq_sweeps.sweeps[rheo_ind]
    lsq_ap_v, lsq_ap_dv = fv.first_ap_vectors(
        [sweep], [lsq_features["spikes_set"][rheo_ind]],
        target_sampling_rate=target_sampling_rate,
        window_length=ap_window_length)

    spiking_ramp_sweep_list = [
        ramp_sweeps.sweeps[swp_ind]
        for swp_ind in ramp_features["spiking_sweeps"].index
    ]
    spiking_ramp_info_list = [
        ramp_features["spikes_set"][swp_ind]
        for swp_ind in ramp_features["spiking_sweeps"].index
    ]
    ramp_ap_v, ramp_ap_dv = fv.first_ap_vectors(
        spiking_ramp_sweep_list,
        spiking_ramp_info_list,
        target_sampling_rate=target_sampling_rate,
        window_length=ap_window_length,
        skip_clipped=True)

    # Combine so that differences can be assessed by analyses like sPCA
    result["first_ap_v"] = np.hstack([ssq_ap_v, lsq_ap_v, ramp_ap_v])
    result["first_ap_dv"] = np.hstack([ssq_ap_dv, lsq_ap_dv, ramp_ap_dv])

    target_amplitudes = np.arange(0, 120, 20)
    supra_info_list = fv.identify_suprathreshold_spike_info(lsq_features,
                                                            target_amplitudes,
                                                            shift=10)
    result["psth"] = fv.psth_vector(supra_info_list, lsq_start, lsq_end)
    result["inst_freq"] = fv.inst_freq_vector(supra_info_list, lsq_start,
                                              lsq_end)

    spike_feature_list = [
        "upstroke_downstroke_ratio",
        "peak_v",
        "fast_trough_v",
        "threshold_v",
        "width",
    ]
    for feature in spike_feature_list:
        result["spiking_" + feature] = fv.spike_feature_vector(
            feature, supra_info_list, lsq_start, lsq_end)

    return result
Beispiel #12
0
class AllenMorphology(Paths):
    """ Handles the download of neuronal morphology data from the Allen database. """
    def __init__(self, *args, **kwargs):
        """
            Initialise API interaction and fetch metadata of neurons in the Allen Database. 
        """
        if not connected_to_internet():
            raise ConnectionError(
                "You will need to be connected to the internet to use the AllenMorphology class to download neurons"
            )

        Paths.__init__(self, *args, **kwargs)

        # Create a Cache for the Cell Types Cache API
        self.ctc = CellTypesCache(manifest_file=os.path.join(
            self.allen_morphology_cache, "manifest.json"))

        # Get a list of cell metadata for neurons with reconstructions, download if necessary
        self.neurons = pd.DataFrame(
            self.ctc.get_cells(species=[CellTypesApi.MOUSE],
                               require_reconstruction=True))
        self.n_neurons = len(self.neurons)

        if not self.n_neurons:
            raise ValueError(
                "Something went wrong and couldn't get neurons metadata from Allen"
            )

        self.downloaded_neurons = self.get_downloaded_neurons()

    def get_downloaded_neurons(self):
        """ 
            Get's the path to files of downloaded neurons
        """
        return [
            os.path.join(self.allen_morphology_cache, f)
            for f in os.listdir(self.allen_morphology_cache) if ".swc" in f
        ]

    def download_neurons(self, ids, **kwargs):
        """
            Download neurons and return neuron reconstructions (instances
            of Neuron class)

        :param ids: list of integers with neurons IDs

        """
        if isinstance(ids, np.ndarray):
            ids = list(ids)
        if not isinstance(ids, (list)):
            ids = [ids]

        neurons = []
        print("Downloading neurons")
        for neuron_id in track(ids):
            neuron_file = os.path.join(self.allen_morphology_cache,
                                       "{}.swc".format(neuron_id))

            # Download file
            self.ctc.get_reconstruction(neuron_id, file_name=neuron_file)

            # Reconstruct neuron
            neurons.append(
                Neuron(neuron_file, neuron_name=str(neuron_id), **kwargs))

        return neurons