def test_file_download_cached_file(nrrd_read, safe_mkdir, mca, cache, file_exists):
    with patch.object(mca, "retrieve_file_over_http") as mock_retrieve:
        @cacheable(reader=nrrd_read,
                pathfinder=Cache.pathfinder(file_name_position=3,
                                            secondary_file_name_position=1))
        def download_volumetric_data(data_path,
                                    file_name,
                                    voxel_resolution=None,
                                    save_file_path=None,
                                    release=None,
                                    coordinate_framework=None):
            url = mca.build_volumetric_data_download_url(data_path,
                                                        file_name,
                                                        voxel_resolution,
                                                        release,
                                                        coordinate_framework)

            mca.retrieve_file_over_http(url, save_file_path)

        with patch('os.path.exists',
                Mock(name="os.path.exists",
                        return_value=file_exists)) as mkdir:
            nrrd_read.reset_mock()

            download_volumetric_data(MCA.AVERAGE_TEMPLATE,
                                    'annotation_10.nrrd',
                                    MCA.VOXEL_RESOLUTION_10_MICRONS,
                                    'volumetric.nrrd',
                                    MCA.CCF_2016,
                                    strategy='file')

        assert not mock_retrieve.called, 'server should not have been called'
        assert not safe_mkdir.called, 'safe_mkdir should not have been called.'
        nrrd_read.assert_called_once_with('volumetric.nrrd')
Beispiel #2
0
def test_file_download_server(mock_imports, mca, cache, file_exists):
    nrrd_read, MCA = mock_imports

    @cacheable(reader=nrrd_read,
               pathfinder=Cache.pathfinder(file_name_position=3,
                                           secondary_file_name_position=1))
    def download_volumetric_data(data_path,
                                 file_name,
                                 voxel_resolution=None,
                                 save_file_path=None,
                                 release=None,
                                 coordinate_framework=None):
        url = mca.build_volumetric_data_download_url(data_path, file_name,
                                                     voxel_resolution, release,
                                                     coordinate_framework)

        mca.retrieve_file_over_http(url, save_file_path)

    with patch('os.path.exists',
               Mock(name="os.path.exists", return_value=file_exists)) as mkdir:
        nrrd_read.reset_mock()

        download_volumetric_data(MCA.AVERAGE_TEMPLATE,
                                 'annotation_10.nrrd',
                                 MCA.VOXEL_RESOLUTION_10_MICRONS,
                                 'volumetric.nrrd',
                                 MCA.CCF_2016,
                                 strategy='create')

    mca.retrieve_file_over_http.assert_called_once_with(
        'http://download.alleninstitute.org/informatics-archive/annotation/ccf_2016/mouse_ccf/average_template/annotation_10.nrrd',
        'volumetric.nrrd')
    assert not Manifest.safe_mkdir.called, 'safe_mkdir should not have been called.'
    nrrd_read.assert_called_once_with('volumetric.nrrd')
def test_file_download_lazy(nrrd_read, safe_mkdir, mca, cache, file_exists):
    with patch.object(mca, "retrieve_file_over_http") as mock_retrieve:
        @cacheable(strategy='lazy',
                reader=nrrd_read,
                pathfinder=Cache.pathfinder(file_name_position=3,
                                            secondary_file_name_position=1))
        def download_volumetric_data(data_path,
                                    file_name,
                                    voxel_resolution=None,
                                    save_file_path=None,
                                    release=None,
                                    coordinate_framework=None):
            url = mca.build_volumetric_data_download_url(data_path,
                                                        file_name,
                                                        voxel_resolution,
                                                        release,
                                                        coordinate_framework)

            mca.retrieve_file_over_http(url, save_file_path)

        with patch('os.path.exists',
                Mock(name="os.path.exists",
                        return_value=file_exists)) as mkdir:
            nrrd_read.reset_mock()
            download_volumetric_data(MCA.AVERAGE_TEMPLATE,
                                    'annotation_10.nrrd',
                                    MCA.VOXEL_RESOLUTION_10_MICRONS,
                                    'volumetric.nrrd',
                                    MCA.CCF_2016,
                                    strategy='lazy')

        if file_exists:
            assert not mock_retrieve.called, 'server call not needed when file exists'
        else:
            mock_retrieve.assert_called_once_with(
                'http://download.alleninstitute.org/informatics-archive/annotation/ccf_2016/mouse_ccf/average_template/annotation_10.nrrd',
                'volumetric.nrrd')
        assert not safe_mkdir.called, 'safe_mkdir should not have been called.'
        nrrd_read.assert_called_once_with('volumetric.nrrd')
