Skip to content

Elements from the data types to grab, complete element selectors and combining DataGrabbers - #524

Merged
fraimondo merged 4 commits into
mainfrom
fix/element-replacements
Oct 9, 2026
Merged

fraimondo merged 4 commits into
mainfrom
fix/element-replacements

Conversation

@fraimondo

Copy link
Copy Markdown
Contributor

DataGrabbers with many replacements (e.g., subject, session and task) listed elements that did not make sense for some data types: with only VBM (one file per subject), the elements were incomplete (("sub-01",)) and could not be grabbed, and the built-in DataGrabbers listed one element per task, processing the same VBM data once per task. This PR makes the elements depend on the data types to grab, and reworks how elements are selected and combined.

DataGrabbers

  • Element keys from the data types to grab: the keys of a PatternDataGrabber are the replacements used by the patterns of its types. With only VBM, the elements are the subjects; with BOLD, the subjects and tasks.
  • Elements found in the files: the elements of each data type are joined on their common replacements (_join_elements), so an element is available if it has the files of all the data types, regardless of the order of the types.
  • Values to grab: replacements can be a dictionary with the values to grab (e.g., {"subject": null, "task": ["rest"]}), or a DataGrabber can link a field to a replacement with _REPLACEMENT_FIELDS (e.g., {"task": "tasks"}). Elements with other values are not listed and cannot be grabbed.
  • Wildcards: * and ? in the patterns can be used to find the elements (the regular expression now translates them and escapes the rest), and the paths are always absolute.
  • Built-in DataGrabbers (AOMIC PIOP1/PIOP2, HCP1200, DMCC13) find their elements in the files with patterns (e.g., task-{task}_acq-* and ?fMRI_{task}) instead of hard-coded subject lists and get_elements/get_item overrides, so they only list the elements with data, and their tasks (and other fields) restrict the elements.
  • MultipleDataGrabber: the DataGrabbers can have different element keys (the elements are joined on their common keys, and each DataGrabber grabs an element with its keys), each data type is grabbed by one DataGrabber (chosen with their types), and a DataGrabber that only grabs nested data types (e.g., only the confounds of BOLD) replaces them.

Running

  • Complete elements are run without searching the dataset (select_elements): with one value for each element key, e.g., each queued job; partial selectors (e.g., only the subject) still search it, once.
  • Fix partial selectors in run, which were always reported as invalid (after computing their elements). All the selectors must have the same number of values.
  • A relative datadir in the YAML is relative to the YAML file, as the storage URI, so the queued jobs (run in the job directory) find the data.

Docs

New sections on elements (with an example dataset and tables), combining datasets, complete and partial elements, restricting the values of the replacements and wildcards.

Tests

New tests for each of the above; some existing tests were updated, e.g., expecting partial selectors to be invalid, or a BIDS test whose pattern never matched any file (so it checked nothing).

Changelog entries to be added once the PR has a number.

🤖 Generated with Claude Code

fraimondo and others added 3 commits October 9, 2026 19:17
DataGrabbers:
- The element keys are the replacements used by the patterns of the data
  types to grab, so data types that do not depend on, e.g., the task are
  processed once per subject.
- The elements of each data type are joined on their common replacements.
- The values of the replacements to grab can be given in `replacements`
  (as a dictionary) or by fields linked with `_REPLACEMENT_FIELDS`;
  elements with other values are not listed and cannot be grabbed.
- The `*` and `?` wildcards in the patterns can be used to find the
  elements, and the paths are always absolute.
- The built-in DataGrabbers (AOMIC PIOP1/PIOP2, HCP1200, DMCC13) find
  their elements in the files, with patterns instead of overriding
  `get_elements` and `get_item`.

Running:
- Complete elements are run without searching the dataset, and partial
  element selectors are no longer reported as invalid. All the selectors
  must have the same number of values.
- A relative `datadir` in the YAML is relative to the YAML file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MultipleDataGrabber now:
- Joins the elements of the DataGrabbers on their common keys, so they can
  have different element keys (e.g., subject and task for BOLD, and only
  subject for VBM), and each DataGrabber grabs an element with its keys.
- Requires each data type to be grabbed by one DataGrabber (chosen with
  their types), except for DataGrabbers that only grab nested data types
  of a data type, which replace the ones of the other DataGrabber.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-09 22:10 UTC

@codecov

codecov Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.43434% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.33%. Comparing base (442e9f6) to head (d5adcba).

Files with missing lines Patch % Lines
junifer/datagrabber/multiple.py 86.44% 4 Missing and 4 partials ⚠️
junifer/datagrabber/base.py 88.23% 2 Missing and 2 partials ⚠️
junifer/datagrabber/pattern.py 98.83% 1 Missing ⚠️

❌ Your patch check has failed because the patch coverage (93.43%) is below the target coverage (95.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #524      +/-   ##
==========================================
+ Coverage   92.25%   92.33%   +0.08%     
==========================================
  Files         148      148              
  Lines        6652     6696      +44     
  Branches      962      977      +15     
==========================================
+ Hits         6137     6183      +46     
+ Misses        332      328       -4     
- Partials      183      185       +2     
Flag Coverage Δ
junifer 92.27% <93.43%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
junifer/api/functions.py 92.19% <100.00%> (+0.07%) ⬆️
junifer/datagrabber/aomic/piop1.py 100.00% <100.00%> (ø)
junifer/datagrabber/aomic/piop2.py 100.00% <100.00%> (ø)
junifer/datagrabber/dmcc13_benchmark.py 100.00% <100.00%> (ø)
junifer/datagrabber/hcp1200/hcp1200.py 100.00% <100.00%> (ø)
junifer/datagrabber/pattern.py 97.82% <98.83%> (+0.62%) ⬆️
junifer/datagrabber/base.py 96.07% <88.23%> (-2.69%) ⬇️
junifer/datagrabber/multiple.py 92.30% <86.44%> (-0.55%) ⬇️

... and 1 file with indirect coverage changes

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

Before Python 3.12, Path.glob skips broken symbolic links when the last
component of the pattern is a literal, so files of a DataLad dataset that
are not downloaded yet were not found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 9, 2026 20:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@fraimondo
fraimondo added this pull request to stack #526 October 9, 2026 22:03
@fraimondo
fraimondo merged commit f37e906 into main Oct 9, 2026
11 of 12 checks passed
@fraimondo
fraimondo deleted the fix/element-replacements branch October 9, 2026 22:04
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.

2 participants