def get_ids_by_peaks(self, peaks, r=10, threshold=0.0, get_image_data=False): """ A wrapper for get_ids_by_mask. Takes a set of xyz coordinates and generates a new Nifti1Image to use as a mask. Args: peaks: Either an n x 3 numpy array, or a list of lists (e.g., [[-10, 22, 14]]) specifying the world (x/y/z) coordinates of the target location(s). r: Radius in millimeters of the sphere to grow around each location. threshold: Optional float indicating the proportion of voxels that must be active in order for a Mappable to be considered active. get_image_data: If true, returns the image data for all activated Mappables in a voxel x Mappable numpy array. Otherwise, returns just the IDs of Mappables. Returns: Either a list of ids (if get_image_data = False) or a numpy array of image data. """ peaks = np.array(peaks) # Make sure we have a numpy array peaks = transformations.xyz_to_mat(peaks) img = imageutils.map_peaks_to_image(peaks, r, vox_dims=self.masker.vox_dims, dims=self.masker.dims, header=self.masker.get_header()) return self.get_ids_by_mask(img, threshold, get_image_data=get_image_data)
def get_ids_by_peaks(self, peaks, r=10, threshold=0.0, get_image_data=False): """ A wrapper for get_ids_by_mask. Takes a set of xyz coordinates and generates a new Nifti1Image to use as a mask. Args: peaks (ndarray, list): Either an n x 3 numpy array, or a list of lists (e.g., [[-10, 22, 14]]) specifying the world (x/y/z) coordinates of the target location(s). r (int): Radius in millimeters of the sphere to grow around each location. threshold (float): Optional float indicating the proportion of voxels that must be active in order for a Mappable to be considered active. get_image_data (bool): When True, returns a voxel x mappable matrix of image data rather than the Mappable instances themselves. Returns: Either a list of ids (if get_image_data = False) or a numpy array of image data. """ peaks = np.array(peaks) # Make sure we have a numpy array peaks = transformations.xyz_to_mat(peaks) img = imageutils.map_peaks_to_image( peaks, r, vox_dims=self.masker.vox_dims, dims=self.masker.dims, header=self.masker.get_header()) return self.get_ids_by_mask(img, threshold, get_image_data=get_image_data)
def peaks_to_vector(coordinates, mask= '/scratch/02863/mparikh/data/MNI152_T1_2mm_brain.nii.gz', radius=10): """ Takes in a list of valid peak coordinates and returns a vector of the corresponding image Parameters ---------- coordinates : list of lists list of x/y/z coordinates mask : mask object in nifti fomat used to vectorize the image radius : int, optional the radius of sphere to expand around the peaks in mm. defaults to 10mm. Returns ------- dense_img : nifti image 1D Numpy array of in-mask voxels """ # transform the coordinates to matrix space #print(coordinates) new_coordinates = nbt.xyz_to_mat(np.array(coordinates)) # now get the denser image, expanding via spheres dense_img = nbi.map_peaks_to_image(new_coordinates, r=radius) # Create a mask object for the image niftiMask = nbm.Mask(mask) # mask the image formed return niftiMask.mask(dense_img)
def __init__(self, dataset, r=6, use_sparse=True): activations, masker, r = dataset.activations, dataset.masker, dataset.r for var in [activations, masker, r]: assert var is not None self.ids = activations["id"].unique() self.masker = masker self.r = r n_studies = len(self.ids) data_shape = (self.masker.n_vox_in_vol, n_studies) if use_sparse: # Fancy indexing assignment is not supported for sparse matrices, # so let's keep lists of values and their indices (rows, cols) to # later construct the csr_matrix. vals, rows, cols = [], [], [] else: self.data = np.zeros(data_shape, dtype=int) logger.info("Mapping %d studies into image space..." % (n_studies,)) for i, (name, data) in enumerate(activations.groupby("id")): logger.debug("%s/%s..." % (str(i + 1), str(n_studies))) img = imageutils.map_peaks_to_image(data[["i", "j", "k"]].values, r=r, header=self.masker.get_header()) img_masked = self.masker.mask(img) if use_sparse: nz = np.nonzero(img_masked) assert len(nz) == 1 vals += list(img_masked[nz]) rows += list(nz[0]) cols += [i] * len(nz[0]) else: self.data[:, i] = img_masked if use_sparse: self.data = sparse.csr_matrix((vals, (rows, cols)), shape=data_shape)
def __init__(self, dataset=None, mappables=None, masker=None, r=6, use_sparse=True): """ Initialize a new ImageTable. If a Dataset instance is passed, all inputs are taken from the Dataset. Alternatively, a user can manually pass the desired mappables and masker (e.g., in cases where the ImageTable class is being used without a Dataset). Can optionally specify the radius of the sphere used for smoothing (default: 6 mm), as well as whether or not to represent the data as a sparse array (generally this should be left to True, as these data are quite sparse and computation can often be speeded up by an order of magnitude.) """ if dataset is not None: mappables, masker, r = dataset.mappables, dataset.masker, dataset.r for var in [mappables, masker, r]: assert var is not None self.ids = [m.id for m in mappables] self.masker = masker self.r = r data_shape = (self.masker.n_vox_in_vol, len(mappables)) if use_sparse: # Fancy indexing assignment is not supported for sparse matrices, so # let's keep lists of values and their indices (rows, cols) to later # construct the csr_matrix. vals, rows, cols = [], [], [] else: self.data = np.zeros(data_shape, dtype=int) logger.info("Creating matrix of %d mappables..." % (len(mappables), )) for i, s in enumerate(mappables): logger.debug("%s/%s..." % (str(i + 1), str(len(mappables)))) img = imageutils.map_peaks_to_image( s.peaks, r=r, header=self.masker.get_header()) img_masked = self.masker.mask(img) if use_sparse: nz = np.nonzero(img_masked) assert (len(nz) == 1) vals += list(img_masked[nz]) rows += list(nz[0]) cols += [i] * len(nz[0]) else: self.data[:, i] = img_masked if use_sparse: self.data = sparse.csr_matrix((vals, (rows, cols)), shape=data_shape)
def __init__(self, dataset=None, mappables=None, masker=None, r=6, use_sparse=True): """ Initialize a new ImageTable. If a Dataset instance is passed, all inputs are taken from the Dataset. Alternatively, a user can manually pass the desired mappables and masker (e.g., in cases where the ImageTable class is being used without a Dataset). Can optionally specify the radius of the sphere used for smoothing (default: 6 mm), as well as whether or not to represent the data as a sparse array (generally this should be left to True, as these data are quite sparse and computation can often be speeded up by an order of magnitude.) """ if dataset is not None: mappables, masker, r = dataset.mappables, dataset.masker, dataset.r for var in [mappables, masker, r]: assert var is not None self.ids = [m.id for m in mappables] self.masker = masker self.r = r data_shape = (self.masker.n_vox_in_vol, len(mappables)) if use_sparse: # Fancy indexing assignment is not supported for sparse matrices, so # let's keep lists of values and their indices (rows, cols) to later # construct the csr_matrix. vals, rows, cols = [], [], [] else: self.data = np.zeros(data_shape, dtype=int) logger.info("Creating matrix of %d mappables..." % (len(mappables),)) for i, s in enumerate(mappables): logger.debug("%s/%s..." % (str(i + 1), str(len(mappables)))) header = self.masker.get_header() img = imageutils.map_peaks_to_image( s.peaks, r=r, header=header, vox_dims=header['pixdim'][1:4], dims=header['dim'][1:4]) img_masked = self.masker.mask(img) if use_sparse: nz = np.nonzero(img_masked) assert(len(nz) == 1) vals += list(img_masked[nz]) rows += list(nz[0]) cols += [i] * len(nz[0]) else: self.data[:, i] = img_masked if use_sparse: self.data = sparse.csr_matrix(( vals, (rows, cols)), shape=data_shape)
def __init__(self, dataset=None, mappables=None, masker=None, r=6, use_sparse=True): if dataset is not None: mappables, masker, r = dataset.mappables, dataset.masker, dataset.r for var in [mappables, masker, r]: assert var is not None self.ids = [m.id for m in mappables] self.masker = masker self.r = r data_shape = (self.masker.n_vox_in_vol, len(mappables)) if use_sparse: # Fancy indexing assignment is not supported for sparse matrices, # so let's keep lists of values and their indices (rows, cols) to # later construct the csr_matrix. vals, rows, cols = [], [], [] else: self.data = np.zeros(data_shape, dtype=int) logger.info("Creating matrix of %d mappables..." % (len(mappables), )) for i, s in enumerate(mappables): logger.debug("%s/%s..." % (str(i + 1), str(len(mappables)))) img = imageutils.map_peaks_to_image( s.peaks, r=r, header=self.masker.get_header()) img_masked = self.masker.mask(img) if use_sparse: nz = np.nonzero(img_masked) assert (len(nz) == 1) vals += list(img_masked[nz]) rows += list(nz[0]) cols += [i] * len(nz[0]) else: self.data[:, i] = img_masked if use_sparse: self.data = sparse.csr_matrix((vals, (rows, cols)), shape=data_shape)
def __init__(self, dataset, r=6, use_sparse=True): activations, masker, r = dataset.activations, dataset.masker, dataset.r for var in [activations, masker, r]: assert var is not None self.ids = activations['id'].unique() self.masker = masker self.r = r n_studies = len(self.ids) data_shape = (self.masker.n_vox_in_vol, n_studies) if use_sparse: # Fancy indexing assignment is not supported for sparse matrices, # so let's keep lists of values and their indices (rows, cols) to # later construct the csr_matrix. vals, rows, cols = [], [], [] else: self.data = np.zeros(data_shape, dtype=int) logger.info("Mapping %d studies into image space..." % (n_studies, )) for i, (name, data) in enumerate(activations.groupby('id')): logger.debug("%s/%s..." % (str(i + 1), str(n_studies))) img = imageutils.map_peaks_to_image( data[['i', 'j', 'k']].values, r=r, header=self.masker.get_header()) img_masked = self.masker.mask(img) if use_sparse: nz = np.nonzero(img_masked) assert (len(nz) == 1) vals += list(img_masked[nz]) rows += list(nz[0]) cols += [i] * len(nz[0]) else: self.data[:, i] = img_masked if use_sparse: self.data = sparse.csr_matrix((vals, (rows, cols)), shape=data_shape)
def get_ids_by_peaks(self, peaks, r=10, threshold=0.0, get_image_data=False): """ A wrapper for get_ids_by_mask. Takes a set of xyz coordinates and generates a new Nifti1Image to use as a mask. Args: peaks: Either an n x 3 numpy array, or a list of lists (e.g., [[-10, 22, 14]]) specifying the world (x/y/z) coordinates of the target location(s). r: Radius in millimeters of the sphere to grow around each location. threshold: Optional float indicating the proportion of voxels that must be active in order for a Mappable to be considered active. get_image_data: If true, returns the image data for all activated Mappables in a voxel x Mappable numpy array. Otherwise, returns just the IDs of Mappables. Returns: Either a list of ids (if get_image_data = False) or a numpy array of image data. """ peaks = np.array(peaks) # Make sure we have a numpy array peaks = transformations.xyz_to_mat(peaks) img = imageutils.map_peaks_to_image( peaks, r, vox_dims=self.volume.vox_dims, dims=self.volume.dims, header=self.volume.get_header()) return self.get_ids_by_mask(img, threshold, get_image_data=get_image_data)
def __init__(self, dataset=None, mappables=None, masker=None, r=6, use_sparse=True): if dataset is not None: mappables, masker, r = dataset.mappables, dataset.masker, dataset.r for var in [mappables, masker, r]: assert var is not None self.ids = [m.id for m in mappables] self.masker = masker self.r = r data_shape = (self.masker.n_vox_in_vol, len(mappables)) if use_sparse: # Fancy indexing assignment is not supported for sparse matrices, # so let's keep lists of values and their indices (rows, cols) to # later construct the csr_matrix. vals, rows, cols = [], [], [] else: self.data = np.zeros(data_shape, dtype=int) logger.info("Creating matrix of %d mappables..." % (len(mappables),)) for i, s in enumerate(mappables): logger.debug("%s/%s..." % (str(i + 1), str(len(mappables)))) img = imageutils.map_peaks_to_image( s.peaks, r=r, header=self.masker.get_header()) img_masked = self.masker.mask(img) if use_sparse: nz = np.nonzero(img_masked) assert(len(nz) == 1) vals += list(img_masked[nz]) rows += list(nz[0]) cols += [i] * len(nz[0]) else: self.data[:, i] = img_masked if use_sparse: self.data = sparse.csr_matrix(( vals, (rows, cols)), shape=data_shape)
def map_peaks(self): """Map all Peaks to a new Nifti1Image.""" return imageutils.map_peaks_to_image(self.peaks)
def map_peaks(self): """Map all Peaks to a new Nifti1Image.""" # if len(self.peaks) == 0: return return imageutils.map_peaks_to_image(self.peaks)
def get_studies(self, features=None, expression=None, mask=None, peaks=None, frequency_threshold=0.001, activation_threshold=0.0, func=np.sum, return_type='ids', r=6 ): """ Get IDs or data for studies that meet specific criteria. If multiple criteria are passed, the set intersection is returned. For example, passing expression='emotion' and mask='my_mask.nii.gz' would return only those studies that are associated with emotion AND report activation within the voxels indicated in the passed image. Args: ids (list): A list of IDs of studies to retrieve. features (list or str): The name of a feature, or a list of features, to use for selecting studies. expression (str): A string expression to pass to the PEG for study retrieval. mask: the mask image (see Masker documentation for valid data types). peaks (ndarray or list): Either an n x 3 numpy array, or a list of lists (e.g., [[-10, 22, 14]]) specifying the world (x/y/z) coordinates of the target location(s). frequency_threshold (float): For feature-based or expression-based selection, the threshold for selecting studies--i.e., the cut-off for a study to be included. Must be a float in range [0, 1]. activation_threshold (int or float): For mask-based or peak-based selection, threshold for a study to be included based on amount of activation displayed. If an integer, represents the absolute number of voxels that must be active within the mask (or generated ROIs) in order for a study to be selected. If a float, it represents the proportion of voxels that must be active. func (Callable): The function to use when aggregating over the list of features. See documentation in FeatureTable.get_ids() for a full explanation. Only used for feature- or expression-based selection. return_type (str): A string specifying what data to return. Valid options are: 'ids': returns a list of IDs of selected studies. 'images': returns a voxel x mappable matrix of data for all selected studies. 'weights': returns a dict where the keys are study IDs and the values are the computed weights. Only valid when performing feature-based selection. r (int): For peak-based selection, the radius in millimeters of the sphere to grow around each peak. Returns: When return_type is 'ids' (default), returns a list of IDs of the selected studies. When return_type is 'data', returns a 2D numpy array, with voxels in rows and studies in columns. When return_type is 'weights' (valid only for expression-based selection), returns a dict, where the keys are study IDs, and the values are the computed weights. Examples -------- Select all studies tagged with the feature 'emotion': >>> ids = dataset.get_studies(features='emotion') Select all studies that activate at least 20% of voxels in an amygdala mask, and retrieve activation data rather than IDs: >>> data = dataset.get_studies(mask='amygdala_mask.nii.gz', threshold=0.2, return_type='images') Select studies that activate at least 5% of all voxels within 12 mm of three specific foci: >>> ids = dataset.get_studies(peaks=[[12, -20, 30], [-26, 22, 22], [0, 36, -20]], r=12) """ results = [] # Feature-based selection if features is not None: # Need to handle weights as a special case, because we can't # retrieve the weights later using just the IDs. if return_type == 'weights': if expression is not None or mask is not None or \ peaks is not None: raise ValueError( "return_type cannot be 'weights' when feature-based " "search is used in conjunction with other search " "modes.") return self.feature_table.get_ids( features, frequency_threshold, func, get_weights=True) else: results.append(self.feature_table.get_ids( features, frequency_threshold, func)) # Logical expression-based selection if expression is not None: _ids = self.feature_table.get_ids_by_expression( expression, frequency_threshold, func) results.append(list(_ids)) # Mask-based selection if mask is not None: mask = self.masker.mask(mask, in_global_mask=True).astype(bool) num_vox = np.sum(mask) prop_mask_active = self.image_table.data.T.dot(mask).astype(float) if isinstance(activation_threshold, float): prop_mask_active /= num_vox indices = np.where(prop_mask_active > activation_threshold)[0] results.append([self.image_table.ids[ind] for ind in indices]) # Peak-based selection if peaks is not None: peaks = np.array(peaks) # Make sure we have a numpy array peaks = transformations.xyz_to_mat(peaks) m = self.masker img = imageutils.map_peaks_to_image( peaks, r, vox_dims=m.vox_dims, dims=m.dims, header=m.get_header()) results.append(self.get_studies( mask=img, activation_threshold=activation_threshold)) # Get intersection of all sets ids = list(reduce(lambda x, y: set(x) & set(y), results)) if return_type == 'ids': return ids elif return_type == 'data': return self.get_image_data(ids)