Skip to content

Commit fffc923

Browse files
Yifan YuCopilot
andcommitted
Update CBMR tests and tutorial
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 9e96fa5 commit fffc923

2 files changed

Lines changed: 132 additions & 131 deletions

File tree

examples/02_meta-analyses/11_plot_cbmr.py

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,29 @@
22
.. _metas_cbmr:
33
.. _metas_voxelwise_cbmr:
44
5-
============================================================
6-
Coordinate-based meta-regression with moderator-effect modes
7-
============================================================
5+
====================================================================
6+
Coordinate-based meta-regression with global and voxelwise moderators
7+
====================================================================
88
99
A tour of coordinate-based meta-regression (CBMR) in NiMARE.
1010
1111
CBMR is a generative framework for estimating smooth activation intensity
12-
functions from coordinate-based meta-analytic data. The same
13-
:class:`~nimare.meta.cbmr.CBMREstimator` can parameterize moderator effects in
14-
three ways:
12+
functions from coordinate-based meta-analytic data. The current
13+
:class:`~nimare.meta.cbmr.CBMREstimator` implementation exposes one public API
14+
for three moderator-effect parameterizations:
1515
1616
* ``moderator_effect="global"`` estimates one scalar coefficient per moderator.
1717
This assumes the effect of the moderator has a global effect across the entire brain.
18-
* ``moderator_effect="voxelwise"`` estimates a scalar coefficient _per voxel_ per moderator.
19-
This assumes the effect of the moderator differentially impacts voxels throughout the brain.
20-
This is likely a more accurate assumption, but requires a lot more data for estimation.
18+
* ``moderator_effect="voxelwise"`` estimates a smooth spatial coefficient map
19+
for each moderator and group. This allows the moderator effect to vary across
20+
the brain, but requires more data for stable estimation.
2121
* ``moderator_effect="mixed"`` estimates scalar coefficients for selected
2222
``global_moderators`` and spatially varying coefficients for selected
2323
``voxelwise_moderators`` in one model.
2424
25-
This tutorial fits all three versions to the same simulated Studyset with the
26-
same groups and standardized moderators, then compares their outputs.
25+
This tutorial fits all three versions to the same simulated Studyset, shows how
26+
to inspect fitted CBMR results, and demonstrates the result-centered inference
27+
helpers added around :class:`~nimare.meta.cbmr.CBMRInference`.
2728
"""
2829

2930
import numpy as np
@@ -39,23 +40,28 @@
3940
# Load Studyset-compatible data
4041
# -----------------------------------------------------------------------------
4142
# We simulate a coordinate-based Studyset with reported foci, sample sizes,
42-
# diagnosis labels, drug-status labels, and continuous moderators.
43-
# The example uses a moderate number of studies and coarse B-spline spacing so
44-
# that both global and voxelwise CBMR fits run quickly.
43+
# diagnosis labels, drug-status labels, and continuous moderators. The example
44+
# uses a moderate number of studies and coarse B-spline spacing so that global,
45+
# voxelwise, and mixed CBMR fits run quickly.
4546

4647
_, studyset = create_coordinate_studyset(
4748
foci=10,
4849
sample_size=(20, 40),
4950
n_studies=200,
51+
seed=100,
5052
)
5153

5254
annotations_df = studyset.annotations_df.copy()
5355
n_rows = annotations_df.shape[0]
54-
annotations_df["diagnosis"] = [
55-
"schizophrenia" if i % 2 == 0 else "depression" for i in range(n_rows)
56+
group_pattern = [
57+
("schizophrenia", "Yes"),
58+
("schizophrenia", "No"),
59+
("depression", "Yes"),
60+
("depression", "No"),
61+
]
62+
annotations_df[["diagnosis", "drug_status"]] = [
63+
group_pattern[i % len(group_pattern)] for i in range(n_rows)
5664
]
57-
annotations_df["drug_status"] = ["Yes" if i % 2 == 0 else "No" for i in range(n_rows)]
58-
annotations_df["drug_status"] = annotations_df["drug_status"].sample(frac=1).reset_index(drop=True)
5965
annotations_df["sample_sizes"] = [studyset.metadata.sample_sizes[i][0] for i in range(n_rows)]
6066
annotations_df["avg_age"] = np.arange(n_rows)
6167
studyset.annotations_df = annotations_df
@@ -83,6 +89,7 @@
8389
lr=1e-1,
8490
tol=1e3, # a reasonable analysis choice is 1e-2; 1e3 is for speed
8591
device="cpu", # use "cuda" if you have a GPU
92+
random_state=100,
8693
)
8794
global_results = global_cbmr.fit(dataset=studyset)
8895

@@ -235,6 +242,7 @@
235242
damping=1.0,
236243
compute_nll=False,
237244
device="cpu", # the full backend also accepts "cuda" if a GPU is available
245+
random_state=100,
238246
)
239247
voxelwise_results = voxelwise_cbmr.fit(dataset=studyset)
240248

@@ -275,11 +283,11 @@
275283
# -----------------------------------------------------------------------------
276284
# A fitted :class:`~nimare.meta.cbmr.CBMRInference` object can generate Relative
277285
# Intensity (RI) and Intensity Difference (ID) diagnostic maps showing how a
278-
# user-defined moderator-unit change affects spatial intensity. The updated
279-
# helper accepts the same moderator/group selectors as the inference methods and
280-
# returns a CBMRResult copy with named RI and ID maps. Users can keep those maps
281-
# for downstream diagnosis or plot RI inside an ID-defined region of interest.
282-
# If no ID threshold is provided, the median absolute ID value is used.
286+
# user-defined moderator-unit change affects spatial intensity. The helper
287+
# accepts the same moderator/group selectors as the inference methods and returns
288+
# a CBMRResult copy with named RI and ID maps. Users can keep those maps for
289+
# downstream diagnosis or plot RI inside an ID-defined region of interest. If no
290+
# ID threshold is provided, the median absolute ID value is used.
283291

284292
voxelwise_inference = voxelwise_results.get_inference(
285293
method="FI",
@@ -397,11 +405,13 @@
397405
group_categories=group_categories,
398406
global_moderators=["standardized_sample_sizes"],
399407
voxelwise_moderators=["standardized_avg_age"],
408+
backend="full",
400409
spline_spacing=100, # a reasonable analysis choice is 10 or 5; 100 is for speed
401410
n_iter=10,
402411
lr=1e-1,
403412
tol=1e3, # a reasonable analysis choice is 1e-4; 1e3 is for speed
404413
device="cpu", # use "cuda" if you have a GPU
414+
random_state=100,
405415
)
406416
mixed_results = mixed_cbmr.fit(dataset=studyset)
407417

0 commit comments

Comments
 (0)