Skip to content

Commit

Permalink
alternative way to sum across studies in a general way
Browse files Browse the repository at this point in the history
  • Loading branch information
jdkent committed Jan 9, 2024
1 parent 7c8a5f5 commit f38e1ae
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 18 deletions.
4 changes: 2 additions & 2 deletions nimare/meta/cbma/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def _compute_weights(self, ma_values):
"""
return None

def _collect_ma_maps(self, coords_key="coordinates", maps_key="ma_maps"):
def _collect_ma_maps(self, coords_key="coordinates", maps_key="ma_maps", return_type="sparse"):
"""Collect modeled activation maps from Estimator inputs.
Parameters
Expand All @@ -231,7 +231,7 @@ def _collect_ma_maps(self, coords_key="coordinates", maps_key="ma_maps"):
ma_maps = self.kernel_transformer.transform(
self.inputs_[coords_key],
masker=self.masker,
return_type="sparse",
return_type=return_type,
)

return ma_maps
Expand Down
8 changes: 5 additions & 3 deletions nimare/meta/cbma/mkda.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ class MKDAChi2(PairwiseCBMAEstimator):

def __init__(
self,
kernel_transformer=MKDAKernel(sum_across_studies=True),
kernel_transformer=MKDAKernel(),
prior=0.5,
memory=Memory(location=None, verbose=0),
memory_level=0,
Expand Down Expand Up @@ -441,6 +441,7 @@ def _fit(self, dataset1, dataset2):
n_selected_active_voxels = self._collect_ma_maps(
maps_key="ma_maps1",
coords_key="coordinates1",
return_type="summary_array",
)

n_selected = self.dataset1.coordinates["id"].unique().shape[0]
Expand All @@ -449,6 +450,7 @@ def _fit(self, dataset1, dataset2):
n_unselected_active_voxels = self._collect_ma_maps(
maps_key="ma_maps2",
coords_key="coordinates2",
return_type="summary_array",
)
n_unselected = self.dataset2.coordinates["id"].unique().shape[0]

Expand Down Expand Up @@ -572,14 +574,14 @@ def _run_fwe_permutation(self, iter_xyz1, iter_xyz2, iter_df1, iter_df2, conn, v

# Generate MA maps and calculate count variables for first dataset
n_selected_active_voxels = self.kernel_transformer.transform(
iter_df1, self.masker, return_type="sparse"
iter_df1, self.masker, return_type="summary_array"
)

n_selected = self.dataset1.coordinates["id"].unique().shape[0]

# Generate MA maps and calculate count variables for second dataset
n_unselected_active_voxels = self.kernel_transformer.transform(
iter_df2, self.masker, return_type="sparse"
iter_df2, self.masker, return_type="summary_array"
)
n_unselected = self.dataset2.coordinates["id"].unique().shape[0]

Expand Down
40 changes: 27 additions & 13 deletions nimare/meta/kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def transform(self, dataset, masker=None, return_type="image"):
Mask to apply to MA maps. Required if ``dataset`` is a DataFrame.
If None (and ``dataset`` is a Dataset), the Dataset's masker attribute will be used.
Default is None.
return_type : {'sparse', 'array', 'image'}, optional
return_type : {'sparse', 'array', 'image', 'summary_array'}, optional
Whether to return a sparse matrix ('sparse'), a numpy array ('array'),
or a list of niimgs ('image').
Default is 'image'.
Expand All @@ -110,6 +110,8 @@ def transform(self, dataset, masker=None, return_type="image"):
equal to `shape` of the images.
If return_type is 'array', a 2D numpy array (C x V), where C is
contrast and V is voxel.
If return_type is 'summary_array', a 1D numpy array (V,) containing
a summary measure for each voxel that has been combined across experiments.
If return_type is 'image', a list of modeled activation images
(one for each of the Contrasts in the input dataset).
Expand All @@ -121,8 +123,10 @@ def transform(self, dataset, masker=None, return_type="image"):
Name of the corresponding column in the Dataset.images DataFrame.
If :meth:`_infer_names` is executed.
"""
if return_type not in ("sparse", "array", "image"):
raise ValueError('Argument "return_type" must be "image", "array", or "sparse".')
if return_type not in ("sparse", "array", "image", "summary_array"):
raise ValueError(
'Argument "return_type" must be "image", "array", "summary_array", "sparse".'
)

if isinstance(dataset, pd.DataFrame):
assert (
Expand Down Expand Up @@ -169,9 +173,14 @@ def transform(self, dataset, masker=None, return_type="image"):
mask_data = mask.get_fdata().astype(dtype)

# Generate the MA maps
transformed_maps = self._cache(self._transform, func_memory_level=2)(mask, coordinates)
if return_type == "summary_array" or return_type == "sparse":
args = (mask, coordinates, return_type)
else:
args = (mask, coordinates)

if return_type == "sparse":
transformed_maps = self._cache(self._transform, func_memory_level=2)(*args)

if return_type == "sparse" or return_type == "summary_array":
return transformed_maps[0]

imgs = []
Expand Down Expand Up @@ -344,10 +353,6 @@ def _generate_description(self):
class KDAKernel(KernelTransformer):
"""Generate KDA modeled activation images from coordinates.
.. versionchanged:: 0.2.1
- Add new parameter ``sum_across_studies`` to sum across studies in KDA.
.. versionchanged:: 0.0.13
- Add new parameter ``memory`` to cache modeled activation (MA) maps.
Expand Down Expand Up @@ -382,24 +387,33 @@ def __init__(
value=1,
memory=Memory(location=None, verbose=0),
memory_level=0,
sum_across_studies=False,
):
self.r = float(r)
self.value = value
self.sum_across_studies = sum_across_studies
super().__init__(memory=memory, memory_level=memory_level)

def _transform(self, mask, coordinates):
def _transform(self, mask, coordinates, return_type="sparse"):
"""return type can either be sparse or summary_array"""

ijks = coordinates[["i", "j", "k"]].values
exp_idx = coordinates["id"].values
if return_type == "sparse":
sum_across_studies = False
elif return_type == "summary_array":
sum_across_studies = True
else:
raise ValueError(
'Argument "return_type" must be "sparse" or "summary_array".'
)

transformed = compute_kda_ma(
mask,
ijks,
self.r,
self.value,
exp_idx,
sum_overlap=self._sum_overlap,
sum_across_studies=self.sum_across_studies,
sum_across_studies=sum_across_studies,
)
exp_ids = np.unique(exp_idx)
return transformed, exp_ids
Expand Down

0 comments on commit f38e1ae

Please sign in to comment.