Source code for allensdk.api.queries.mouse_connectivity_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-2017. 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 .reference_space_api import ReferenceSpaceApi
from .grid_data_api import GridDataApi
from ..cache import cacheable, Cache
import numpy as np
import nrrd
import six


[docs]class MouseConnectivityApi(ReferenceSpaceApi, GridDataApi): ''' HTTP Client for the Allen Mouse Brain Connectivity Atlas. See: `Mouse Connectivity API <http://help.brain-map.org/display/mouseconnectivity/API>`_ ''' PRODUCT_IDS = [5, 31] def __init__(self, base_uri=None): super(MouseConnectivityApi, self).__init__(base_uri=base_uri)
[docs] @cacheable() def get_experiments(self, structure_ids, **kwargs): ''' Fetch experiment metadata from the Mouse Brain Connectivity Atlas. Parameters ---------- structure_ids : integer or list, optional injection structure Returns ------- url : string The constructed URL ''' criteria_list = ['[failed$eqfalse]', 'products[id$in%s]' % (','.join(str(i) for i in MouseConnectivityApi.PRODUCT_IDS))] if structure_ids is not None: if type(structure_ids) is not list: structure_ids = [structure_ids] criteria_list.append('[id$in%s]' % ','.join(str(i) for i in structure_ids)) criteria_string = ','.join(criteria_list) return self.model_query('SectionDataSet', criteria=criteria_string, **kwargs)
[docs] @cacheable() def get_experiments_api(self): ''' Fetch experiment metadata from the Mouse Brain Connectivity Atlas via the ApiConnectivity table. Returns ------- url : string The constructed URL ''' return self.model_query('ApiConnectivity', num_rows='all')
[docs] @cacheable() def get_manual_injection_summary(self, experiment_id): ''' Retrieve manual injection summary. ''' criteria = '[id$in%d]' % (experiment_id) include = ['specimen(donor(transgenic_mouse(transgenic_lines)),', 'injections(structure,age)),', 'equalization,products'] only = ['id', 'failed', 'storage_directory', 'red_lower', 'red_upper', 'green_lower', 'green_upper', 'blue_lower', 'blue_upper', 'products.id', 'specimen_id', 'structure_id', 'reference_space_id', 'primary_injection_structure_id', 'registration_point', 'coordinates_ap', 'coordinates_dv', 'coordinates_ml', 'angle', 'sex', 'strain', 'injection_materials', 'acronym', 'structures.name', 'days', 'transgenic_mice.name', 'transgenic_lines.name', 'transgenic_lines.description', 'transgenic_lines.id', 'donors.id'] return self.model_query('SectionDataSet', criteria=criteria, include=include, only=only)
[docs] @cacheable() def get_experiment_detail(self, experiment_id): '''Retrieve the experiments data.''' criteria = '[id$eq%d]' % (experiment_id) include = ['specimen(stereotaxic_injections(primary_injection_structure,structures,stereotaxic_injection_coordinates)),', 'equalization,', 'sub_images'] order = ["'sub_images.section_number$asc'"] return self.model_query('SectionDataSet', criteria=criteria, include=include, order=order)
[docs] @cacheable() def get_projection_image_info(self, experiment_id, section_number): '''Fetch meta-information of one projection image. Parameters ---------- experiment_id : integer section_number : integer Notes ----- See: image examples under `Experimental Overview and Metadata <http://help.brain-map.org/display/mouseconnectivity/API##API-ExperimentalOverviewandMetadata>`_ for additional documentation. Download the image using :py:meth:`allensdk.api.queries.image_download_api.ImageDownloadApi.download_section_image` ''' criteria = '[id$eq%d]' % (experiment_id) include = ['equalization,sub_images[section_number$eq%d]' % (section_number)] return self.model_query('SectionDataSet', criteria=criteria, include=include)
[docs] def download_reference_aligned_image_channel_volumes(self, data_set_id, save_file_path=None): ''' Returns ------- The well known file is downloaded ''' well_known_file_url = self.get_reference_aligned_image_channel_volumes_url( data_set_id) if save_file_path is None: save_file_path = str(data_set_id) + '.zip' self.retrieve_file_over_http(well_known_file_url, save_file_path)
[docs] def build_reference_aligned_image_channel_volumes_url(self, data_set_id): '''Construct url to download the red, green, and blue channels aligned to the 25um adult mouse brain reference space volume. Parameters ---------- data_set_id : integerallensdk.api.queries aka attachable_id Notes ----- See: `Reference-aligned Image Channel Volumes <http://help.brain-map.org/display/mouseconnectivity/API#API-ReferencealignedImageChannelVolumes>`_ for additional documentation. ''' criteria = ['well_known_file_type', "[name$eq'ImagesResampledTo25MicronARA']", "[attachable_id$eq%d]" % (data_set_id)] model_stage = self.model_stage('WellKnownFile', criteria=criteria) url = self.build_query_url([model_stage]) return url
[docs] def get_reference_aligned_image_channel_volumes_url(self, data_set_id): '''Retrieve the download link for a specific data set.\ Notes ----- See `Reference-aligned Image Channel Volumes <http://help.brain-map.org/display/mouseconnectivity/API#API-ReferencealignedImageChannelVolumes>`_ for additional documentation. ''' download_link = self.do_query(self.build_reference_aligned_image_channel_volumes_url, lambda parsed_json: str( parsed_json['msg'][0]['download_link']), data_set_id) url = self.api_url + download_link return url
[docs] @cacheable() def get_structure_unionizes(self, experiment_ids, is_injection=None, structure_name=None, structure_ids=None, hemisphere_ids=None, normalized_projection_volume_limit=None, include=None, debug=None, order=None): experiment_filter = '[section_data_set_id$in%s]' %\ ','.join(str(i) for i in experiment_ids) if is_injection is True: is_injection_filter = '[is_injection$eqtrue]' elif is_injection is False: is_injection_filter = '[is_injection$eqfalse]' else: is_injection_filter = '' if normalized_projection_volume_limit is not None: volume_filter = '[normalized_projection_volume$gt%f]' %\ (normalized_projection_volume_limit) else: volume_filter = '' if hemisphere_ids is not None: hemisphere_filter = '[hemisphere_id$in%s]' %\ ','.join(str(h) for h in hemisphere_ids) else: hemisphere_filter = '' if structure_name is not None: structure_filter = ",structure[name$eq'%s']" % (structure_name) elif structure_ids is not None: structure_filter = '[structure_id$in%s]' %\ ','.join(str(i) for i in structure_ids) else: structure_filter = '' return self.model_query( 'ProjectionStructureUnionize', criteria=''.join([experiment_filter, is_injection_filter, volume_filter, hemisphere_filter, structure_filter]), include=include, order=order, num_rows='all', debug=debug, count=False)
[docs] @cacheable(strategy='create', pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path')) def download_injection_density(self, path, experiment_id, resolution): self.download_projection_grid_data( experiment_id, [GridDataApi.INJECTION_DENSITY], resolution, path)
[docs] @cacheable(strategy='create', pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path')) def download_projection_density(self, path, experiment_id, resolution): self.download_projection_grid_data( experiment_id, [GridDataApi.PROJECTION_DENSITY], resolution, path)
[docs] @cacheable(strategy='create', pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path')) def download_injection_fraction(self, path, experiment_id, resolution): self.download_projection_grid_data( experiment_id, [GridDataApi.INJECTION_FRACTION], resolution, path)
[docs] @cacheable(strategy='create', pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path')) def download_data_mask(self, path, experiment_id, resolution): self.download_projection_grid_data( experiment_id, [GridDataApi.DATA_MASK], resolution, path)
[docs] def calculate_injection_centroid(self, injection_density, injection_fraction, resolution=25): ''' Compute the centroid of an injection site. Parameters ---------- injection_density: np.ndarray The injection density volume of an experiment injection_fraction: np.ndarray The injection fraction volume of an experiment ''' # find all voxels with injection_fraction > 0 injection_voxels = np.nonzero(injection_fraction) injection_density_computed = np.multiply(injection_density[injection_voxels], injection_fraction[injection_voxels]) sum_density = np.sum(injection_density_computed) # compute centroid in CCF coordinates if sum_density > 0: centroid = np.dot(injection_density_computed, list(zip(*injection_voxels))) / sum_density * resolution else: centroid = None return centroid