Source code for allensdk.api.queries.cell_types_api

# Allen Institute Software License - This software license is the 2-clause BSD
# license plus a third clause that prohibits redistribution for commercial
# purposes without further permission.
#
# Copyright 2015-2016. Allen Institute. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Redistributions for commercial purposes are not permitted without the
# Allen Institute's written permission.
# For purposes of this license, commercial purposes is the incorporation of the
# Allen Institute's software into anything for which you will charge fees or
# other compensation. Contact terms@alleninstitute.org for commercial licensing
# opportunities.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
from .rma_api import RmaApi
from ..cache import cacheable
from allensdk.config.manifest import Manifest
from allensdk.api.cache import Cache
from allensdk.deprecated import deprecated


[docs]class CellTypesApi(RmaApi): NWB_FILE_TYPE = 'NWBDownload' SWC_FILE_TYPE = '3DNeuronReconstruction' MARKER_FILE_TYPE = '3DNeuronMarker' MOUSE = 'Mus musculus' HUMAN = 'Homo Sapiens' def __init__(self, base_uri=None): super(CellTypesApi, self).__init__(base_uri)
[docs] @cacheable() def list_cells_api(self, id=None, require_morphology=False, require_reconstruction=False, reporter_status=None, species=None): criteria = None if id: criteria = "[specimen__id$eq%d]" % id cells = self.model_query( 'ApiCellTypesSpecimenDetail', criteria=criteria, num_rows='all') return cells
[docs] @deprecated("please use list_cells_api instead") def list_cells(self, id=None, require_morphology=False, require_reconstruction=False, reporter_status=None, species=None): """ Query the API for a list of all cells in the Cell Types Database. Parameters ---------- id: int ID of a cell. If not provided returns all matching cells. require_morphology: boolean Only return cells that have morphology images. require_reconstruction: boolean Only return cells that have morphological reconstructions. reporter_status: list Return cells that have a particular cell reporter status. species: list Filter for cells that belong to one or more species. If None, return all. Must be one of [ CellTypesApi.MOUSE, CellTypesApi.HUMAN ]. Returns ------- list Meta data for all cells. """ if id: criteria = "[id$eq'%d']" % id else: criteria = "[is_cell_specimen$eq'true'],products[name$in'Mouse Cell Types','Human Cell Types'],ephys_result[failed$eqfalse]" include = ('structure,cortex_layer,donor(transgenic_lines,organism,conditions),specimen_tags,cell_soma_locations,' + 'ephys_features,data_sets,neuron_reconstructions,cell_reporter') cells = self.model_query( 'Specimen', criteria=criteria, include=include, num_rows='all') for cell in cells: # specimen tags for tag in cell['specimen_tags']: tag_name, tag_value = tag['name'].split(' - ') tag_name = tag_name.replace(' ', '_') cell[tag_name] = tag_value # morphology and reconstuction cell['has_reconstruction'] = len( cell['neuron_reconstructions']) > 0 cell['has_morphology'] = len(cell['data_sets']) > 0 # transgenic line cell['transgenic_line'] = None for tl in cell['donor']['transgenic_lines']: if tl['transgenic_line_type_name'] == 'driver': cell['transgenic_line'] = tl['name'] # cell reporter status cell['reporter_status'] = cell.get('cell_reporter', {}).get('name', None) # species cell['species'] = cell.get('donor',{}).get('organism',{}).get('name', None) # conditions (whitelist) condition_types = [ 'disease categories' ] condition_keys = dict(zip(condition_types, [ ct.replace(' ', '_') for ct in condition_types ])) for ct, ck in condition_keys.items(): cell[ck] = [] conditions = cell.get('donor',{}).get('conditions', []) for condition in conditions: c_type, c_val = condition['name'].split(' - ') if c_type in condition_keys: cell[condition_keys[c_type]].append(c_val) result = self.filter_cells(cells, require_morphology, require_reconstruction, reporter_status, species) return result
[docs] def get_cell(self, id): ''' Query the API for a one cells in the Cell Types Database. Returns ------- list Meta data for one cell. ''' cells = self.list_cells_api(id=id) cell = None if not cells else cells[0] return cell
[docs] @cacheable() def get_ephys_sweeps(self, specimen_id): """ Query the API for a list of sweeps for a particular cell in the Cell Types Database. Parameters ---------- specimen_id: int Specimen ID of a cell. Returns ------- list: List of sweep dictionaries belonging to a cell """ criteria = "[specimen_id$eq%d]" % specimen_id sweeps = self.model_query( 'EphysSweep', criteria=criteria, num_rows='all') return sorted(sweeps, key=lambda x: x['sweep_number'])
[docs] @deprecated("please use filter_cells_api") def filter_cells(self, cells, require_morphology, require_reconstruction, reporter_status, species): """ Filter a list of cell specimens to those that optionally have morphologies or have morphological reconstructions. Parameters ---------- cells: list List of cell metadata dictionaries to be filtered require_morphology: boolean Filter out cells that have no morphological images. require_reconstruction: boolean Filter out cells that have no morphological reconstructions. reporter_status: list Filter for cells that have a particular cell reporter status species: list Filter for cells that belong to one or more species. If None, return all. Must be one of [ CellTypesApi.MOUSE, CellTypesApi.HUMAN ]. """ if require_morphology: cells = [c for c in cells if c['has_morphology']] if require_reconstruction: cells = [c for c in cells if c['has_reconstruction']] if reporter_status: cells = [c for c in cells if c[ 'reporter_status'] in reporter_status] if species: species_lower = [ s.lower() for s in species ] cells = [c for c in cells if c['donor']['organism']['name'].lower() in species_lower] return cells
[docs] def filter_cells_api(self, cells, require_morphology=False, require_reconstruction=False, reporter_status=None, species=None, simple=True): """ """ if require_morphology or require_reconstruction: cells = [c for c in cells if c.get('nr__reconstruction_type') is not None] if reporter_status: cells = [c for c in cells if c.get('cell_reporter_status') in reporter_status] if species: species_lower = [ s.lower() for s in species ] cells = [c for c in cells if c.get('donor__species',"").lower() in species_lower] if simple: cells = self.simplify_cells_api(cells) return cells
[docs] def simplify_cells_api(self, cells): return [{ 'reporter_status': cell['cell_reporter_status'], 'cell_soma_location': [ cell['csl__x'], cell['csl__y'], cell['csl__z'] ], 'species': cell['donor__species'], 'id': cell['specimen__id'], 'name': cell['specimen__name'], 'structure_layer_name': cell['structure__layer'], 'structure_area_id': cell['structure_parent__id'], 'structure_area_abbrev': cell['structure_parent__acronym'], 'transgenic_line': cell['line_name'], 'dendrite_type': cell['tag__dendrite_type'], 'apical': cell['tag__apical'], 'reconstruction_type': cell['nr__reconstruction_type'], 'disease_state': cell['donor__disease_state'] } for cell in cells ]
[docs] @cacheable() def get_ephys_features(self): """ Query the API for the full table of EphysFeatures for all cells. """ return self.model_query( 'EphysFeature', criteria='specimen(ephys_result[failed$eqfalse])', num_rows='all')
[docs] @cacheable() def get_morphology_features(self): """ Query the API for the full table of morphology features for all cells Notes ----- by default the tags column is removed because it isn't useful """ return self.model_query( 'NeuronReconstruction', criteria="specimen(ephys_result[failed$eqfalse])", excpt='tags', num_rows='all')
[docs] @cacheable(strategy='create', pathfinder=Cache.pathfinder(file_name_position=2, path_keyword='file_name')) def save_ephys_data(self, specimen_id, file_name): """ Save the electrophysology recordings for a cell as an NWB file. Parameters ---------- specimen_id: int ID of the specimen, from the Specimens database model in the Allen Institute API. file_name: str Path to save the NWB file. """ criteria = '[id$eq%d],ephys_result(well_known_files(well_known_file_type[name$eq%s]))' % ( specimen_id, self.NWB_FILE_TYPE) includes = 'ephys_result(well_known_files(well_known_file_type))' results = self.model_query('Specimen', criteria=criteria, include=includes, num_rows='all') try: file_url = results[0]['ephys_result'][ 'well_known_files'][0]['download_link'] except Exception as _: raise Exception("Specimen %d has no ephys data" % specimen_id) self.retrieve_file_over_http(self.api_url + file_url, file_name)
[docs] def save_reconstruction(self, specimen_id, file_name): """ Save the morphological reconstruction of a cell as an SWC file. Parameters ---------- specimen_id: int ID of the specimen, from the Specimens database model in the Allen Institute API. file_name: str Path to save the SWC file. """ Manifest.safe_make_parent_dirs(file_name) criteria = '[id$eq%d],neuron_reconstructions(well_known_files)' % specimen_id includes = 'neuron_reconstructions(well_known_files(well_known_file_type[name$eq\'%s\']))' % self.SWC_FILE_TYPE results = self.model_query('Specimen', criteria=criteria, include=includes, num_rows='all') try: file_url = results[0]['neuron_reconstructions'][ 0]['well_known_files'][0]['download_link'] except: raise Exception("Specimen %d has no reconstruction" % specimen_id) self.retrieve_file_over_http(self.api_url + file_url, file_name)
[docs] def save_reconstruction_markers(self, specimen_id, file_name): """ Save the marker file for the morphological reconstruction of a cell. These are comma-delimited files indicating points of interest in a reconstruction (truncation points, early tracing termination, etc). Parameters ---------- specimen_id: int ID of the specimen, from the Specimens database model in the Allen Institute API. file_name: str Path to save the marker file. """ Manifest.safe_make_parent_dirs(file_name) criteria = '[id$eq%d],neuron_reconstructions(well_known_files)' % specimen_id includes = 'neuron_reconstructions(well_known_files(well_known_file_type[name$eq\'%s\']))' % self.MARKER_FILE_TYPE results = self.model_query('Specimen', criteria=criteria, include=includes, num_rows='all') try: file_url = results[0]['neuron_reconstructions'][ 0]['well_known_files'][0]['download_link'] except: raise LookupError("Specimen %d has no marker file" % specimen_id) self.retrieve_file_over_http(self.api_url + file_url, file_name)