Skip to content

[FIX] table generation with cluster corrected images in Jackknife and focuscounter#1087

Merged
jdkent merged 2 commits into
neurostuff:mainfrom
jdkent:fix/table_generation
Jul 9, 2026
Merged

[FIX] table generation with cluster corrected images in Jackknife and focuscounter#1087
jdkent merged 2 commits into
neurostuff:mainfrom
jdkent:fix/table_generation

Conversation

@jdkent

@jdkent jdkent commented Jul 9, 2026

Copy link
Copy Markdown
Member

Closes #1086 .

Changes proposed in this pull request:

  • replace voxel_thresh with target_thresh (since applying a voxel_thresh to a cluster corrected image is technically correct, but it is semantically confusing)
  • resolve to the correct z map from the corresponding corrected image.

Summary by Sourcery

Introduce a new diagnostics threshold API and corrected-cluster handling, while scaffolding the future nimare.ml masked activation feature dataset module with tests, specs, and examples.

Bug Fixes:

  • Ensure diagnostics cluster tables for Monte Carlo cluster-corrected maps use thresholded cluster support combined with the original statistic/z maps for peak values.
  • Prevent ambiguous or incorrect use of voxel-level thresholds in diagnostics by resolving cluster-corrected targets to the appropriate statistic maps.

Enhancements:

  • Add a target_threshold parameter to diagnostics, deprecating voxel_thresh with explicit alias handling and validation.
  • Improve diagnostics cluster table generation to detect cluster-corrected target images and automatically select the corresponding original statistic map for peak reporting.
  • Add helper utilities in diagnostics for cluster label support and peak map resolution to standardize table/support generation.

Documentation:

  • Add a comprehensive specification, data model, quickstart, contracts, tasks, and checklist documentation for the upcoming masked activation feature dataset (nimare.ml) module, including public API and scikit-learn compatibility contracts.
  • Add Sphinx-Gallery example scaffolds for masked activation feature dataset creation and reduction workflows under examples/05_machine_learning.
  • Document the new diagnostics target_threshold parameter and clarify its relationship to deprecated voxel_thresh for cluster-corrected images.

Tests:

  • Add tests covering deprecation behavior and alias resolution between voxel_thresh and target_threshold in diagnostics.
  • Add tests verifying corrected-cluster diagnostics tables use original z statistics within thresholded cluster support for peak values.
  • Update Jackknife and FocusCounter diagnostics tests to use target_threshold instead of voxel_thresh and validate tail label map naming, mixed-sign cluster warnings, and group-specific behavior.
  • Add initial tests for the new nimare.ml module, including a canonical Studyset fixture and placeholders asserting that unimplemented ML components currently raise NotImplementedError.

Chores:

  • Create scaffolding for the new nimare.ml module, exposing MAFeatureDataset, MAFeatureExtractor, and make_map_reducer as placeholders.
  • Add planning and checklist artifacts for the masked activation feature dataset feature under specs/001-ma-feature-dataset/, capturing research, implementation plan, tasks, and requirements.

@sourcery-ai

sourcery-ai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Refactors diagnostics threshold handling and cluster table generation for corrected images, adds scaffolded machine-learning API and specs for masked activation feature datasets, and updates tests/examples to cover the new behavior and future ML module.

Sequence diagram for diagnostics cluster table generation with corrected images

sequenceDiagram
    participant Diagnostics
    participant MetaResult as result
    participant Clusters as _get_clusters_table_and_label_maps
    participant ClusterFunc as get_clusters_table

    Diagnostics->>Clusters: _get_clusters_table_and_label_maps(result, target_img, target_image, target_threshold, cluster_threshold)
    Clusters->>MetaResult: result.estimator
    Clusters->>ClusterFunc: get_clusters_table(target_img, threshold, cluster_threshold, two_sided, return_label_maps=True)
    ClusterFunc-->>Clusters: clusters_table, label_maps

    alt [target_image is cluster_corrected and clusters_table not empty]
        Clusters->>MetaResult: _get_peak_value_map_for_cluster_table(result, target_image)
        Clusters->>MetaResult: get_map(peak_value_map, return_type=image)
        Clusters->>ClusterFunc: get_clusters_table(masked_peak_img, 0, 0, two_sided)
        ClusterFunc-->>Clusters: peak_clusters_table
        Clusters-->>Diagnostics: peak_clusters_table, label_maps
    else [not cluster_corrected or no clusters]
        Clusters-->>Diagnostics: clusters_table, label_maps
    end
Loading

File-Level Changes

Change Details Files
Unify diagnostics voxel threshold handling and support cluster-corrected target images with peak statistics from original maps.
  • Add alias resolver to treat voxel_thresh as deprecated and prefer target_threshold with explicit conflict errors
  • Detect cluster-corrected target images and infer corresponding original z/stat maps for peak statistics
  • Generate candidate peak value maps based on target image description, falling back to common z/stat map names
  • Compute cluster support masks from label maps and re-run clustering on masked original peak maps to build corrected-cluster tables
  • Refactor Diagnostics to store target_threshold, update transform to use new cluster-table helper, and clarify parameter docstrings
