Releases: khanlab/snakebids
0.9.2
0.9.1
Changes
HOTFIX release to fix a bug introduced in our 0.9.0 release. Maintains compatibility with python 3.7.
π Bug Fixes
- HOTFIX Fix pybidsdb path resolution @pvandyken (#325)
π Documentation
- Fix version fetching in readthedocs build @pvandyken (#326)
0.9.0
Highlights
BidsComponent API
This release further expands our BidsComponent
API. You can now index entities directly on a bids component. For example, the following code is now valid:
inputs["surface"]["hemi"].expand(...)
inputs["surface"]["hemi", "session"].entities["hemi"]
One primary use-case is partial expansion over just some of the entities in a component. For example, if you have gifti surface files as an input with "subject", "session", and "hemi" as wildcards, you can expand over just the hemispheres using:
inputs["surface"]["hemi"].expand(
"path/to/data/sub-{subject}/ses-{session}/anat/sub-{subject}_ses-{session}_hemi-{hemi}_pial.gii",
allow_missing=True,
)
Allow Booleans as Filters in CLI
Snakebids has always allowed the specification of custom filters from app CLIs:
./run.py . derivatives/my_app participant --filter-t1w space=T1w
Previously, it was impossible to use booleans as filters. You couldn't filter for paths without a given entity, or with any value on a given entity. This update adds this ability using a special syntax:
./run.py . derivatives/my_app participant --filter-t1w space:any
Note that a :
is used instead of a =
. The specifier may be any of:
- any: any value, but the entity must be present
- optional: the entity may or may not be present, and may have any value (the "default" filter)
- none: the entity must not be present
Bug Fixes and Gotchas
A few things we addressed:
- Booleans could not previously be used as one item in a list of filters. For example, this previously would not work correctly
pybids_inputs:
t1:
filters:
datatype: anat
suffix: T1w
acquisition:
- MPRAGE
- false
This syntax can be useful for filtering paths that must either be absent or set to a specific value.
- Extension was previously not correctly supported. If used as an argument in
bids
, it would not be correctly placed at the end of the path. Normally, that wasn't an issue, as snakebids users generally just specify the path as part of the suffix. It would cause problems if you wanted to use the extension as a wildcard, however. This release correctly supports extension.
Last release for Python 3.7
Since Python 3.7 has reached EOL, this is the last release that will maintain support. Newer releases will start using syntax only available on Python 3.8+, and thus will not work on Python 3.7 Projects still primarily using 3.7 should strongly consider upgrading.
Changes
π Features
- Save more provenance information @tkkuehn (#308)
- Add BidsValidator Plugin @kaitj (#291)
- Implement
BidsPartialComponent
@pvandyken (#284) - Implement extension support @pvandyken (#285)
- Boolean CLI filters @tkkuehn (#309)
π Bug Fixes
- Allow Booleans in filter lists @pvandyken (#314)
π§° Maintenance
- Update scipy constraints for py3.8 @kaitj (#320)
- Update cookiecutter @kaitj (#316)
- Always set SnakeBidsApp.args in run_snakemake @tkkuehn (#310)
- Test magic args @tkkuehn (#305)
- Update pybids_db parameters @kaitj (#296)
- Raise error on missing
custom_path
and invalidbids_dir
@kaitj (#297) - Add DuplicateComponentError for more precision @tkkuehn (#300)
π Documentation
0.8.1
Changes
This release fixes a bug we introduced in v0.8.0
preventing the use of custom command-line filters like --filter_T1w
. It also allows compatibility with pybids 0.16.0
(on python >= 3.8
only).
π Bug Fixes
π§° Maintenance
- Ignore deadlines for hypothesis tests on pr @pvandyken (#290)
- Update pybids py37, py38+ constraints @kaitj (#288)
- Restrict pybids bug check to python 3.7 @pvandyken (#283)
0.8.0
The BidsDataset
Release!
In the early days, generate_inputs()
returned a simple dictionary intended to be merged into the snakemake config
:
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 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.
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
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:
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:
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
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:
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:
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:
inputs['bold'].zip_lists['subject', 'session']
This is useful for expanding over just a portion of your wildcards. See here 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
, andentities
@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)
0.7.2
Changes
π Bug Fixes
- [FIX] change error message when no input found @Remi-Gau (#231)
- Block components with same names in dataset init @pvandyken (#228)
- Use entity-specific parsers @pvandyken (#229)
- Check if BidsDir exists before indexing @pvandyken (#218)
π§° Maintenance
- Skip Bids Indexing when
custom_paths
specified @pvandyken (#224) - Split Dataset and Component models into new file @pvandyken (#225)
- Update setup-poetry to v4 @pvandyken (#214)
- Transition versioning to dynamic-poetry-versioning @pvandyken (#210)
- Remove redundant inputs from github actions @pvandyken (#211)
- Update auto-assign action version @pvandyken (#212)
π Documentation
- Update some outdated references to BidsInputs @pvandyken (#226)
- Fix docstring type in _get_lists_from_bids @pvandyken (#217)
0.7.1
Changes
- Add support for python 3.11 @pvandyken (#200)
π§° Maintenance
- Update dependencies @pvandyken (#199)
0.7.0
Highlights
With the new BidsComponent
structure, accessing bids dataset parameters involved long, repetitive attribute names like inputs.input_lists
, or inputs.input_wildcards
. In this release, both BidsComponent
and BidsDataset
(the object returned by generate_inputs
) are equipped with new, shorter versions of the names. inputs.input_wildcards
becomes inputs.wildcards
, inputs.input_path
becomes inputs.path
, and inputs.input_zip_lists
becomes inputs.zip_lists
. inputs.input_lists
has been updated to inputs.entities
to better reflect what the attribute refers to.
None of this is breaking, however! The old names have been kept around as aliases of the new names, so workflows will continue to work as usual. While we have no current plans to deprecate the old names, new workflows should start migrating to the new syntax.
This version allows true
and false
as filters in generate_inputs
. They will require the presence of an entity or prohibit it, respectively.
The snakebids create
experience has been updated, removing some legacy code and making the boilerplate app up-to-date with modern snakebids.
π Features
- Input aliases @pvandyken (#198)
- Allow filtering of entities using True and False @pvandyken (#191)
- Snakebids create enhancements @tkkuehn (#188)
π§° Maintenance
- Migrate poetry syntax to poetry v1.2 @pvandyken (#195)
π Documentation
- Allow filtering of entities using True and False @pvandyken (#191)
- Use correct command for testing in README @pvandyken (#190)
0.6.2
Changes
π Bug Fixes
- Fix forced output into occupied directory @pvandyken (#183)
- Propogate message to super-Exception @pvandyken (#178)
π§° Maintenance
- BidsInputs Refactoring @pvandyken (#175)
- Update readthedocs config syntax @pvandyken (#177)