The `BidsDataset` Release!
In the early days, `generate_inputs()` returned a simple dictionary intended to be merged into the snakemake `config`:
py
config.update(snakebids.generate_inputs(
bids_dir=config['bids_dir'],
pybids_inputs=config['pybids_inputs'],
))
config['input_zip_lists']['bold']
Over the past few releases, we've been transitioning to a new `BidsDataset` class, equipped with powerful filtering and indexing capabilities. These features have been opt-in via the `use_bids_inputs` argument on `generate_inputs`, but in this release, we now return this class by default! If you're still using the old dicts, check out the [migration guide](https://snakebids.readthedocs.io/en/stable/migration/0.5_to_0.8.html) to make the upgrade.
**BREAKING**: To continue using the old dict return, you need to set `use_bids_inputs` to `False` when calling `generate_inputs`
Datasets and Components
`BidsDatasets` are a subclass of python dicts. Instead of keys like `'input_zip_lists'` and `'input_wildcards'`, you now use the *component names* as keys. A component is a particular group of images or files indexed by `generate_inputs`. It corresponds to the entries in your `pybids_inputs` field in the `config.yaml`, such as `t1w`, `bold`, `dwi`, `mask`, or whatever else you may be indexing.
py
inputs = snakebids.generate_inputs(
bids_dir=config['bids_dir'],
pybids_inputs=config['pybids_inputs'],
)
inputs['t1w']
inputs['bold']
These key accesses returns a `BidsComponent` class, which in turn has properties such as `zip_lists`, `entities`, `wildcards`, and `path`. More info can be found [here](
https://snakebids.readthedocs.io/en/stable/bids_app/workflow.html)
**BREAKING** `BidsDataset` has properties such as `zip_lists`, `entities`, and `wildcards` that previously could be used to access component information. These names are being repurposed in an upcoming release, so their current use is deprecated. Components should now always be accessed as `inputs['bold'].zip_lists`, never `inputs.zip_lists['bold']`.
`expand`ing the API
`BidsComponent` now comes equipped with an `expand` method that wraps around the `snakemake` version of the function. It expands only over the wildcard combinations actually found in your dataset, saving you from `MissingInput` errors in your snakemake workflow. In effect, it turns an `expand` call that used to look like this:
py
rule all:
input:
expand(
expand(
bids(
root=root,
desc="{smooth}",
**inputs["bold"].wildcards,
),
allow_missing=True,
smooth=[1, 2, 3, 4],
),
zip,
**inputs["bold"].zip_lists,
)
into this:
py
rule all:
input:
inputs['bold'].expand(
bids(
root=root,
desc="{smooth}",
**inputs["bold"].wildcards,
),
smooth=[1, 2, 3, 4],
)
`BidsComponent` also has a new `filter` method, with exactly the same API as the [`filter_lists`](https://snakebids.readthedocs.io/en/stable/api/main.html#snakebids.filter_list) function. Unlike the function, which only acts on zip_lists, the new method filters the entire component and returns a new `BidsComponent`, making it easy to chain with expand:
py
inputs['bold'].filter(subject=patient_group).expand(
bids(
root=root,
desc="{smooth}",
**inputs["bold"].wildcards,
),
smooth=[1, 2, 3, 4],
))
Pretty printing of `BidsComponent` and `BidsDataset`
Both of these objects now print in a beautiful, human-readable form:
py
BidsDataset({
"bold": BidsComponent(
name="bold",
path="bids/sub-{subject}/ses-{session}/func/sub-{subject}_ses-{session}_task-{task}_bold.nii.gz",
zip_lists={
"subject": ["001", "001", "001", "001", "002", "002" ],
"session": ["01", "01", "02", "02", "01", "01" ],
"task": ["nback", "rest", "nback", "rest", "nback", "rest"],
},
),
"t1w": BidsComponent(
name="t1w",
path="example/sub-{subject}/ses-{session}/anat/sub-{subject}_ses-{session}_run-{run}_T1w.nii.gz",
zip_lists={
"subject": ["001", "001", "001", "002", "002", "002", "002"],
"session": ["01", "01", "02", "01", "01", "02", "02" ],
"run": ["01", "02", "01", "01", "02", "01", "02" ],
},
),
})
The zip_lists tables automatically elide to fit within your console window (when running in an REPL). You can force a specific wi
Multi-select dicts
The `wildcards`, `entities`, and `zip_lists` properties of `BidsComponent` now allow you to select multiple items at the same time:
py
inputs['bold'].zip_lists['subject', 'session']
This is useful for expanding over just a portion of your wildcards. See [here](https://snakebids.readthedocs.io/en/stable/api/details.html#snakebids.utils.utils.MultiSelectDict) for more details.
Shiny new docs
The documentation has been overhauled, with an improved tutorial and API reference.
Changes
🚀 Features
- `BidsComponent.filter` pvandyken (279)
- Change default of allow\_missing pvandyken (280)
- Implement `BidsComponent.expand()` pvandyken (273)
- Switch default of use\_bids\_inputs to True pvandyken (275)
- Support multiple selection in `BidComponent.wildcards`, `zip_lists`, and `entities` pvandyken (274)
- Remove add\_plugins method from SnakeBidsApp pvandyken (271)
- Implement pretty printing for dataset objects pvandyken (266)
- Implement first pass at simple plugins tkkuehn (261)
- Make some cookiecutter variables optional tkkuehn (253)
- Expose BIDSLayout in BidsDataset pvandyken (233)
- Elaborate on warning for empty components tkkuehn (254)
- Introduce PybidsError for cryptic pybids errors tkkuehn (252)
- Add deprecation warnings to `BidsDataset` properties slated for change pvandyken (251)
🐛 Bug Fixes
- Move target\_rule to beginning of snakemake call pvandyken (265)
- Ensure bids() is called with identifying entities pvandyken (234)
🧰 Maintenance
- Remove unnecessary `use_bids_inputs = True` pvandyken (281)
- Complete type hints and add pyright to CI tkkuehn (277)
- Switch from pylint/flake8 to ruff pvandyken (278)
- Update glob\_wildcards to return ZipLists pvandyken (272)
- Update deprecation dependency to own package pvandyken (268)
- Update dependencies pvandyken (247)
📝 Documentation
- Final documentation fixes before release pvandyken (282)
- Create migration guide for v0.8 pvandyken (276)
- Major updates to documentation pvandyken (267)