nimare/diagnostics.py
Strengthen diagnostics tests to cover deprecation behavior and corrected-cluster table semantics, and adapt Jackknife/FocusCounter tests to new threshold parameter.
  • Add tests for voxel_thresh deprecation warning and mutual-exclusivity with target_threshold
  • Add a detailed DummyResult-based test ensuring corrected cluster tables report peaks from original z maps constrained to thresholded support
  • Update Jackknife and FocusCounter tests to use target_threshold instead of voxel_thresh
  • Extend tests for tail labeling, mixed-sign clusters, maskers, and smoke cases with the new threshold API
nimare/tests/test_diagnostics.py
Introduce a scaffolded nimare.ml module with placeholder MAFeatureDataset/MAFeatureExtractor/make_map_reducer APIs and corresponding tests.
  • Create nimare/ml.py defining MAFeatureDataset, MAFeatureExtractor, and make_map_reducer as NiMAREBase-derived placeholders raising NotImplementedError
  • Add minimal tests that import the ML module, build a canonical Studyset fixture, and assert placeholders currently raise NotImplementedError
nimare/ml.py
nimare/tests/test_ml.py
Add design, specification, and public API contracts for the masked activation feature dataset ML module.
  • Document research decisions, data model, tasks/implementation plan, public API contract, sklearn compatibility contract, and quickstart workflow for MAFeatureDataset and MAFeatureExtractor
  • Add a requirements checklist to validate spec quality and readiness
specs/001-ma-feature-dataset/research.md
specs/001-ma-feature-dataset/data-model.md
specs/001-ma-feature-dataset/tasks.md
specs/001-ma-feature-dataset/contracts/public-api.md
specs/001-ma-feature-dataset/spec.md
specs/001-ma-feature-dataset/plan.md
specs/001-ma-feature-dataset/quickstart.md
specs/001-ma-feature-dataset/contracts/sklearn-compatibility.md
specs/001-ma-feature-dataset/checklists/requirements.md
Add Sphinx-Gallery example scaffolds for future MA feature dataset and reduction workflows.
  • Create two machine-learning examples that import the ML public API symbols and print their names for now, keeping examples executable during docs builds
examples/05_machine_learning/01_plot_ma_feature_dataset.py
examples/05_machine_learning/02_plot_ma_feature_reduction.py

Assessment against linked issues

Issue Objective Addressed Explanation
#1086 Generate diagnostics cluster tables using both the FWE cluster-corrected target map to define clusters and the corresponding original z/statistic map to compute peak statistics inside those clusters.
#1086 Clarify and update the diagnostics threshold API by deprecating the confusing voxel_thresh parameter in favor of a target_threshold that explicitly thresholds the selected target image, including cluster-corrected maps.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The cluster diagnostics helpers rely on fairly specific naming conventions (e.g., _level-cluster, _corr-, z_desc-*, stat_desc-*, stat_desc-group1MinusGroup2); consider centralizing or documenting these patterns in a single utility to reduce the risk of breakage if map naming changes elsewhere.
  • In _get_clusters_table_and_label_maps, the logic for inferring two_sided from the estimator or data is duplicated and slightly implicit; you might want to factor this into a dedicated helper so that future changes to the two-sided behavior are easier to maintain and test.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The cluster diagnostics helpers rely on fairly specific naming conventions (e.g., `_level-cluster`, `_corr-`, `z_desc-*`, `stat_desc-*`, `stat_desc-group1MinusGroup2`); consider centralizing or documenting these patterns in a single utility to reduce the risk of breakage if map naming changes elsewhere.
- In `_get_clusters_table_and_label_maps`, the logic for inferring `two_sided` from the estimator or data is duplicated and slightly implicit; you might want to factor this into a dedicated helper so that future changes to the two-sided behavior are easier to maintain and test.

## Individual Comments

### Comment 1
<location path="nimare/diagnostics.py" line_range="141-146" />
<code_context>
+    )
+
+
+def _get_cluster_support_data(label_maps, shape):
+    """Convert one or more cluster label maps to a binary support array."""
+    support = np.zeros(shape, dtype=bool)
+    for label_map in label_maps:
+        support |= np.asanyarray(label_map.dataobj) > 0
+    return support
+
</code_context>
<issue_to_address>
**suggestion:** Cluster support binary mask threshold may be too specific to positive labels.

The current `> 0` check assumes all cluster labels are positive. If labels ever include negative values with 0 as background, this will incorrectly exclude those clusters. Using `!= 0` would keep 0 as background while correctly including all non-zero labels and make the function more robust to different labeling schemes.

```suggestion
def _get_cluster_support_data(label_maps, shape):
    """Convert one or more cluster label maps to a binary support array."""
    support = np.zeros(shape, dtype=bool)
    for label_map in label_maps:
        # Treat 0 as background and include all non-zero labels (positive or negative)
        support |= np.asanyarray(label_map.dataobj) != 0
    return support
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread nimare/diagnostics.py
@jdkent
jdkent force-pushed the fix/table_generation branch from 798d4c9 to c10e841 Compare July 9, 2026 21:21
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.98246% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.53%. Comparing base (ba8d921) to head (c10e841).

Files with missing lines Patch % Lines
nimare/diagnostics.py 92.98% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1087      +/-   ##
==========================================
+ Coverage   85.50%   85.53%   +0.03%     
==========================================
  Files          56       56              
  Lines       11248    11300      +52     
==========================================
+ Hits         9618     9666      +48     
- Misses       1630     1634       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jdkent
jdkent merged commit 87ebdaa into neurostuff:main Jul 9, 2026
28 of 29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use both FWE cluster map and original z map for generating table

1 participant