Beispiel #4
0
class CellTypesApi(RmaApi):
    NWB_FILE_TYPE = 'NWBDownload'
    SWC_FILE_TYPE = '3DNeuronReconstruction'
    MARKER_FILE_TYPE = '3DNeuronMarker'

    MOUSE = 'Mus musculus'
    HUMAN = 'H**o Sapiens'

    def __init__(self, base_uri=None):
        super(CellTypesApi, self).__init__(base_uri)
        

    @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

    @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

    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

    @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'])


    @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

    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

    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 ]

    @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')

    @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')

    @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)

    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)

    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)
Beispiel #5
0
class VoxelModelApi(MouseConnectivityApi):
    '''HTTP Client extending MouseConnectivityApi to download model data.
    '''
    HTTP_MODEL_DIRECTORY = "http://download.alleninstitute.org/publications/"\
            "A_high_resolution_data-driven_model_of_the_mouse_connectome/"

    NODES_FILE = "nodes.csv.gz"
    WEIGHTS_FILE = "weights.csv.gz"
    SOURCE_MASK_FILE = "source_mask_params.json"
    TARGET_MASK_FILE = "target_mask_params.json"

    CONNECTION_DENSITY_FILE = 'connection_density.csv.gz'
    CONNECTION_STRENGTH_FILE = 'connection_strength.csv.gz'
    NORMALIZED_CONNECTION_DENSITY_FILE = 'normalized_connection_density.csv.gz'
    NORMALIZED_CONNECTION_STRENGTH_FILE = 'normalized_connection_strength.csv.gz'

    def download_model_files(self, file_name, save_file_path=None):
        """Download  data.

        Parameters
        ----------
        file_name : string, optional
        save_file_path : string, optional
            File name to save as.
        """
        url = self.HTTP_MODEL_DIRECTORY + file_name
        self.retrieve_file_over_http(url, save_file_path)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path'))
    def download_nodes(self, file_name):
        self.download_model_files(self.NODES_FILE, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path'))
    def download_weights(self, file_name):
        self.download_model_files(self.WEIGHTS_FILE, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path'))
    def download_source_mask_params(self, file_name):
        self.download_model_files(self.SOURCE_MASK_FILE, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path'))
    def download_target_mask_params(self, file_name):
        self.download_model_files(self.TARGET_MASK_FILE, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path'))
    def download_connection_density(self, file_name):
        self.download_model_files(self.CONNECTION_DENSITY_FILE, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path'))
    def download_connection_strength(self, file_name):
        self.download_model_files(self.CONNECTION_STRENGTH_FILE, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path'))
    def download_normalized_connection_density(self, file_name):
        self.download_model_files(self.NORMALIZED_CONNECTION_DENSITY_FILE, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1, path_keyword='path'))
    def download_normalized_connection_strength(self, file_name):
        self.download_model_files(self.NORMALIZED_CONNECTION_STRENGTH_FILE, file_name)
class ReferenceSpaceApi(RmaApi):

    AVERAGE_TEMPLATE = 'average_template'
    ARA_NISSL = 'ara_nissl'
    MOUSE_2011 = 'annotation/mouse_2011'
    DEVMOUSE_2012 = 'annotation/devmouse_2012'
    CCF_2015 = 'annotation/ccf_2015'
    CCF_2016 = 'annotation/ccf_2016'
    CCF_2017 = 'annotation/ccf_2017'
    CCF_VERSION_DEFAULT = CCF_2017

    VOXEL_RESOLUTION_10_MICRONS = 10
    VOXEL_RESOLUTION_25_MICRONS = 25
    VOXEL_RESOLUTION_50_MICRONS = 50
    VOXEL_RESOLUTION_100_MICRONS = 100

    def __init__(self, base_uri=None):
        super(ReferenceSpaceApi, self).__init__(base_uri=base_uri)

    @cacheable(strategy='create',
               reader=nrrd.read,
               pathfinder=Cache.pathfinder(file_name_position=3,
                                           path_keyword='file_name'))
    def download_annotation_volume(self, ccf_version, resolution, file_name):
        '''
        Download the annotation volume at a particular resolution.

        Parameters
        ----------
        ccf_version: string
            Which reference space version to download. Defaults to "annotation/ccf_2017"
        resolution: int
            Desired resolution to download in microns.
            Must be 10, 25, 50, or 100.
        file_name: string
            Where to save the annotation volume.
        
        Note: the parameters must be used as positional parameters, not keywords
        '''

        if ccf_version is None:
            ccf_version = ReferenceSpaceApi.CCF_VERSION_DEFAULT

        self.download_volumetric_data(ccf_version,
                                      'annotation_%d.nrrd' % resolution,
                                      save_file_path=file_name)

    @cacheable(strategy='create',
               reader=sitk_utilities.read_ndarray_with_sitk,
               pathfinder=Cache.pathfinder(file_name_position=3,
                                           path_keyword='file_name'))
    def download_mouse_atlas_volume(self, age, volume_type, file_name):
        '''Download a reference volume (annotation, grid annotation, atlas volume) 
        from the mouse brain atlas project

        Parameters
        ----------
        age : str
            Specify a mouse age for which to download the reference volume
        volume_type : str
            Specify the type of volume to download
        file_name : str
            Specify the path to the downloaded volume
        '''

        remote_file_name = '{}_{}.zip'.format(age, volume_type)
        url = '/'.join([
            self.informatics_archive_endpoint, 'current-release',
            'mouse_annotation', remote_file_name
        ])

        self.retrieve_file_over_http(url, file_name, zipped=True)

    @cacheable(strategy='create',
               reader=nrrd.read,
               pathfinder=Cache.pathfinder(file_name_position=2,
                                           path_keyword='file_name'))
    def download_template_volume(self, resolution, file_name):
        '''
        Download the registration template volume at a particular resolution.

        Parameters
        ----------

        resolution: int
            Desired resolution to download in microns.  Must be 10, 25, 50, or 100.

        file_name: string
            Where to save the registration template volume.
        '''
        self.download_volumetric_data(ReferenceSpaceApi.AVERAGE_TEMPLATE,
                                      'average_template_%d.nrrd' % resolution,
                                      save_file_path=file_name)

    @cacheable(strategy='create',
               reader=nrrd.read,
               pathfinder=Cache.pathfinder(file_name_position=4,
                                           path_keyword='file_name'))
    def download_structure_mask(self, structure_id, ccf_version, resolution,
                                file_name):
        '''Download an indicator mask for a specific structure.

        Parameters
        ----------
        structure_id : int
            Unique identifier for the annotated structure
        ccf_version : string
            Which reference space version to download. Defaults to "annotation/ccf_2017"
        resolution : int
            Desired resolution to download in microns.  Must be 10, 25, 50, or 100.
        file_name : string
             Where to save the downloaded mask.

        '''

        if ccf_version is None:
            ccf_version = ReferenceSpaceApi.CCF_VERSION_DEFAULT

        structure_mask_dir = 'structure_masks_{0}'.format(resolution)
        data_path = '{0}/{1}/{2}'.format(ccf_version, 'structure_masks',
                                         structure_mask_dir)
        remote_file_name = 'structure_{0}.nrrd'.format(structure_id)

        try:
            self.download_volumetric_data(data_path,
                                          remote_file_name,
                                          save_file_path=file_name)
        except Exception as e:
            self._file_download_log.error(
                '''We weren't able to download a structure mask for structure {0}. 
                                             You can instead build the mask locally using 
                                             ReferenceSpace.many_structure_masks'''
            )
            raise

    @cacheable(strategy='create',
               reader=read_obj,
               pathfinder=Cache.pathfinder(file_name_position=3,
                                           path_keyword='file_name'))
    def download_structure_mesh(self, structure_id, ccf_version, file_name):
        '''Download a Wavefront obj file containing a triangulated 3d mesh built 
        from an annotated structure.

        Parameters
        ----------
        structure_id : int
            Unique identifier for the annotated structure
        ccf_version : string
            Which reference space version to download. Defaults to "annotation/ccf_2017"
        file_name : string
             Where to save the downloaded mask.

        '''

        if ccf_version is None:
            ccf_version = ReferenceSpaceApi.CCF_VERSION_DEFAULT

        data_path = '{0}/{1}'.format(ccf_version, 'structure_meshes')
        remote_file_name = '{0}.obj'.format(structure_id)

        try:
            self.download_volumetric_data(data_path,
                                          remote_file_name,
                                          save_file_path=file_name)
        except Exception as e:
            self._file_download_log.error(
                'unable to download a structure mesh for structure {0}.'.
                format(structure_id))
            raise

    def build_volumetric_data_download_url(self,
                                           data_path,
                                           file_name,
                                           voxel_resolution=None,
                                           release=None,
                                           coordinate_framework=None):
        '''Construct url to download 3D reference model in NRRD format.

        Parameters
        ----------
        data_path : string
            'average_template', 'ara_nissl', 'annotation/ccf_{year}', 
            'annotation/mouse_2011', or 'annotation/devmouse_2012'
        voxel_resolution : int
            10, 25, 50 or 100
        coordinate_framework : string
            'mouse_ccf' (default) or 'mouse_annotation'

        Notes
        -----
        See: `3-D Reference Models <http://help.brain-map.org/display/mouseconnectivity/API#API-3DReferenceModels>`_
        for additional documentation.
        '''

        if voxel_resolution is None:
            voxel_resolution = ReferenceSpaceApi.VOXEL_RESOLUTION_10_MICRONS

        if release is None:
            release = 'current-release'

        if coordinate_framework is None:
            coordinate_framework = 'mouse_ccf'

        url = ''.join([
            self.informatics_archive_endpoint,
            '/%s/%s/' % (release, coordinate_framework), data_path, '/',
            file_name
        ])

        return url

    def download_volumetric_data(self,
                                 data_path,
                                 file_name,
                                 voxel_resolution=None,
                                 save_file_path=None,
                                 release=None,
                                 coordinate_framework=None):
        '''Download 3D reference model in NRRD format.

        Parameters
        ----------
        data_path : string
            'average_template', 'ara_nissl', 'annotation/ccf_{year}', 
            'annotation/mouse_2011', or 'annotation/devmouse_2012'
        file_name : string
            server-side file name. 'annotation_10.nrrd' for example.
        voxel_resolution : int
            10, 25, 50 or 100
        coordinate_framework : string
            'mouse_ccf' (default) or 'mouse_annotation'

        Notes
        -----
        See: `3-D Reference Models <http://help.brain-map.org/display/mouseconnectivity/API#API-3DReferenceModels>`_
        for additional documentation.
        '''
        url = self.build_volumetric_data_download_url(data_path, file_name,
                                                      voxel_resolution,
                                                      release,
                                                      coordinate_framework)

        if save_file_path is None:
            save_file_path = file_name

        if save_file_path is None:
            save_file_path = 'volumetric_data.nrrd'

        self.retrieve_file_over_http(url, save_file_path)
Beispiel #7
0
class MouseAtlasApi(ReferenceSpaceApi, GridDataApi):
    ''' Downloads Mouse Brain Atlas grid data, reference volumes, and metadata.
    '''

    MOUSE_ATLAS_PRODUCTS = (1, )
    DEVMOUSE_ATLAS_PRODUCTS = (3, )
    MOUSE_ORGANISM = (2, )
    HUMAN_ORGANISM = (1, )

    @cacheable()
    @pageable(num_rows=2000, total_rows='all')
    def get_section_data_sets(self, gene_ids=None, product_ids=None, **kwargs):
        ''' Download a list of section data sets (experiments) from the Mouse Brain
        Atlas project.

        Parameters
        ----------
        gene_ids : list of int, optional
            Filter results based on the genes whose expression was characterized 
            in each experiment. Default is all.
        product_ids : list of int, optional
            Filter results to a subset of products. Default is the Mouse Brain Atlas.

        Returns
        -------
        list of dict : 
            Each element is a section data set record, with one or more gene 
            records nested in a list. 

        '''

        if product_ids is None:
            product_ids = list(self.MOUSE_ATLAS_PRODUCTS)
        criteria = 'products[id$in{}]'.format(','.join(map(str, product_ids)))

        if gene_ids is not None:
            criteria += ',genes[id$in{}]'.format(','.join(map(str, gene_ids)))

        return self.model_query(model='SectionDataSet',
                                criteria=criteria,
                                include='genes',
                                **kwargs)

    @cacheable()
    @pageable(num_rows=2000, total_rows='all')
    def get_genes(self, organism_ids=None, chromosome_ids=None, **kwargs):
        ''' Download a list of genes

        Parameters
        ----------
        organism_ids : list of int, optional
            Filter genes to those appearing in these organisms. Defaults to mouse (2).
        chromosome_ids : list of int, optional
            Filter genes to those appearing on these chromosomes. Defaults to all.

        Returns
        -------
        list of dict:
            Each element is a gene record, with a nested chromosome record (also a dict).

        '''

        if organism_ids is None:
            organism_ids = list(self.MOUSE_ORGANISM)
        criteria = '[organism_id$in{}]'.format(','.join(map(str,
                                                            organism_ids)))

        if chromosome_ids is not None:
            criteria += ',[chromosome_id$in{}]'.format(','.join(
                map(str, chromosome_ids)))

        return self.model_query(model='Gene',
                                criteria=criteria,
                                include='chromosome',
                                **kwargs)

    @cacheable(strategy='create',
               reader=sitk_utilities.read_ndarray_with_sitk,
               pathfinder=Cache.pathfinder(file_name_position=1,
                                           path_keyword='path'))
    def download_expression_density(self, path, experiment_id):
        self.download_gene_expression_grid_data(experiment_id,
                                                GridDataApi.DENSITY, path)

    @cacheable(strategy='create',
               reader=sitk_utilities.read_ndarray_with_sitk,
               pathfinder=Cache.pathfinder(file_name_position=1,
                                           path_keyword='path'))
    def download_expression_energy(self, path, experiment_id):
        self.download_gene_expression_grid_data(experiment_id,
                                                GridDataApi.ENERGY, path)

    @cacheable(strategy='create',
               reader=sitk_utilities.read_ndarray_with_sitk,
               pathfinder=Cache.pathfinder(file_name_position=1,
                                           path_keyword='path'))
    def download_expression_intensity(self, path, experiment_id):
        self.download_gene_expression_grid_data(experiment_id,
                                                GridDataApi.INTENSITY, path)
class MouseConnectivityApiPrerelease(MouseConnectivityApi):
    '''Client for retrieving prereleased mouse connectivity data from lims.

    Parameters
    ----------
    base_uri : string, optional
        Does not affect pulling from lims.
    file_name : string, optional
        File name to save/read storage_directories dict. Passed to
        GridDataApiPrerelease constructor.
    '''
    def __init__(self,
                 storage_directories_file_name,
                 cache_storage_directories=True,
                 base_uri=None):
        super(MouseConnectivityApiPrerelease, self).__init__(base_uri=base_uri)
        self.grid_data_api = GridDataApiPrerelease.from_file_name(
            storage_directories_file_name, cache=cache_storage_directories)

    @cacheable()
    def get_experiments(self):
        query_result = lu.query(_EXPERIMENT_QUERY)

        experiments = []
        for row in query_result:
            if str(row[b'id']) in self.grid_data_api.storage_directories:

                exp_dict = _experiment_dict(row)
                experiments.append(exp_dict)

        return experiments

    #@cacheable()
    def get_structure_unionizes(self):
        raise NotImplementedError()

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1,
                                           path_keyword='path'))
    def download_injection_density(self, path, experiment_id, resolution):
        file_name = "%s_%s.nrrd" % (GridDataApi.INJECTION_DENSITY, resolution)

        self.grid_data_api.download_projection_grid_data(
            path, experiment_id, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1,
                                           path_keyword='path'))
    def download_projection_density(self, path, experiment_id, resolution):
        file_name = "%s_%s.nrrd" % (GridDataApi.PROJECTION_DENSITY, resolution)

        self.grid_data_api.download_projection_grid_data(
            path, experiment_id, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1,
                                           path_keyword='path'))
    def download_injection_fraction(self, path, experiment_id, resolution):
        file_name = "%s_%s.nrrd" % (GridDataApi.INJECTION_FRACTION, resolution)

        self.grid_data_api.download_projection_grid_data(
            path, experiment_id, file_name)

    @cacheable(strategy='create',
               pathfinder=Cache.pathfinder(file_name_position=1,
                                           path_keyword='path'))
    def download_data_mask(self, path, experiment_id, resolution):
        file_name = "%s_%s.nrrd" % (GridDataApi.DATA_MASK, resolution)

        self.grid_data_api.download_projection_grid_data(
            path, experiment_id, file_name)